Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Re-architects the OpenStack Dashboard for modularity and extensibility.

Implements blueprint extensible-architecture.
Implements blueprint improve-dev-documentation.
Implements blueprint gettext-everywhere.
Implements blueprint sphinx-docs.

Complete re-architecture of the dashboard to transform it from a standalone django-openstack app to a Horizon framework for building dashboards. See the docs for more information.

Incidentally fixes the following bugs:

Fixes bug 845868 -- no PEP8 violations.
Fixes bug 766096 -- the dashboard can now be installed at any arbitrary URL.
Fixes bug 879111 -- tenant id is now controlled solely by the tenant switcher, not the url (which was disregarded anyway)
Fixes bug 794754 -- output of venv installation is considerably reduced.

Due to the scale and scope of this patch I recommend reviewing it on github: https://github.com/gabrielhurley/horizon/tree/extensible_architecture

Change-Id: I8e63f7ea235f904247df40c33cb66338d973df9e
  • Loading branch information...
commit 9742842795e964c7f260aec831665d5cb28cd420 1 parent 91ceb59
@gabrielhurley gabrielhurley authored
Showing with 6,289 additions and 16,778 deletions.
  1. +8 −8 .bzrignore
  2. +12 −11 .gitignore
  3. +17 −17 README
  4. +0 −56 django-openstack/README
  5. +0 −1,093 django-openstack/django_openstack/api.py
  6. +0 −48 django-openstack/django_openstack/context_processors.py
  7. +0 −118 django-openstack/django_openstack/dash/urls.py
  8. +0 −95 django-openstack/django_openstack/dash/views/containers.py
  9. +0 −252 django-openstack/django_openstack/dash/views/networks.py
  10. +0 −42 django-openstack/django_openstack/decorators.py
  11. +0 −8 django-openstack/django_openstack/exceptions.py
  12. +0 −1,948 django-openstack/django_openstack/locale/es/LC_MESSAGES/django.po
  13. +0 −1,948 django-openstack/django_openstack/locale/fr/LC_MESSAGES/django.po
  14. BIN  django-openstack/django_openstack/locale/ja/LC_MESSAGES/django.mo
  15. +0 −1,947 django-openstack/django_openstack/locale/pt/LC_MESSAGES/django.po
  16. +0 −1,947 django-openstack/django_openstack/locale/zh-cn/LC_MESSAGES/django.po
  17. +0 −1,947 django-openstack/django_openstack/locale/zh-tw/LC_MESSAGES/django.po
  18. +0 −50 django-openstack/django_openstack/signals.py
  19. +0 −78 django-openstack/django_openstack/syspanel/urls.py
  20. +0 −17 django-openstack/django_openstack/templates/django_openstack/auth/_login.html
  21. +0 −9 django-openstack/django_openstack/templates/django_openstack/common/instances/_reboot.html
  22. +0 −9 django-openstack/django_openstack/templates/django_openstack/common/instances/_terminate.html
  23. +0 −28 django-openstack/django_openstack/templates/django_openstack/dash/_sidebar.html
  24. +0 −19 django-openstack/django_openstack/templates/django_openstack/dash/containers/index.html
  25. +0 −31 django-openstack/django_openstack/templates/django_openstack/dash/networks/detail.html
  26. +0 −18 django-openstack/django_openstack/templates/django_openstack/syspanel/_sidebar.html
  27. +0 −19 django-openstack/django_openstack/templates/django_openstack/syspanel/flavors/index.html
  28. +0 −46 django-openstack/django_openstack/templatetags/templatetags/sidebar_modules.py
  29. +0 −15 django-openstack/django_openstack/templatetags/templatetags/swift_paging.py
  30. +0 −99 django-openstack/django_openstack/test.py
  31. +0 −1,587 django-openstack/django_openstack/tests/api_tests.py
  32. +0 −2  django-openstack/django_openstack/tests/broken/README
  33. +0 −81 django-openstack/django_openstack/tests/broken/base.py
  34. +0 −70 django-openstack/django_openstack/tests/broken/credential_tests.py
  35. +0 −237 django-openstack/django_openstack/tests/broken/image_tests.py
  36. +0 −69 django-openstack/django_openstack/tests/broken/instance_tests.py
  37. +0 −93 django-openstack/django_openstack/tests/broken/keypair_tests.py
  38. +0 −41 django-openstack/django_openstack/tests/broken/region_tests.py
  39. +0 −187 django-openstack/django_openstack/tests/broken/test_models.py
  40. +0 −171 django-openstack/django_openstack/tests/broken/volume_tests.py
  41. +0 −23 django-openstack/django_openstack/tests/context_processor_tests.py
  42. +0 −71 django-openstack/django_openstack/tests/templatetag_tests.py
  43. +0 −77 django-openstack/django_openstack/tests/view_tests/base.py
  44. +0 −121 django-openstack/django_openstack/tests/view_tests/dash/container_tests.py
  45. +0 −104 django-openstack/django_openstack/tests/view_tests/dash/port_tests.py
  46. +0 −38 django-openstack/django_openstack/urls.py
  47. +0 −48 django-openstack/django_openstack/utils.py
  48. +0 −68 doc/generate_autodoc_index.py
  49. +0 −69 doc/source/index.rst
  50. +0 −32 doc/source/testing.rst
  51. 0  {doc → docs}/Makefile
  52. 0  django-openstack/django_openstack/tests/view_tests/syspanel/__init__.py → docs/source/_static/.gitignore
  53. +93 −3 {doc → docs}/source/conf.py
  54. +37 −0 docs/source/faq.rst
  55. +19 −0 docs/source/glossary.rst
  56. +101 −0 docs/source/index.rst
  57. +124 −0 docs/source/intro.rst
  58. +146 −0 docs/source/quickstart.rst
  59. +6 −0 docs/source/ref/context_processors.rst
  60. +6 −0 docs/source/ref/decorators.rst
  61. +6 −0 docs/source/ref/exceptions.rst
  62. +17 −0 docs/source/ref/forms.rst
  63. +42 −0 docs/source/ref/horizon.rst
  64. +6 −0 docs/source/ref/middleware.rst
  65. +100 −0 docs/source/ref/run_tests.rst
  66. +6 −0 docs/source/ref/users.rst
  67. +12 −0 docs/source/ref/views.rst
  68. +62 −0 docs/source/testing.rst
  69. 0  {django-openstack → horizon}/LICENSE
  70. +2 −2 {django-openstack → horizon}/Makefile
  71. +59 −0 horizon/README
  72. 0  {django-openstack → horizon}/bootstrap.py
  73. +7 −6 {django-openstack → horizon}/buildout.cfg
  74. +50 −0 horizon/horizon/__init__.py
  75. +39 −0 horizon/horizon/api/__init__.py
  76. +118 −0 horizon/horizon/api/base.py
  77. +95 −0 horizon/horizon/api/deprecated.py
  78. +89 −0 horizon/horizon/api/glance.py
  79. +256 −0 horizon/horizon/api/keystone.py
  80. +357 −0 horizon/horizon/api/nova.py
  81. +133 −0 horizon/horizon/api/quantum.py
  82. +132 −0 horizon/horizon/api/swift.py
  83. +594 −0 horizon/horizon/base.py
  84. +69 −0 horizon/horizon/context_processors.py
  85. 0  {django-openstack/django_openstack/tests/view_tests/dash → horizon/horizon/dashboards}/__init__.py
  86. 0  {django-openstack/django_openstack/tests/view_tests → horizon/horizon/dashboards/nova}/__init__.py
  87. 0  ...k/django_openstack/templatetags/templatetags → horizon/horizon/dashboards/nova/containers}/__init__.py
  88. +33 −86 ...openstack/django_openstack/dash/views/objects.py → horizon/horizon/dashboards/nova/containers/forms.py
  89. +35 −0 horizon/horizon/dashboards/nova/containers/panel.py
  90. +128 −49 ..._openstack/tests/view_tests/dash/object_tests.py → horizon/horizon/dashboards/nova/containers/tests.py
  91. +36 −0 horizon/horizon/dashboards/nova/containers/urls.py
  92. +134 −0 horizon/horizon/dashboards/nova/containers/views.py
  93. +33 −0 horizon/horizon/dashboards/nova/dashboard.py
  94. 0  ...go-openstack/django_openstack/templatetags → horizon/horizon/dashboards/nova/floating_ips}/__init__.py
  95. +7 −65 ...ck/django_openstack/dash/views/floating_ips.py → horizon/horizon/dashboards/nova/floating_ips/forms.py
  96. +30 −0 horizon/horizon/dashboards/nova/floating_ips/panel.py
  97. +40 −45 ...ack/tests/view_tests/dash/floating_ip_tests.py → horizon/horizon/dashboards/nova/floating_ips/tests.py
  98. +28 −0 horizon/horizon/dashboards/nova/floating_ips/urls.py
  99. +88 −0 horizon/horizon/dashboards/nova/floating_ips/views.py
  100. 0  {django-openstack/django_openstack/syspanel/views → horizon/horizon/dashboards/nova/images}/__init__.py
  101. +6 −136 django-openstack/django_openstack/dash/views/images.py → horizon/horizon/dashboards/nova/images/forms.py
  102. +6 −5 django-openstack/django_openstack/syspanel/forms.py → horizon/horizon/dashboards/nova/images/panel.py
  103. +30 −34 ...ango_openstack/tests/view_tests/dash/images_tests.py → horizon/horizon/dashboards/nova/images/tests.py
  104. +27 −0 horizon/horizon/dashboards/nova/images/urls.py
  105. +163 −0 horizon/horizon/dashboards/nova/images/views.py
  106. 0  {django-openstack/django_openstack/syspanel → horizon/horizon/dashboards/nova/instances}/__init__.py
  107. +101 −0 horizon/horizon/dashboards/nova/instances/forms.py
  108. +30 −0 horizon/horizon/dashboards/nova/instances/panel.py
  109. +56 −78 ...openstack/tests/view_tests/dash/instance_tests.py → horizon/horizon/dashboards/nova/instances/tests.py
  110. +33 −0 horizon/horizon/dashboards/nova/instances/urls.py
  111. +59 −127 ...penstack/django_openstack/dash/views/instances.py → horizon/horizon/dashboards/nova/instances/views.py
  112. 0  {django-openstack/django_openstack/middleware → horizon/horizon/dashboards/nova/keypairs}/__init__.py
  113. +9 −56 ...-openstack/django_openstack/dash/views/keypairs.py → horizon/horizon/dashboards/nova/keypairs/forms.py
  114. +30 −0 horizon/horizon/dashboards/nova/keypairs/panel.py
  115. +20 −30 ...o_openstack/tests/view_tests/dash/keypair_tests.py → horizon/horizon/dashboards/nova/keypairs/tests.py
  116. +28 −0 horizon/horizon/dashboards/nova/keypairs/urls.py
  117. +80 −0 horizon/horizon/dashboards/nova/keypairs/views.py
  118. 0  {django-openstack/django_openstack → horizon/horizon/dashboards/nova}/models.py
  119. 0  {django-openstack/django_openstack/dash/views → horizon/horizon/dashboards/nova/networks}/__init__.py
  120. +67 −67 django-openstack/django_openstack/dash/views/ports.py → horizon/horizon/dashboards/nova/networks/forms.py
  121. +33 −0 horizon/horizon/dashboards/nova/networks/panel.py
  122. +94 −24 ...o_openstack/tests/view_tests/dash/network_tests.py → horizon/horizon/dashboards/nova/networks/tests.py
  123. +10 −18 ...penstack/django_openstack/tests/dependency_tests.py → horizon/horizon/dashboards/nova/networks/urls.py
  124. +231 −0 horizon/horizon/dashboards/nova/networks/views.py
  125. 0  {django-openstack/django_openstack/dash → horizon/horizon/dashboards/nova/overview}/__init__.py
  126. +30 −0 horizon/horizon/dashboards/nova/overview/panel.py
  127. +3 −7 {django-openstack/django_openstack/auth → horizon/horizon/dashboards/nova/overview}/urls.py
  128. 0  {django-openstack/django_openstack/auth → horizon/horizon/dashboards/nova/security_groups}/__init__.py
  129. +7 −82 ...ngo_openstack/dash/views/security_groups.py → horizon/horizon/dashboards/nova/security_groups/forms.py
  130. +30 −0 horizon/horizon/dashboards/nova/security_groups/panel.py
  131. +36 −77 ...ts/view_tests/dash/security_groups_tests.py → horizon/horizon/dashboards/nova/security_groups/tests.py
  132. +28 −0 horizon/horizon/dashboards/nova/security_groups/urls.py
  133. +103 −0 horizon/horizon/dashboards/nova/security_groups/views.py
  134. 0  {django-openstack/django_openstack → horizon/horizon/dashboards/nova/snapshots}/__init__.py
  135. +57 −0 horizon/horizon/dashboards/nova/snapshots/forms.py
  136. +30 −0 horizon/horizon/dashboards/nova/snapshots/panel.py
  137. +32 −43 ...penstack/tests/view_tests/dash/snapshots_tests.py → horizon/horizon/dashboards/nova/snapshots/tests.py
  138. +26 −0 horizon/horizon/dashboards/nova/snapshots/urls.py
  139. +18 −46 ...penstack/django_openstack/dash/views/snapshots.py → horizon/horizon/dashboards/nova/snapshots/views.py
  140. +2 −9 ..._openstack/templates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/base.html
  141. 0  ...plates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/containers/_delete.html
  142. 0  ...emplates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/containers/_form.html
  143. +3 −3 ...emplates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/containers/_list.html
  144. +3 −3 ...mplates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/containers/create.html
  145. +19 −0 horizon/horizon/dashboards/nova/templates/nova/containers/index.html
  146. 0  ...es/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/floating_ips/_allocate.html
  147. 0  ...s/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/floating_ips/_associate.html
  148. 0  ...jango_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/floating_ips/_disassociate.html
  149. +3 −3 ...plates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/floating_ips/_list.html
  150. 0  ...tes/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/floating_ips/_release.html
  151. +3 −3 ...es/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/floating_ips/associate.html
  152. +5 −5 ...plates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/floating_ips/index.html
  153. 0  .../templates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/images/_delete.html
  154. 0  ...ck/templates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/images/_form.html
  155. +1 −1  .../templates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/images/_launch.html
  156. 0  ...lates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/images/_launch_form.html
  157. +3 −3 ...ck/templates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/images/_list.html
  158. +4 −4 ...ck/templates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/images/index.html
  159. +3 −3 ...k/templates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/images/launch.html
  160. +3 −3 ...k/templates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/images/update.html
  161. 0  ...templates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/instances/_form.html
  162. +8 −8 ...templates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/instances/_list.html
  163. +4 −4 ...emplates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/instances/detail.html
  164. +6 −6 ...templates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/instances/index.html
  165. +5 −5 ...emplates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/instances/update.html
  166. 0  .../templates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/instances/usage.csv
  167. +5 −5 ...templates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/instances/usage.html
  168. 0  ...emplates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/keypairs/_delete.html
  169. 0  .../templates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/keypairs/_form.html
  170. +1 −1  .../templates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/keypairs/_list.html
  171. +4 −4 ...templates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/keypairs/create.html
  172. +4 −4 ...templates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/keypairs/import.html
  173. +8 −8 .../templates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/keypairs/index.html
  174. 0  ...emplates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/networks/_delete.html
  175. 0  ...tes/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/networks/_delete_port.html
  176. 0  ...tes/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/networks/_detach_port.html
  177. +4 −4 ...emplates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/networks/_detail.html
  178. 0  .../templates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/networks/_form.html
  179. +3 −3 .../templates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/networks/_list.html
  180. 0  ...emplates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/networks/_rename.html
  181. 0  ...tes/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/networks/_rename_form.html
  182. 0  ...tes/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/networks/_toggle_port.html
  183. +4 −4 ...templates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/networks/create.html
  184. +31 −0 horizon/horizon/dashboards/nova/templates/nova/networks/detail.html
  185. +6 −6 .../templates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/networks/index.html
  186. +4 −4 ...templates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/networks/rename.html
  187. 0  ...k/templates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/objects/_copy.html
  188. 0  ...templates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/objects/_delete.html
  189. 0  ...templates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/objects/_filter.html
  190. 0  ...k/templates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/objects/_form.html
  191. +3 −3 ...k/templates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/objects/_list.html
  192. 0  ...templates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/objects/_paging.html
  193. +4 −4 ...ck/templates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/objects/copy.html
  194. +6 −6 ...k/templates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/objects/index.html
  195. +4 −4 .../templates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/objects/upload.html
  196. 0  ...k/templates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/ports/_attach.html
  197. 0  ...k/templates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/ports/_create.html
  198. +4 −4 ...ck/templates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/ports/attach.html
  199. +4 −4 ...ck/templates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/ports/create.html
  200. 0  ...s/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/security_groups/_delete.html
  201. 0  ...ngo_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/security_groups/_delete_rule.html
  202. 0  ...tes/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/security_groups/_form.html
  203. +2 −2 ...tes/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/security_groups/_list.html
  204. +3 −3 ...es/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/security_groups/create.html
  205. +3 −3 ...jango_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/security_groups/edit_rules.html
  206. +6 −6 ...tes/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/security_groups/index.html
  207. +3 −3 ...nstack/templates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/settings.html
  208. 0  ...templates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/snapshots/_form.html
  209. +4 −4 ...emplates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/snapshots/create.html
  210. +5 −5 ...templates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/snapshots/index.html
  211. 0  ...ates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/volumes/_attach_form.html
  212. 0  ...templates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/volumes/_delete.html
  213. 0  ...ates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/volumes/_detach_form.html
  214. 0  ...k/templates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/volumes/_form.html
  215. +5 −5 ...k/templates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/volumes/_list.html
  216. +4 −4 .../templates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/volumes/attach.html
  217. +4 −4 .../templates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/volumes/create.html
  218. +3 −3 .../templates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/volumes/detail.html
  219. +5 −5 ...k/templates/django_openstack/dash → horizon/horizon/dashboards/nova/templates/nova}/volumes/index.html
  220. 0  ...ango_openstack/tests/templates/base-sidebar.html → horizon/horizon/dashboards/nova/volumes/__init__.py
  221. +8 −84 ...go-openstack/django_openstack/dash/views/volumes.py → horizon/horizon/dashboards/nova/volumes/forms.py
  222. +26 −0 horizon/horizon/dashboards/nova/volumes/panel.py
  223. 0  horizon/horizon/dashboards/nova/volumes/tests.py
  224. +25 −0 horizon/horizon/dashboards/nova/volumes/urls.py
  225. +110 −0 horizon/horizon/dashboards/nova/volumes/views.py
  226. 0  horizon/horizon/dashboards/settings/__init__.py
  227. +30 −0 horizon/horizon/dashboards/settings/dashboard.py
  228. +23 −0 horizon/horizon/dashboards/settings/models.py
  229. +13 −0 horizon/horizon/dashboards/settings/templates/settings/base.html
  230. +32 −0 horizon/horizon/dashboards/settings/templates/settings/user/settings.html
  231. 0  horizon/horizon/dashboards/settings/user/__init__.py
  232. +26 −0 horizon/horizon/dashboards/settings/user/panel.py
  233. +28 −0 horizon/horizon/dashboards/settings/user/urls.py
  234. 0  horizon/horizon/dashboards/syspanel/__init__.py
  235. +32 −0 horizon/horizon/dashboards/syspanel/dashboard.py
  236. 0  horizon/horizon/dashboards/syspanel/flavors/__init__.py
  237. +7 −60 ...tack/django_openstack/syspanel/views/flavors.py → horizon/horizon/dashboards/syspanel/flavors/forms.py
  238. +30 −0 horizon/horizon/dashboards/syspanel/flavors/panel.py
  239. 0  horizon/horizon/dashboards/syspanel/flavors/tests.py
  240. +26 −0 horizon/horizon/dashboards/syspanel/flavors/urls.py
  241. +77 −0 horizon/horizon/dashboards/syspanel/flavors/views.py
  242. 0  horizon/horizon/dashboards/syspanel/images/__init__.py
  243. +83 −0 horizon/horizon/dashboards/syspanel/images/forms.py
  244. +30 −0 horizon/horizon/dashboards/syspanel/images/panel.py
  245. 0  horizon/horizon/dashboards/syspanel/images/tests.py
  246. +26 −0 horizon/horizon/dashboards/syspanel/images/urls.py
  247. +26 −85 ...nstack/django_openstack/syspanel/views/images.py → horizon/horizon/dashboards/syspanel/images/views.py
  248. 0  horizon/horizon/dashboards/syspanel/instances/__init__.py
  249. +31 −0 horizon/horizon/dashboards/syspanel/instances/panel.py
  250. 0  horizon/horizon/dashboards/syspanel/instances/tests.py
  251. +11 −15 ...o-openstack/django_openstack/tests/testurls.py → horizon/horizon/dashboards/syspanel/instances/urls.py
  252. +106 −32 .../django_openstack/syspanel/views/instances.py → horizon/horizon/dashboards/syspanel/instances/views.py
  253. +23 −0 horizon/horizon/dashboards/syspanel/models.py
  254. 0  horizon/horizon/dashboards/syspanel/overview/__init__.py
  255. +31 −0 horizon/horizon/dashboards/syspanel/overview/panel.py
  256. +26 −0 horizon/horizon/dashboards/syspanel/overview/urls.py
  257. 0  horizon/horizon/dashboards/syspanel/quotas/__init__.py
  258. +30 −0 horizon/horizon/dashboards/syspanel/quotas/panel.py
  259. 0  horizon/horizon/dashboards/syspanel/quotas/tests.py
  260. +25 −0 horizon/horizon/dashboards/syspanel/quotas/urls.py
  261. +5 −17 ...nstack/django_openstack/syspanel/views/quotas.py → horizon/horizon/dashboards/syspanel/quotas/views.py
  262. 0  horizon/horizon/dashboards/syspanel/services/__init__.py
  263. +58 −0 horizon/horizon/dashboards/syspanel/services/forms.py
  264. +30 −0 horizon/horizon/dashboards/syspanel/services/panel.py
  265. 0  horizon/horizon/dashboards/syspanel/services/tests.py
  266. +25 −0 horizon/horizon/dashboards/syspanel/services/urls.py
  267. +11 −48 ...ck/django_openstack/syspanel/views/services.py → horizon/horizon/dashboards/syspanel/services/views.py
  268. +2 −9 ...enstack/templates/django_openstack → horizon/horizon/dashboards/syspanel/templates}/syspanel/base.html
  269. +1 −1  ...plates/django_openstack → horizon/horizon/dashboards/syspanel/templates}/syspanel/flavors/_create.html
  270. 0  ...plates/django_openstack → horizon/horizon/dashboards/syspanel/templates}/syspanel/flavors/_delete.html
  271. 0  ...emplates/django_openstack → horizon/horizon/dashboards/syspanel/templates}/syspanel/flavors/_form.html
  272. +1 −1  ...emplates/django_openstack → horizon/horizon/dashboards/syspanel/templates}/syspanel/flavors/_list.html
  273. +3 −3 ...mplates/django_openstack → horizon/horizon/dashboards/syspanel/templates}/syspanel/flavors/create.html
  274. +19 −0 horizon/horizon/dashboards/syspanel/templates/syspanel/flavors/index.html
  275. 0  ...mplates/django_openstack → horizon/horizon/dashboards/syspanel/templates}/syspanel/images/_delete.html
  276. 0  ...templates/django_openstack → horizon/horizon/dashboards/syspanel/templates}/syspanel/images/_form.html
  277. +3 −3 ...templates/django_openstack → horizon/horizon/dashboards/syspanel/templates}/syspanel/images/_list.html
  278. 0  ...mplates/django_openstack → horizon/horizon/dashboards/syspanel/templates}/syspanel/images/_toggle.html
  279. +4 −4 ...templates/django_openstack → horizon/horizon/dashboards/syspanel/templates}/syspanel/images/index.html
  280. +3 −3 ...emplates/django_openstack → horizon/horizon/dashboards/syspanel/templates}/syspanel/images/update.html
  281. +6 −6 ...plates/django_openstack → horizon/horizon/dashboards/syspanel/templates}/syspanel/instances/_list.html
  282. +5 −5 ...lates/django_openstack → horizon/horizon/dashboards/syspanel/templates}/syspanel/instances/detail.html
  283. +6 −6 ...plates/django_openstack → horizon/horizon/dashboards/syspanel/templates}/syspanel/instances/index.html
  284. 0  .../django_openstack → horizon/horizon/dashboards/syspanel/templates}/syspanel/instances/tenant_usage.csv
  285. +2 −2 ...django_openstack → horizon/horizon/dashboards/syspanel/templates}/syspanel/instances/tenant_usage.html
  286. 0  ...mplates/django_openstack → horizon/horizon/dashboards/syspanel/templates}/syspanel/instances/usage.csv
  287. +3 −3 ...plates/django_openstack → horizon/horizon/dashboards/syspanel/templates}/syspanel/instances/usage.html
  288. +3 −3 ...templates/django_openstack → horizon/horizon/dashboards/syspanel/templates}/syspanel/quotas/index.html
  289. +1 −1  ...mplates/django_openstack → horizon/horizon/dashboards/syspanel/templates}/syspanel/services/_list.html
  290. 0  ...lates/django_openstack → horizon/horizon/dashboards/syspanel/templates}/syspanel/services/_toggle.html
  291. +4 −4 ...mplates/django_openstack → horizon/horizon/dashboards/syspanel/templates}/syspanel/services/index.html
  292. 0  ...ates/django_openstack → horizon/horizon/dashboards/syspanel/templates}/syspanel/tenants/_add_user.html
  293. +1 −1  ...s/django_openstack → horizon/horizon/dashboards/syspanel/templates}/syspanel/tenants/_create_form.html
  294. 0  ...plates/django_openstack → horizon/horizon/dashboards/syspanel/templates}/syspanel/tenants/_delete.html
  295. 0  ...emplates/django_openstack → horizon/horizon/dashboards/syspanel/templates}/syspanel/tenants/_form.html
  296. +4 −4 ...emplates/django_openstack → horizon/horizon/dashboards/syspanel/templates}/syspanel/tenants/_list.html
  297. 0  ...s/django_openstack → horizon/horizon/dashboards/syspanel/templates}/syspanel/tenants/_quotas_form.html
  298. 0  ...s/django_openstack → horizon/horizon/dashboards/syspanel/templates}/syspanel/tenants/_remove_user.html
  299. +1 −1  ...s/django_openstack → horizon/horizon/dashboards/syspanel/templates}/syspanel/tenants/_update_form.html
  300. +1 −1  ...o_openstack → horizon/horizon/dashboards/syspanel/templates}/syspanel/tenants/_update_quotas_form.html
Sorry, we could not display the entire diff because too many files (447) changed.
View
16 .bzrignore
@@ -1,11 +1,11 @@
-django-openstack/.installed.cfg
-django-openstack/bin
-django-openstack/develop-eggs/
-django-openstack/downloads/
-django-openstack/eggs/
-django-openstack/parts/
-django-openstack/src/django_nova.egg-info
-django-openstack/src/django_openstack.egg-info
+horizon/.installed.cfg
+horizon/bin
+horizon/develop-eggs/
+horizon/downloads/
+horizon/eggs/
+horizon/parts/
+horizon/src/django_nova.egg-info
+horizon/src/django_openstack.egg-info
django-nova-syspanel/src/django_nova_syspanel.egg-info
openstack-dashboard/.dashboard-venv
openstack-dashboard/local/dashboard_openstack.sqlite3
View
23 .gitignore
@@ -5,19 +5,20 @@ coverage.xml
pep8.txt
pylint.txt
reports
-django-openstack/.installed.cfg
-django-openstack/bin
-django-openstack/develop-eggs/
-django-openstack/downloads/
-django-openstack/eggs/
-django-openstack/htmlcov
-django-openstack/launchpad
-django-openstack/parts/
-django-openstack/django_nova.egg-info
-django-openstack/django_openstack.egg-info
+horizon/.installed.cfg
+horizon/bin
+horizon/develop-eggs/
+horizon/downloads/
+horizon/eggs/
+horizon/htmlcov
+horizon/launchpad
+horizon/parts/
+horizon/django_nova.egg-info
+horizon/horizon.egg-info
+horizon/django_openstack.egg-info
django-nova-syspanel/src/django_nova_syspanel.egg-info
openstack-dashboard/.dashboard-venv
openstack-dashboard/local/dashboard_openstack.sqlite3
openstack-dashboard/local/local_settings.py
build/
-doc/source/sourcecode
+docs/source/sourcecode
View
34 README
@@ -4,14 +4,14 @@ OpenStack Dashboard (Horizon)
The OpenStack Dashboard is a Django based reference implementation of a web
based management interface for OpenStack.
-It is based on django-openstack, which is designed to be a generic Django
-module that can be re-used in other sites.
+It is based on the ``horizon`` module, which is designed to be a generic Django
+app that can be re-used in other projects.
For more information about how to get started with the OpenStack Dashboard,
view the README file in the openstack-dashboard folder.
-For more information about working directly with django-openstack, see the
-README file in the django-openstack folder.
+For more information about working directly with ``horizon``, see the
+README file in the ``horizon`` folder.
For release management:
@@ -29,21 +29,21 @@ Project Structure and Testing:
------------------------------
This project is a bit different from other Openstack projects in that it has
-two very distinct components underneath it: django-openstack, and
-openstack-dashboard.
+two very distinct components underneath it: ``horizon``, and
+``openstack-dashboard``.
-django-openstack holds the generic libraries and components that can be
-used in any Django project. In testing, this component is set up with
-buildout (see run_tests.sh), and any dependencies that get added need to
-be added to the django-openstack/buildout.cfg file.
+The ``horizon`` directory holds the generic libraries and components that can
+be used in any Django project. In testing, this component is set up with
+buildout (see ``run_tests.sh``), and any dependencies that get added need to
+be added to the ``horizon/buildout.cfg`` file.
-openstack-dashboard is a reference django project that uses django-openstack
-and is built with a virtualenv and tested through that environment. If
-depdendencies are added that the reference django project needs, they
-should be added to openstack-dashboard/tools/pip-requires.
+The ``openstack-dashboard`` directory contains a reference Django project that
+uses ``horizon`` and is built with a virtualenv and tested through that
+environment. If dependencies are added that ``openstack-dashboard`` requires
+they should be added to ``openstack-dashboard/tools/pip-requires``.
-The run_tests.sh script invokes tests and analysis on both of these
-components in it's process, and is what Jenkins uses to verify the
+The ``run_tests.sh`` script invokes tests and analyses on both of these
+components in its process, and is what Jenkins uses to verify the
stability of the project.
To run the tests::
@@ -55,7 +55,7 @@ Building Contributor Documentation
This documentation is written by contributors, for contributors.
-The source is maintained in the `doc/source` folder using
+The source is maintained in the ``docs/source`` folder using
`reStructuredText`_ and built by `Sphinx`_
.. _reStructuredText: http://docutils.sourceforge.net/rst.html
View
56 django-openstack/README
@@ -1,56 +0,0 @@
-Django-OpenStack
----------------------
-
-The Django-OpenStack project is a Django module that is used to provide web based
-interactions with an OpenStack cloud.
-
-There is a reference implementation that uses this module located at:
-
- http://launchpad.net/horizon
-
-It is highly recommended that you make use of this reference implementation
-so that changes you make can be visualized effectively and are consistent.
-Using this reference implementation as a development environment will greatly
-simplify development of the django-openstack module.
-
-Of course, if you are developing your own Django site using django-openstack, then
-you can disregard this advice.
-
-
-
-Getting Started
----------------
-
-Django-OpenStack uses Buildout (http://www.buildout.org/) to manage local
-development. To configure your local Buildout environment first install the following
-system-level dependencies:
- * python-dev
- * git
- * bzr
-
-Then instantiate buildout with
-
- $ python bootstrap.py
- $ bin/buildout
-
-This will install all the dependencies of django-openstack and provide some useful
-scripts in the bin/ directory:
-
- bin/python provides a python shell for the current buildout.
- bin/django provides django functions for the current buildout.
-
-
-You should now be able to run unit tests as follows:
-
- $ bin/django test
-or
- $ bin/test
-
-You can run unit tests with code coverage on django_openstack by setting
-NOSE_WITH_COVERAGE:
-
- $ NOSE_WITH_COVERAGE=true bin/test
-
-Get even better coverage info by running coverage directly:
-
- $ coverage run --branch --source django_openstack bin/django test django_openstack && coverage html
View
1,093 django-openstack/django_openstack/api.py
@@ -1,1093 +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.
-
-"""
-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, django_openstack developers not working on django_openstack.api
-shouldn't need to understand the finer details of APIs for
-Keystone/Nova/Glance/Swift et. al.
-"""
-
-import httplib
-import json
-import logging
-import urlparse
-
-from django.conf import settings
-from django.contrib import messages
-
-import cloudfiles
-from django_openstack import exceptions
-import openstack.compute
-import openstackx.admin
-import openstackx.api.exceptions as api_exceptions
-import openstackx.extras
-import openstackx.auth
-from glance import client as glance_client
-from glance.common import exception as glance_exceptions
-from novaclient import client as base_nova_client
-from keystoneclient import exceptions as keystone_exceptions
-from keystoneclient.v2_0 import client as keystone_client
-from novaclient.v1_1 import client as nova_client
-from quantum import client as quantum_client
-
-LOG = logging.getLogger('django_openstack.api')
-
-
-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:
- LOG.debug('Attempted to access unknown attribute "%s" on'
- ' APIResource object of type "%s" wrapping resource of'
- ' type "%s"' % (attr, self.__class__,
- self._apiresource.__class__))
- raise AttributeError(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 openstackx
- """
- def __init__(self, apidict):
- self._apidict = apidict
-
- def __getattr__(self, attr):
- if attr in self._attrs:
- try:
- return self._apidict[attr]
- except KeyError, e:
- raise AttributeError(e)
-
- else:
- LOG.debug('Attempted to access unknown item "%s" on'
- 'APIResource object of type "%s"'
- % (attr, self.__class__))
- raise AttributeError(attr)
-
- def __getitem__(self, item):
- try:
- return self.__getattr__(item)
- except AttributeError, e:
- # caller is expecting a KeyError
- raise KeyError(e)
-
- def get(self, item, default=None):
- try:
- return self.__getattr__(item)
- except AttributeError:
- return default
-
-
-class Container(APIResourceWrapper):
- """Simple wrapper around cloudfiles.container.Container"""
- _attrs = ['name']
-
-
-class Console(APIResourceWrapper):
- """Simple wrapper around openstackx.extras.consoles.Console"""
- _attrs = ['id', 'output', 'type']
-
-
-class Flavor(APIResourceWrapper):
- """Simple wrapper around openstackx.admin.flavors.Flavor"""
- _attrs = ['disk', 'id', 'links', 'name', 'ram', 'vcpus']
-
-
-class FloatingIp(APIResourceWrapper):
- """Simple wrapper for floating ips"""
- _attrs = ['ip', 'fixed_ip', 'instance_id', 'id']
-
-
-class Image(APIDictWrapper):
- """Simple wrapper around glance image dictionary"""
- _attrs = ['checksum', 'container_format', 'created_at', 'deleted',
- 'deleted_at', 'disk_format', 'id', 'is_public', 'location',
- 'name', 'properties', 'size', 'status', 'updated_at', 'owner']
-
- def __getattr__(self, attrname):
- if attrname == "properties":
- return ImageProperties(super(Image, self).__getattr__(attrname))
- else:
- return super(Image, self).__getattr__(attrname)
-
-
-class ImageProperties(APIDictWrapper):
- """Simple wrapper around glance image properties dictionary"""
- _attrs = ['architecture', 'image_location', 'image_state', 'kernel_id',
- 'project_id', 'ramdisk_id']
-
-
-class KeyPair(APIResourceWrapper):
- """Simple wrapper around openstackx.extras.keypairs.Keypair"""
- _attrs = ['fingerprint', 'name', 'private_key']
-
-
-class Volume(APIResourceWrapper):
- """Nova Volume representation"""
- _attrs = ['id', 'status', 'displayName', 'size', 'volumeType', 'createdAt',
- 'attachments', 'displayDescription']
-
-
-class Server(APIResourceWrapper):
- """Simple wrapper around openstackx.extras.server.Server
-
- Preserves the request info so image name can later be retrieved
- """
- _attrs = ['addresses', 'attrs', 'hostId', 'id', 'image', 'links',
- 'metadata', 'name', 'private_ip', 'public_ip', 'status', 'uuid',
- 'image_name', 'VirtualInterfaces']
-
- def __init__(self, apiresource, request):
- super(Server, self).__init__(apiresource)
- self.request = request
-
- def __getattr__(self, attr):
- if attr == "attrs":
- return ServerAttributes(super(Server, self).__getattr__(attr))
- else:
- return super(Server, self).__getattr__(attr)
-
- @property
- def image_name(self):
- try:
- image = image_get(self.request, self.image['id'])
- return image.name
- except glance_exceptions.NotFound:
- return "(not found)"
-
- def reboot(self, hardness=openstack.compute.servers.REBOOT_HARD):
- compute_api(self.request).servers.reboot(self.id, hardness)
-
-
-class ServerAttributes(APIDictWrapper):
- """Simple wrapper around openstackx.extras.server.Server attributes
-
- Preserves the request info so image name can later be retrieved
- """
- _attrs = ['description', 'disk_gb', 'host', 'image_ref', 'kernel_id',
- 'key_name', 'launched_at', 'mac_address', 'memory_mb', 'name',
- 'os_type', 'tenant_id', 'ramdisk_id', 'scheduled_at',
- 'terminated_at', 'user_data', 'user_id', 'vcpus', 'hostname',
- 'security_groups']
-
-
-class Services(APIResourceWrapper):
- _attrs = ['disabled', 'host', 'id', 'last_update', 'stats', 'type', 'up',
- 'zone']
-
-
-class SwiftObject(APIResourceWrapper):
- _attrs = ['name']
-
-
-class Tenant(APIResourceWrapper):
- """Simple wrapper around keystoneclient.tenants.Tenant"""
- _attrs = ['id', 'description', 'enabled', 'name']
-
-
-class Token(APIResourceWrapper):
- """Simple wrapper around keystoneclient.tokens.Tenant"""
- _attrs = ['id', 'user', 'serviceCatalog', 'tenant']
-
-
-class Usage(APIResourceWrapper):
- """Simple wrapper around openstackx.extras.usage.Usage"""
- _attrs = ['begin', 'instances', 'stop', 'tenant_id',
- 'total_active_disk_size', 'total_active_instances',
- 'total_active_ram_size', 'total_active_vcpus', 'total_cpu_usage',
- 'total_disk_usage', 'total_hours', 'total_ram_usage']
-
-
-class User(APIResourceWrapper):
- """Simple wrapper around keystoneclient.users.User"""
- _attrs = ['email', 'enabled', 'id', 'tenantId', 'name']
-
-
-class Role(APIResourceWrapper):
- """Wrapper around keystoneclient.roles.role"""
- _attrs = ['id', 'name', 'description', 'service_id']
-
-
-class SecurityGroup(APIResourceWrapper):
- """Simple wrapper around openstackx.extras.security_groups.SecurityGroup"""
- _attrs = ['id', 'name', 'description', 'tenant_id', 'rules']
-
-
-class SecurityGroupRule(APIResourceWrapper):
- """Simple wrapper around
- openstackx.extras.security_groups.SecurityGroupRule"""
- _attrs = ['id', 'parent_group_id', 'group_id', 'ip_protocol',
- 'from_port', 'to_port', 'groups', 'ip_ranges']
-
-
-class SecurityGroupRule(APIResourceWrapper):
- """Simple wrapper around openstackx.extras.users.User"""
- _attrs = ['id', 'name', 'description', 'tenant_id', 'security_group_rules']
-
-
-class SwiftAuthentication(object):
- """Auth container to pass CloudFiles storage URL and token from
- session.
- """
- def __init__(self, storage_url, auth_token):
- self.storage_url = storage_url
- self.auth_token = auth_token
-
- def authenticate(self):
- return (self.storage_url, '', self.auth_token)
-
-
-class ServiceCatalogException(api_exceptions.ApiException):
- def __init__(self, service_name):
- message = 'Invalid service catalog service: %s' % service_name
- super(ServiceCatalogException, self).__init__(404, message)
-
-
-class VirtualInterface(APIResourceWrapper):
- _attrs = ['id', 'mac_address']
-
-
-def get_service_from_catalog(catalog, service_type):
- for service in catalog:
- if service['type'] == service_type:
- return service
- return None
-
-
-def url_for(request, service_type, admin=False):
- catalog = request.user.service_catalog
- service = get_service_from_catalog(catalog, service_type)
- if service:
- try:
- if admin:
- return service['endpoints'][0]['adminURL']
- else:
- return service['endpoints'][0]['internalURL']
- except (IndexError, KeyError):
- raise ServiceCatalogException(service_type)
- else:
- raise ServiceCatalogException(service_type)
-
-
-def check_openstackx(f):
- """Decorator that adds extra info to api exceptions
-
- The OpenStack Dashboard currently depends on openstackx extensions
- being present in Nova. Error messages depending for views depending
- on these extensions do not lead to the conclusion that Nova is missing
- extensions.
-
- This decorator should be dropped and removed after Keystone and
- Horizon more gracefully handle extensions and openstackx extensions
- aren't required by Horizon in Nova.
- """
- def inner(*args, **kwargs):
- try:
- return f(*args, **kwargs)
- except api_exceptions.NotFound, e:
- e.message = e.details or ''
- e.message += ' This error may be caused by a misconfigured' \
- ' Nova url in keystone\'s service catalog, or ' \
- ' by missing openstackx extensions in Nova. ' \
- ' See the Horizon README.'
- raise
-
- return inner
-
-
-def compute_api(request):
- compute = openstack.compute.Compute(
- auth_token=request.user.token,
- management_url=url_for(request, 'compute'))
- # this below hack is necessary to make the jacobian compute client work
- # TODO(mgius): It looks like this is unused now?
- compute.client.auth_token = request.user.token
- compute.client.management_url = url_for(request, 'compute')
- LOG.debug('compute_api connection created using token "%s"'
- ' and url "%s"' %
- (request.user.token, url_for(request, 'compute')))
- return compute
-
-
-def glance_api(request):
- o = urlparse.urlparse(url_for(request, 'image'))
- LOG.debug('glance_api connection created for host "%s:%d"' %
- (o.hostname, o.port))
- return glance_client.Client(o.hostname,
- o.port,
- auth_tok=request.user.token)
-
-
-def admin_api(request):
- LOG.debug('admin_api connection created using token "%s"'
- ' and url "%s"' %
- (request.user.token, url_for(request, 'compute', True)))
- return openstackx.admin.Admin(auth_token=request.user.token,
- management_url=url_for(request, 'compute', True))
-
-
-def extras_api(request):
- LOG.debug('extras_api connection created using token "%s"'
- ' and url "%s"' %
- (request.user.token, url_for(request, 'compute')))
- return openstackx.extras.Extras(auth_token=request.user.token,
- management_url=url_for(request, 'compute'))
-
-
-def novaclient(request):
- LOG.debug('novaclient connection created using token "%s" and url "%s"' %
- (request.user.token, url_for(request, 'compute')))
- c = nova_client.Client(username=request.user.username,
- api_key=request.user.token,
- project_id=request.user.tenant_id,
- auth_url=url_for(request, 'compute'))
- c.client.auth_token = request.user.token
- c.client.management_url = url_for(request, 'compute')
- return c
-
-
-def keystoneclient(request, username=None, password=None, tenant_id=None,
- token_id=None, endpoint=None):
- """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.
-
- The client is cached so that subsequent API calls during the same
- request/response cycle don't have to be re-authenticated.
- """
- # Take care of client connection caching/fetching a new client
- user = request.user
- if (hasattr(request, '_keystone') and
- request._keystone.auth_token == user.token):
- conn = request._keystone
- else:
- conn = keystone_client.Client(username=username or user.username,
- password=password,
- project_id=tenant_id or user.tenant_id,
- token=token_id or user.token,
- auth_url=settings.OPENSTACK_KEYSTONE_URL,
- endpoint=endpoint)
- request._keystone = conn
-
- # Fetch the correct endpoint for the user type
- catalog = getattr(conn, 'service_catalog', None)
- if catalog and "serviceCatalog" in catalog.catalog.keys():
- if user.is_admin():
- endpoint = catalog.url_for(service_type='identity',
- endpoint_type='adminURL')
- else:
- endpoint = catalog.url_for(service_type='identity',
- endpoint_type='publicURL')
- else:
- endpoint = settings.OPENSTACK_KEYSTONE_URL
- conn.management_url = endpoint
-
- return conn
-
-
-def swift_api(request):
- LOG.debug('object store connection created using token "%s"'
- ' and url "%s"' %
- (request.session['token'], url_for(request, 'object-store')))
- auth = SwiftAuthentication(url_for(request, 'object-store'),
- request.session['token'])
- return cloudfiles.get_connection(auth=auth)
-
-
-def quantum_api(request):
- tenant = None
- if hasattr(request, 'user'):
- tenant = request.user.tenant_id
- else:
- tenant = settings.QUANTUM_TENANT
-
- return quantum_client.Client(settings.QUANTUM_URL, settings.QUANTUM_PORT,
- False, tenant, 'json')
-
-
-def console_create(request, instance_id, kind='text'):
- return Console(extras_api(request).consoles.create(instance_id, kind))
-
-
-def flavor_create(request, name, memory, vcpu, disk, flavor_id):
- # TODO -- convert to novaclient when novaclient adds create support
- return Flavor(admin_api(request).flavors.create(
- name, int(memory), int(vcpu), int(disk), flavor_id))
-
-
-def flavor_delete(request, flavor_id, purge=False):
- # TODO -- convert to novaclient when novaclient adds delete support
- admin_api(request).flavors.delete(flavor_id, purge)
-
-
-def flavor_get(request, flavor_id):
- return Flavor(novaclient(request).flavors.get(flavor_id))
-
-
-def flavor_list(request):
- return [Flavor(f) for f in novaclient(request).flavors.list()]
-
-
-def tenant_floating_ip_list(request):
- """
- Fetches a list of all floating ips.
- """
- return [FloatingIp(ip) for ip in novaclient(request).floating_ips.list()]
-
-
-def tenant_floating_ip_get(request, floating_ip_id):
- """
- Fetches a floating ip.
- """
- return novaclient(request).floating_ips.get(floating_ip_id)
-
-
-def tenant_floating_ip_allocate(request):
- """
- Allocates a floating ip to tenant.
- """
- return novaclient(request).floating_ips.create()
-
-
-def tenant_floating_ip_release(request, floating_ip_id):
- """
- Releases floating ip from the pool of a tenant.
- """
- return novaclient(request).floating_ips.delete(floating_ip_id)
-
-
-def image_create(request, image_meta, image_file):
- return Image(glance_api(request).add_image(image_meta, image_file))
-
-
-def image_delete(request, image_id):
- return glance_api(request).delete_image(image_id)
-
-
-def image_get(request, image_id):
- return Image(glance_api(request).get_image(image_id)[0])
-
-
-def image_list_detailed(request):
- return [Image(i) for i in glance_api(request).get_images_detailed()]
-
-
-def snapshot_list_detailed(request):
- filters = {}
- filters['property-image_type'] = 'snapshot'
- filters['is_public'] = 'none'
- return [Image(i) for i in glance_api(request)
- .get_images_detailed(filters=filters)]
-
-
-def snapshot_create(request, instance_id, name):
- return novaclient(request).servers.create_image(instance_id, name)
-
-
-def image_update(request, image_id, image_meta=None):
- image_meta = image_meta and image_meta or {}
- return Image(glance_api(request).update_image(image_id,
- image_meta=image_meta))
-
-
-def keypair_create(request, name):
- return KeyPair(novaclient(request).keypairs.create(name))
-
-
-def keypair_import(request, name, public_key):
- return KeyPair(novaclient(request).keypairs.create(name, public_key))
-
-
-def keypair_delete(request, keypair_id):
- novaclient(request).keypairs.delete(keypair_id)
-
-
-def keypair_list(request):
- return [KeyPair(key) for key in novaclient(request).keypairs.list()]
-
-
-def volume_list(request):
- return [Volume(vol) for vol in novaclient(request).volumes.list()]
-
-
-def volume_get(request, volume_id):
- return Volume(novaclient(request).volumes.get(volume_id))
-
-
-def volume_instance_list(request, instance_id):
- return novaclient(request).volumes.get_server_volumes(instance_id)
-
-
-def volume_create(request, size, name, description):
- return Volume(novaclient(request).volumes.create(
- size, name, description))
-
-
-def volume_delete(request, volume_id):
- novaclient(request).volumes.delete(volume_id)
-
-
-def volume_attach(request, volume_id, instance_id, device):
- novaclient(request).volumes.create_server_volume(
- instance_id, volume_id, device)
-
-
-def volume_detach(request, instance_id, attachment_id):
- novaclient(request).volumes.delete_server_volume(
- instance_id, attachment_id)
-
-
-def server_create(request, name, image, flavor,
- key_name, user_data, security_groups):
- return Server(novaclient(request).servers.create(
- name, image, flavor, userdata=user_data,
- security_groups=security_groups,
- key_name=key_name), request)
-
-
-def server_delete(request, instance):
- compute_api(request).servers.delete(instance)
-
-
-def server_get(request, instance_id):
- return Server(extras_api(request).servers.get(instance_id), request)
-
-
-@check_openstackx
-def server_list(request):
- return [Server(s, request) for s in extras_api(request).servers.list()]
-
-
-@check_openstackx
-def admin_server_list(request):
- return [Server(s, request) for s in admin_api(request).servers.list()]
-
-
-def server_reboot(request,
- instance_id,
- hardness=openstack.compute.servers.REBOOT_HARD):
- server = server_get(request, instance_id)
- server.reboot(hardness)
-
-
-def server_update(request, instance_id, name, description):
- return extras_api(request).servers.update(instance_id,
- name=name,
- description=description)
-
-
-def server_add_floating_ip(request, server, address):
- """
- Associates floating IP to server's fixed IP.
- """
- server = novaclient(request).servers.get(server)
- fip = novaclient(request).floating_ips.get(address)
-
- return novaclient(request).servers.add_floating_ip(server, fip)
-
-
-def server_remove_floating_ip(request, server, address):
- """
- Removes relationship between floating and server's fixed ip.
- """
- fip = novaclient(request).floating_ips.get(address)
- server = novaclient(request).servers.get(fip.instance_id)
-
- return novaclient(request).servers.remove_floating_ip(server, fip)
-
-
-def service_get(request, name):
- return Services(admin_api(request).services.get(name))
-
-
-@check_openstackx
-def service_list(request):
- return [Services(s) for s in admin_api(request).services.list()]
-
-
-def service_update(request, name, enabled):
- return Services(admin_api(request).services.update(name, enabled))
-
-
-def tenant_create(request, tenant_name, description, enabled):
- return Tenant(keystoneclient(request).tenants.create(tenant_name,
- description,
- enabled))
-
-
-def tenant_get(request, tenant_id):
- return Tenant(keystoneclient(request).tenants.get(tenant_id))
-
-
-def tenant_delete(request, tenant_id):
- keystoneclient(request).tenants.delete(tenant_id)
-
-
-def tenant_list(request):
- return [Tenant(t) for t in keystoneclient(request).tenants.list()]
-
-
-def tenant_update(request, tenant_id, tenant_name, description, enabled):
- return Tenant(keystoneclient(request).tenants.update(tenant_id,
- tenant_name,
- description,
- enabled))
-
-
-def tenant_delete(request, tenant_id):
- keystoneclient(request).tenants.delete(tenant_id)
-
-
-def tenant_list_for_token(request, token):
- c = keystoneclient(request, token_id=token,
- endpoint=settings.OPENSTACK_KEYSTONE_URL)
- return [Tenant(t) for t in c.tenants.list()]
-
-
-def token_create(request, tenant, username, password):
- '''
- Creates a token using the username and password provided. If tenant
- is provided it will retrieve a scoped token and the service catalog for
- the given tenant. Otherwise it will return an unscoped token and without
- a service catalog.
- '''
- c = keystoneclient(request, username=username, password=password,
- tenant_id=tenant,
- endpoint=settings.OPENSTACK_KEYSTONE_URL)
- token = c.tokens.authenticate(username=username,
- password=password,
- tenant=tenant)
- return Token(token)
-
-
-def token_create_scoped(request, tenant, token):
- '''
- Creates a scoped token using the tenant id and unscoped token; retrieves
- the service catalog for the given tenant.
- '''
- if hasattr(request, '_keystone'):
- del request._keystone
- c = keystoneclient(request, tenant_id=tenant, token_id=token,
- endpoint=settings.OPENSTACK_KEYSTONE_URL)
- scoped_token = c.tokens.authenticate(tenant=tenant, token=token)
- return Token(scoped_token)
-
-
-def tenant_quota_get(request, tenant):
- return novaclient(request).quotas.get(tenant)
-
-
-@check_openstackx
-def usage_get(request, tenant_id, start, end):
- return Usage(extras_api(request).usage.get(tenant_id, start, end))
-
-
-@check_openstackx
-def usage_list(request, start, end):
- return [Usage(u) for u in extras_api(request).usage.list(start, end)]
-
-
-def security_group_list(request):
- return [SecurityGroup(g) for g in novaclient(request).\
- security_groups.list()]
-
-
-def security_group_get(request, security_group_id):
- return SecurityGroup(novaclient(request).\
- security_groups.get(security_group_id))
-
-
-def security_group_create(request, name, description):
- return SecurityGroup(novaclient(request).\
- security_groups.create(name, description))
-
-
-def security_group_delete(request, security_group_id):
- novaclient(request).security_groups.delete(security_group_id)
-
-
-def security_group_rule_create(request, parent_group_id, ip_protocol=None,
- from_port=None, to_port=None, cidr=None,
- group_id=None):
- return SecurityGroup(novaclient(request).\
- security_group_rules.create(parent_group_id,
- ip_protocol,
- from_port,
- to_port,
- cidr,
- group_id))
-
-
-def security_group_rule_delete(request, security_group_rule_id):
- novaclient(request).security_group_rules.delete(security_group_rule_id)
-
-
-def user_list(request, tenant_id=None):
- return [User(u) for u in
- keystoneclient(request).users.list(tenant_id=tenant_id)]
-
-
-def user_create(request, user_id, email, password, tenant_id, enabled):
- return User(keystoneclient(request).users.create(
- user_id, password, email, tenant_id, enabled))
-
-
-def user_delete(request, user_id):
- keystoneclient(request).users.delete(user_id)
-
-
-def user_get(request, user_id):
- return User(keystoneclient(request).users.get(user_id))
-
-
-def user_update_email(request, user_id, email):
- return User(keystoneclient(request).users.update_email(user_id, email))
-
-
-def user_update_enabled(request, user_id, enabled):
- return User(keystoneclient(request).users.update_enabled(user_id, enabled))
-
-
-def user_update_password(request, user_id, password):
- return User(keystoneclient(request).users.update_password(user_id,
- password))
-
-
-def user_update_tenant(request, user_id, tenant_id):
- return User(keystoneclient(request).users.update_tenant(user_id,
- tenant_id))
-
-
-def _get_role(request, name):
- roles = keystoneclient(request).roles.list()
- for role in roles:
- if role.name.lower() == name.lower():
- return role
-
- raise Exception(_('Role does not exist: %s') % name)
-
-
-def _get_roleref(request, user_id, tenant_id, role):
- rolerefs = keystoneclient(request).roles.get_user_role_refs(user_id)
- for roleref in rolerefs:
- if roleref.roleId == role.id and roleref.tenantId == tenant_id:
- return roleref
- raise Exception(_('Role "%s" does not exist for that user on this tenant.')
- % role.name)
-
-
-def role_add_for_tenant_user(request, tenant_id, user_id, role):
- role = _get_role(request, role)
- return keystoneclient(request).roles.add_user_to_tenant(tenant_id,
- user_id,
- role.id)
-
-
-def role_delete_for_tenant_user(request, tenant_id, user_id, role):
- role = _get_role(request, role)
- roleref = _get_roleref(request, user_id, tenant_id, role)
- return keystoneclient(request).roles.remove_user_from_tenant(tenant_id,
- user_id,
- roleref.id)
-
-
-def swift_container_exists(request, container_name):
- try:
- swift_api(request).get_container(container_name)
- return True
- except cloudfiles.errors.NoSuchContainer:
- return False
-
-
-def swift_object_exists(request, container_name, object_name):
- container = swift_api(request).get_container(container_name)
-
- try:
- container.get_object(object_name)
- return True
- except cloudfiles.errors.NoSuchObject:
- return False
-
-
-def swift_get_containers(request, marker=None):
- return [Container(c) for c in swift_api(request).get_all_containers(
- limit=getattr(settings, 'SWIFT_PAGINATE_LIMIT', 10000),
- marker=marker)]
-
-
-def swift_create_container(request, name):
- if swift_container_exists(request, name):
- raise Exception('Container with name %s already exists.' % (name))
-
- return Container(swift_api(request).create_container(name))
-
-
-def swift_delete_container(request, name):
- swift_api(request).delete_container(name)
-
-
-def swift_get_objects(request, container_name, prefix=None, marker=None):
- container = swift_api(request).get_container(container_name)
- objects = container.get_objects(prefix=prefix, marker=marker,
- limit=getattr(settings, 'SWIFT_PAGINATE_LIMIT', 10000))
- return [SwiftObject(o) for o in objects]
-
-
-def swift_copy_object(request, orig_container_name, orig_object_name,
- new_container_name, new_object_name):
-
- container = swift_api(request).get_container(orig_container_name)
-
- if swift_object_exists(request,
- new_container_name,
- new_object_name) == True:
- raise Exception('Object with name %s already exists in container %s'
- % (new_object_name, new_container_name))
-
- orig_obj = container.get_object(orig_object_name)
- return orig_obj.copy_to(new_container_name, new_object_name)
-
-
-def swift_upload_object(request, container_name, object_name, object_data):
- container = swift_api(request).get_container(container_name)
- obj = container.create_object(object_name)
- obj.write(object_data)
-
-
-def swift_delete_object(request, container_name, object_name):
- container = swift_api(request).get_container(container_name)
- container.delete_object(object_name)
-
-
-def swift_get_object_data(request, container_name, object_name):
- container = swift_api(request).get_container(container_name)
- return container.get_object(object_name).stream()
-
-
-def quantum_list_networks(request):
- return quantum_api(request).list_networks()
-
-
-def quantum_network_details(request, network_id):
- return quantum_api(request).show_network_details(network_id)
-
-
-def quantum_list_ports(request, network_id):
- return quantum_api(request).list_ports(network_id)
-
-
-def quantum_port_details(request, network_id, port_id):
- return quantum_api(request).show_port_details(network_id, port_id)
-
-
-def quantum_create_network(request, data):
- return quantum_api(request).create_network(data)
-
-
-def quantum_delete_network(request, network_id):
- return quantum_api(request).delete_network(network_id)
-
-
-def quantum_update_network(request, network_id, data):
- return quantum_api(request).update_network(network_id, data)
-
-
-def quantum_create_port(request, network_id):
- return quantum_api(request).create_port(network_id)
-
-
-def quantum_delete_port(request, network_id, port_id):
- return quantum_api(request).delete_port(network_id, port_id)
-
-
-def quantum_attach_port(request, network_id, port_id, data):
- return quantum_api(request).attach_resource(network_id, port_id, data)
-
-
-def quantum_detach_port(request, network_id, port_id):
- return quantum_api(request).detach_resource(network_id, port_id)
-
-
-def quantum_set_port_state(request, network_id, port_id, data):
- return quantum_api(request).set_port_state(network_id, port_id, data)
-
-
-def quantum_port_attachment(request, network_id, port_id):
- return quantum_api(request).show_port_attachment(network_id, port_id)
-
-
-def get_vif_ids(request):
- vifs = []
- attached_vifs = []
- # Get a list of all networks
- networks_list = quantum_api(request).list_networks()
- for network in networks_list['networks']:
- ports = quantum_api(request).list_ports(network['id'])
- # Get port attachments
- for port in ports['ports']:
- port_attachment = quantum_api(request).show_port_attachment(
- network['id'],
- port['id'])
- if port_attachment['attachment']:
- attached_vifs.append(
- port_attachment['attachment']['id'].encode('ascii'))
- # Get all instances
- instances = server_list(request)
- # Get virtual interface ids by instance
- for instance in instances:
- id = instance.id
- instance_vifs = extras_api(request).virtual_interfaces.list(id)
- for vif in instance_vifs:
- # Check if this VIF is already connected to any port
- if str(vif.id) in attached_vifs:
- vifs.append({
- 'id': vif.id,
- 'instance': instance.id,
- 'instance_name': instance.name,
- 'available': False})
- else:
- vifs.append({
- 'id': vif.id,
- 'instance': instance.id,
- 'instance_name': instance.name,
- 'available': True})
- return vifs
-
-
-class GlobalSummary(object):
- node_resources = ['vcpus', 'disk_size', 'ram_size']
- unit_mem_size = {'disk_size': ['GiB', 'TiB'], 'ram_size': ['MiB', 'GiB']}
- node_resource_info = ['', 'active_', 'avail_']
-
- def __init__(self, request):
- self.summary = {}
- for rsrc in GlobalSummary.node_resources:
- for info in GlobalSummary.node_resource_info:
- self.summary['total_' + info + rsrc] = 0
- self.request = request
- self.service_list = []
- self.usage_list = []
-
- def service(self):
- try:
- self.service_list = service_list(self.request)
- except api_exceptions.ApiException, e:
- self.service_list = []
- LOG.exception('ApiException fetching service list in instance '
- 'usage')
- messages.error(self.request,
- _('Unable to get service info: %s') % e.message)
- return
-
- for service in self.service_list:
- if service.type == 'nova-compute':
- self.summary['total_vcpus'] += min(service.stats['max_vcpus'],
- service.stats.get('vcpus', 0))
- self.summary['total_disk_size'] += min(
- service.stats['max_gigabytes'],
- service.stats.get('local_gb', 0))
- self.summary['total_ram_size'] += min(
- service.stats['max_ram'],
- service.stats['memory_mb']) if 'max_ram' \
- in service.stats \
- else service.stats.get('memory_mb', 0)
-
- def usage(self, datetime_start, datetime_end):
- try:
- self.usage_list = usage_list(self.request, datetime_start,
- datetime_end)
- except api_exceptions.ApiException, e:
- self.usage_list = []
- LOG.exception('ApiException fetching usage list in instance usage'
- ' on date range "%s to %s"' % (datetime_start,
- datetime_end))
- messages.error(self.request,
- _('Unable to get usage info: %s') % e.message)
- return
-
- for usage in self.usage_list:
- # FIXME: api needs a simpler dict interface (with iteration)
- # - anthony
- # NOTE(mgius): Changed this on the api end. Not too much
- # neater, but at least its not going into private member
- # data of an external class anymore
- # usage = usage._info
- for k in usage._attrs:
- v = usage.__getattr__(k)
- if type(v) in [float, int]:
- if not k in self.summary:
- self.summary[k] = 0
- self.summary[k] += v
-
- def human_readable(self, rsrc):
- if self.summary['total_' + rsrc] > 1023:
- self.summary['unit_' + rsrc] = GlobalSummary.unit_mem_size[rsrc][1]
- mult = 1024.0
- else:
- self.summary['unit_' + rsrc] = GlobalSummary.unit_mem_size[rsrc][0]
- mult = 1.0
-
- for kind in GlobalSummary.node_resource_info:
- self.summary['total_' + kind + rsrc + '_hr'] = \
- self.summary['total_' + kind + rsrc] / mult
-
- def avail(self):
- for rsrc in GlobalSummary.node_resources:
- self.summary['total_avail_' + rsrc] = \
- self.summary['total_' + rsrc] - \
- self.summary['total_active_' + rsrc]
View
48 django-openstack/django_openstack/context_processors.py
@@ -1,48 +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.conf import settings
-from django_openstack import api
-from django.contrib import messages
-from openstackx.api import exceptions as api_exceptions
-
-
-def tenants(request):
- if not request.user or not request.user.is_authenticated():
- return {}
-
- try:
- return {'tenants': api.tenant_list_for_token(request,
- request.user.token)}
- except api_exceptions.BadRequest, e:
- messages.error(request, _("Unable to retrieve tenant list from\
- keystone: %s") % e.message)
- return {'tenants': []}
-
-
-def object_store(request):
- catalog = getattr(request.user, 'service_catalog', [])
- object_store = catalog and api.get_service_from_catalog(catalog,
- 'object-store')
- return {'object_store_configured': object_store}
-
-
-def quantum(request):
- return {'quantum_configured': settings.QUANTUM_ENABLED}
View
118 django-openstack/django_openstack/dash/urls.py
@@ -1,118 +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.conf.urls.defaults import *
-
-SECURITY_GROUPS = r'^(?P<tenant_id>[^/]+)/security_groups/' \
- '(?P<security_group_id>[^/]+)/%s$'
-INSTANCES = r'^(?P<tenant_id>[^/]+)/instances/(?P<instance_id>[^/]+)/%s$'
-IMAGES = r'^(?P<tenant_id>[^/]+)/images/(?P<image_id>[^/]+)/%s$'
-KEYPAIRS = r'^(?P<tenant_id>[^/]+)/keypairs/%s$'
-SNAPSHOTS = r'^(?P<tenant_id>[^/]+)/snapshots/(?P<instance_id>[^/]+)/%s$'
-VOLUMES = r'^(?P<tenant_id>[^/]+)/volumes/(?P<volume_id>[^/]+)/%s$'
-CONTAINERS = r'^(?P<tenant_id>[^/]+)/containers/%s$'
-FLOATING_IPS = r'^(?P<tenant_id>[^/]+)/floating_ips/(?P<ip_id>[^/]+)/%s$'
-OBJECTS = r'^(?P<tenant_id>[^/]+)/containers/(?P<container_name>[^/]+)/%s$'
-NETWORKS = r'^(?P<tenant_id>[^/]+)/networks/%s$'
-PORTS = r'^(?P<tenant_id>[^/]+)/networks/(?P<network_id>[^/]+)/ports/%s$'
-
-urlpatterns = patterns('django_openstack.dash.views.instances',
- url(r'^(?P<tenant_id>[^/]+)/$', 'usage', name='dash_usage'),
- url(r'^(?P<tenant_id>[^/]+)/instances/$', 'index', name='dash_instances'),
- url(r'^(?P<tenant_id>[^/]+)/instances/refresh$', 'refresh',
- name='dash_instances_refresh'),
- url(INSTANCES % 'detail', 'detail', name='dash_instances_detail'),
- url(INSTANCES % 'console', 'console', name='dash_instances_console'),
- url(INSTANCES % 'vnc', 'vnc', name='dash_instances_vnc'),
- url(INSTANCES % 'update', 'update', name='dash_instances_update'),
-)
-
-urlpatterns += patterns('django_openstack.dash.views.security_groups',
- url(r'^(?P<tenant_id>[^/]+)/security_groups/$', 'index',
- name='dash_security_groups'),
- url(r'^(?P<tenant_id>[^/]+)/security_groups/create$', 'create',
- name='dash_security_groups_create'),
- url(SECURITY_GROUPS % 'edit_rules', 'edit_rules',
- name='dash_security_groups_edit_rules'),
-)
-
-urlpatterns += patterns('django_openstack.dash.views.images',
- url(r'^(?P<tenant_id>[^/]+)/images/$', 'index', name='dash_images'),
- url(IMAGES % 'launch', 'launch', name='dash_images_launch'),
- url(IMAGES % 'update', 'update', name='dash_images_update'),
-)
-
-urlpatterns += patterns('django_openstack.dash.views.keypairs',
- url(r'^(?P<tenant_id>[^/]+)/keypairs/$', 'index', name='dash_keypairs'),
- url(KEYPAIRS % 'create', 'create', name='dash_keypairs_create'),
- url(KEYPAIRS % 'import', 'import_keypair', name='dash_keypairs_import'),
-)
-
-urlpatterns += patterns('django_openstack.dash.views.floating_ips',
- url(r'^(?P<tenant_id>[^/]+)/floating_ips/$', 'index',
- name='dash_floating_ips'),
- url(FLOATING_IPS % 'associate', 'associate',
- name='dash_floating_ips_associate'),
- url(FLOATING_IPS % 'disassociate', 'disassociate',
- name='dash_floating_ips_disassociate'),
-)
-
-urlpatterns += patterns('django_openstack.dash.views.snapshots',
- url(r'^(?P<tenant_id>[^/]+)/snapshots/$', 'index', name='dash_snapshots'),
- url(SNAPSHOTS % 'create', 'create', name='dash_snapshots_create'),
-)
-
-urlpatterns += patterns('django_openstack.dash.views.volumes',
- url(r'^(?P<tenant_id>[^/]+)/volumes/$', 'index', name='dash_volumes'),
- url(r'^(?P<tenant_id>[^/]+)/volumes/create', 'create',
- name='dash_volumes_create'),
- url(VOLUMES % 'attach', 'attach', name='dash_volumes_attach'),
- url(VOLUMES % 'detail', 'detail', name='dash_volumes_detail'),
-)
-
-# Swift containers and objects.
-urlpatterns += patterns('django_openstack.dash.views.containers',
- url(CONTAINERS % '', 'index', name='dash_containers'),
- url(CONTAINERS % 'create', 'create', name='dash_containers_create'),
-)
-
-urlpatterns += patterns('django_openstack.dash.views.objects',
- url(OBJECTS % '', 'index', name='dash_objects'),
- url(OBJECTS % 'upload', 'upload', name='dash_objects_upload'),
- url(OBJECTS % '(?P<object_name>[^/]+)/copy',
- 'copy', name='dash_object_copy'),
- url(OBJECTS % '(?P<object_name>[^/]+)/download',
- 'download', name='dash_objects_download'),
-)
-
-urlpatterns += patterns('django_openstack.dash.views.networks',
- url(r'^(?P<tenant_id>[^/]+)/networks/$', 'index', name='dash_networks'),
- url(NETWORKS % 'create', 'create', name='dash_network_create'),
- url(NETWORKS % '(?P<network_id>[^/]+)/detail', 'detail',
- name='dash_networks_detail'),
- url(NETWORKS % '(?P<network_id>[^/]+)/rename', 'rename',
- name='dash_network_rename'),
-)
-
-urlpatterns += patterns('django_openstack.dash.views.ports',
- url(PORTS % 'create', 'create', name='dash_ports_create'),
- url(PORTS % '(?P<port_id>[^/]+)/attach', 'attach',
- name='dash_ports_attach'),
-)
View
95 django-openstack/django_openstack/dash/views/containers.py
@@ -1,95 +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.
-
-"""
-Views for managing Swift containers.
-"""
-import logging
-
-from django import template
-from django.contrib import messages
-from django.contrib.auth.decorators import login_required
-from django import shortcuts
-from django.utils.translation import ugettext as _
-
-from django_openstack import api
-from django_openstack import forms
-
-from cloudfiles.errors import ContainerNotEmpty
-
-
-LOG = logging.getLogger('django_openstack.dash')
-
-
-class DeleteContainer(forms.SelfHandlingForm):
- container_name = forms.CharField(widget=forms.HiddenInput())
-
- def handle(self, request, data):
- try:
- api.swift_delete_container(request, data['container_name'])
- except ContainerNotEmpty, e:
- messages.error(request,
- _('Unable to delete non-empty container: %s') %
- data['container_name'])
- LOG.exception('Unable to delete container "%s". Exception: "%s"' %
- (data['container_name'], str(e)))
- else:
- messages.info(request,
- _('Successfully deleted container: %s') % \
- data['container_name'])
- return shortcuts.redirect(request.build_absolute_uri())
-
-
-class CreateContainer(forms.SelfHandlingForm):
- name = forms.CharField(max_length="255", label=_("Container Name"))
-
- def handle(self, request, data):
- api.swift_create_container(request, data['name'])
- messages.success(request, _("Container was successfully created."))
- return shortcuts.redirect("dash_containers", request.user.tenant_id)
-
-
-@login_required
-def index(request, tenant_id):
- marker = request.GET.get('marker', None)
-
- delete_form, handled = DeleteContainer.maybe_handle(request)
- if handled:
- return handled
-
- containers = api.swift_get_containers(request, marker=marker)
-
- return shortcuts.render_to_response(
- 'django_openstack/dash/containers/index.html', {
- 'containers': containers,
- 'delete_form': delete_form,
- }, context_instance=template.RequestContext(request))
-
-
-@login_required
-def create(request, tenant_id):
- form, handled = CreateContainer.maybe_handle(request)
- if handled:
- return handled
-
- return shortcuts.render_to_response(
- 'django_openstack/dash/containers/create.html', {
- 'create_form': form,
- }, context_instance=template.RequestContext(request))
View
252 django-openstack/django_openstack/dash/views/networks.py
@@ -1,252 +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.
-
-"""
-Views for managing api.quantum_api(request) networks.
-"""
-import logging
-
-from django import http
-from django import shortcuts
-from django import template
-from django.conf import settings
-from django.contrib import messages
-from django.contrib.auth.decorators import login_required
-from django.utils import simplejson
-from django.utils.translation import ugettext as _
-
-from django_openstack import forms
-from django_openstack import api
-
-from django_openstack.dash.views.ports import DeletePort
-from django_openstack.dash.views.ports import DetachPort
-from django_openstack.dash.views.ports import TogglePort
-
-import warnings
-
-
-LOG = logging.getLogger('django_openstack.dash.views.networks')
-
-
-class CreateNetwork(forms.SelfHandlingForm):
- name = forms.CharField(required=True, label=_("Network Name"))
-
- def handle(self, request, data):
- network_name = data['name']
-
- try:
- LOG.info('Creating network %s ' % network_name)
- send_data = {'network': {'name': '%s' % network_name}}
- api.quantum_create_network(request, send_data)
- except Exception, e:
- messages.error(request,
- _('Unable to create network %(network)s: %(msg)s') %
- {"network": network_name, "msg": e.message})
- return shortcuts.redirect(request.build_absolute_uri())
- else:
- msg = _('Network %s has been created.') % network_name
- LOG.info(msg)
- messages.success(request, msg)
- return shortcuts.redirect('dash_networks',
- tenant_id=request.user.tenant_id)
-
-
-class DeleteNetwork(forms.SelfHandlingForm):
- network = forms.CharField(widget=forms.HiddenInput())
-
- def handle(self, request, data):
- try:
- LOG.info('Deleting network %s ' % data['network'])
- api.quantum_delete_network(request, data['network'])
- except Exception, e:
- messages.error(request,
- _('Unable to delete network %(network)s: %(msg)s') %
- {"network": data['network'], "msg": e.message})
- else:
- msg = _('Network %s has been deleted.') % data['network']
- LOG.info(msg)
- messages.success(request, msg)
-
- return shortcuts.redirect(request.build_absolute_uri())
-
-
-class RenameNetwork(forms.SelfHandlingForm):
- network = forms.CharField(widget=forms.HiddenInput())
- new_name = forms.CharField(required=True)
-
- def handle(self, request, data):
- try:
- LOG.info('Renaming network %s to %s' %
- (data['network'], data['new_name']))
- send_data = {'network': {'name': '%s' % data['new_name']}}
- api.quantum_update_network(request, data['network'], send_data)
- except Exception, e:
- messages.error(request,
- _('Unable to rename network %(network)s: %(msg)s') %
- {"network": data['network'], "msg": e.message})
- else:
- msg = _('Network %(net)s has been renamed to %(new_name)s.') % {
- "net": data['network'], "new_name": data['new_name']}
- LOG.info(msg)
- messages.success(request, msg)
-
- return shortcuts.redirect(request.build_absolute_uri())
-
-
-@login_required
-def index(request, tenant_id):
- delete_form, delete_handled = DeleteNetwork.maybe_handle(request)
-
- networks = []
- instances = []
-
- try:
- networks_list = api.quantum_list_networks(request)
- details = []
- for network in networks_list['networks']:
- net_stats = _calc_network_stats(request, tenant_id, network['id'])
- # Get network details like name and id
- details = api.quantum_network_details(request, network['id'])
- networks.append({
- 'name': details['network']['name'],
- 'id': network['id'],
- 'total': net_stats['total'],
- 'available': net_stats['available'],
- 'used': net_stats['used'],
- 'tenant': tenant_id
- })
-
- except Exception, e:
- messages.error(request,
- _('Unable to get network list: %s') % e.message)
-
- return shortcuts.render_to_response(
- 'django_openstack/dash/networks/index.html', {
- 'networks': networks,
- 'delete_form': delete_form,
- }, context_instance=template.RequestContext(request))
-
-
-@login_required
-def create(request, tenant_id):
- network_form, handled = CreateNetwork.maybe_handle(request)
- if handled:
- return shortcuts.redirect('dash_networks', request.user.tenant_id)
-
- return shortcuts.render_to_response(
- 'django_openstack/dash/networks/create.html', {
- 'network_form': network_form
- }, context_instance=template.RequestContext(request))
-
-
-@login_required
-def detail(request, tenant_id, network_id):
- delete_port_form, delete_handled = DeletePort.maybe_handle(request)
- detach_port_form, detach_handled = DetachPort.maybe_handle(request)
- toggle_port_form, port_toggle_handled = TogglePort.maybe_handle(request)
-
- network = {}
-
- try:
- network_details = api.quantum_network_details(request, network_id)
- network['name'] = network_details['network']['name']
- network['id'] = network_id
- network['ports'] = _get_port_states(request, tenant_id, network_id)
- except Exception, e:
- messages.error(request,
- _('Unable to get network details: %s') % e.message)
-
- return shortcuts.render_to_response(
- 'django_openstack/dash/networks/detail.html', {
- 'network': network,
- 'tenant': tenant_id,
- 'delete_port_form': delete_port_form,
- 'detach_port_form': detach_port_form,
- 'toggle_port_form': toggle_port_form
- }, context_instance=template.RequestContext(request))
-
-
-@login_required
-def rename(request, tenant_id, network_id):
- rename_form, handled = RenameNetwork.maybe_handle(request)
- network_details = api.quantum_network_details(request, network_id)
-
- if handled:
- return shortcuts.redirect('dash_networks', request.user.tenant_id)
-
- return shortcuts.render_to_response(
- 'django_openstack/dash/networks/rename.html', {
- 'network': network_details,
- 'rename_form': rename_form
- }, context_instance=template.RequestContext(request))
-
-
-def _get_port_states(request, tenant_id, network_id):
- """
- Helper method to find port states for a network
- """
- network_ports = []
- # Get all vifs for comparison with port attachments
- vifs = api.get_vif_ids(request)
-
- # Get all ports on this network
- ports = api.quantum_list_ports(request, network_id)
- for port in ports['ports']:
- port_details = api.quantum_port_details(request,
- network_id, port['id'])
- # Get port attachments
- port_attachment = api.quantum_port_attachment(request,
- network_id, port['id'])
- # Find instance the attachment belongs to
- connected_instance = None
- if port_attachment['attachment']:
- for vif in vifs:
- if str(vif['id']) == str(port_attachment['attachment']['id']):
- connected_instance = vif['instance_name']
- break
- network_ports.append({
- 'id': port_details['port']['id'],
- 'state': port_details['port']['state'],
- 'attachment': port_attachment['attachment'],
- 'instance': connected_instance
- })
- return network_ports
-
-
-def _calc_network_stats(request, tenant_id, network_id):
- """
- Helper method to calculate statistics for a network
- """
- # Get all ports statistics for the network
- total = 0
- available = 0
- used = 0
- ports = api.quantum_list_ports(request, network_id)
- for port in ports['ports']:
- total += 1
- # Get port attachment
- port_attachment = api.quantum_port_attachment(request,
- network_id, port['id'])
- if port_attachment['attachment']:
- used += 1
- else:
- available += 1
-
- return {'total': total, 'used': used, 'available': available}
View
42 django-openstack/django_openstack/decorators.py
@@ -1,42 +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 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.
-
-"""
-Simple decorator container for general purpose
-"""
-
-from django.shortcuts import redirect
-import logging
-
-
-LOG = logging.getLogger('django_openstack.syspanel')
-
-
-def enforce_admin_access(fn):
- """ Preserve unauthorized bypass typing directly the URL and redirects to
- the overview dash page """
- def dec(*args, **kwargs):
- if args[0].user.is_admin():
- return fn(*args, **kwargs)
- else:
- LOG.warn('Redirecting user "%s" from syspanel to dash ( %s )' %
- (args[0].user.username, fn.__name__))
- return redirect('dash_overview')
- return dec
View
8 django-openstack/django_openstack/exceptions.py
@@ -1,8 +0,0 @@
-""" Standardized exception classes for the OpenStack Dashboard. """
-
-from novaclient import exceptions as nova_exceptions
-
-
-class Unauthorized(nova_exceptions.Unauthorized):
- """ A wrapper around novaclient's Unauthorized exception. """
- pass
View
1,948 django-openstack/django_openstack/locale/es/LC_MESSAGES/django.po
@@ -1,1948 +0,0 @@
-# Translations of Dashboard for OpenStack User Interface.
-# Copyright 2011 Midokura KK
-# This file is distributed under the same license as the Dashboard for OpenStack.
-# FIRST AUTHOR Jeffrey Wilcox, 2011.
-#
-#, fuzzy
-msgid ""
-msgstr ""
-"Project-Id-Version: openstack-dashboard\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2011-10-27 14:03+0900\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"
-
-#: api.py:1002 syspanel/views/services.py:88
-#, python-format
-msgid "Unable to get service info: %s"
-msgstr ""
-
-#: api.py:1028 dash/views/instances.py:180 syspanel/views/flavors.py:95
-#: syspanel/views/instances.py:146
-#, python-format
-msgid "Unable to get usage info: %s"
-msgstr ""
-
-#: context_processors.py:34
-#, python-format
-msgid ""
-"Unable to retrieve tenant list from "
-"keystone: %s"
-msgstr ""
-
-#: forms.py:180
-#, python-format
-msgid "Unexpected error: %s"
-msgstr ""
-
-#: auth/views.py:38
-msgid "User Name"
-msgstr ""
-
-#: auth/views.py:39 syspanel/views/users.py:55 syspanel/views/users.py:73
-msgid "Password"
-msgstr ""
-
-#: auth/views.py:83
-#, python-format
-msgid "No tenants present for user: %(user)s"
-msgstr ""
-
-#: auth/views.py:105
-#, python-format
-msgid "Error authenticating: %s"
-msgstr ""
-
-#: auth/views.py:110
-#, python-format
-msgid "Error authenticating with keystone: %s"
-msgstr ""
-
-#: dash/views/containers.py:49
-#, python-format
-msgid "Unable to delete non-empty container: %s"
-msgstr ""
-
-#: dash/views/containers.py:55
-#, python-format
-msgid "Successfully deleted container: %s"
-msgstr ""
-
-#: dash/views/containers.py:61
-msgid "Container Name"
-msgstr ""
-
-#: dash/views/containers.py:65
-msgid "Container was successfully created."
-msgstr ""
-
-#: dash/views/floating_ips.py:47
-#, python-format
-msgid "Successfully released Floating IP: %s"
-msgstr ""
-
-#: dash/views/floating_ips.py:51
-#, python-format
-msgid "Error releasing Floating IP from tenant: %s"
-msgstr ""
-
-#: dash/views/floating_ips.py:67
-#: templates/django_openstack/dash/networks/_detail.html:19
-msgid "Instance"
-msgstr ""
-
-#: dash/views/floating_ips.py:76
-#, python-format
-msgid ""
-"Successfully associated Floating IP: "
-"%(ip)s with Instance: %(inst)s"
-msgstr ""
-
-#: dash/views/floating_ips.py:82
-#, python-format
-msgid "Error associating Floating IP: %s"
-msgstr ""
-
-#: dash/views/floating_ips.py:99
-#, python-format
-msgid "Successfully disassociated Floating IP: %s"
-msgstr ""
-
-#: dash/views/floating_ips.py:103
-#, python-format
-msgid "Error disassociating Floating IP: %s"