Merge lp:~devcamcar/django-nova/move-django-nova into lp:django-nova
- move-django-nova
- Merge into trunk
Proposed by
Devin Carlen
Status: | Merged |
---|---|
Approved by: | Devin Carlen |
Approved revision: | 20 |
Merged at revision: | 20 |
Proposed branch: | lp:~devcamcar/django-nova/move-django-nova |
Merge into: | lp:django-nova |
Diff against target: |
7292 lines (+5/-6810) 88 files modified
LICENSE (+0/-176) README (+5/-41) bootstrap.py (+0/-260) buildout.cfg (+0/-19) setup.py (+0/-29) src/django_nova/adminclient.py (+0/-498) src/django_nova/connection.py (+0/-38) src/django_nova/exceptions.py (+0/-95) src/django_nova/forms.py (+0/-262) src/django_nova/management/commands/createnovausers.py (+0/-37) src/django_nova/manager.py (+0/-340) src/django_nova/models.py (+0/-121) src/django_nova/shortcuts.py (+0/-131) src/django_nova/templates/admin/django_nova/project/add_project.html (+0/-45) src/django_nova/templates/admin/django_nova/project/add_project_user.html (+0/-69) src/django_nova/templates/admin/django_nova/project/base_projects.html (+0/-16) src/django_nova/templates/admin/django_nova/project/change_list.html (+0/-3) src/django_nova/templates/admin/django_nova/project/delete_project.html (+0/-25) src/django_nova/templates/admin/django_nova/project/delete_project_user.html (+0/-25) src/django_nova/templates/admin/django_nova/project/edit_project.html (+0/-95) src/django_nova/templates/admin/django_nova/project/global_edit_user.html (+0/-71) src/django_nova/templates/admin/django_nova/project/project_list.html (+0/-42) src/django_nova/templates/admin/django_nova/project/project_user.html (+0/-76) src/django_nova/templates/admin/django_nova/project/send_credentials.html (+0/-87) src/django_nova/templates/admin/django_nova/project/user_list.html (+0/-39) src/django_nova/templates/django_nova/_messages.html (+0/-41) src/django_nova/templates/django_nova/base.html (+0/-85) src/django_nova/templates/django_nova/credentials/expired.html (+0/-17) src/django_nova/templates/django_nova/images/_launch_form.html (+0/-7) src/django_nova/templates/django_nova/images/_list.html (+0/-112) src/django_nova/templates/django_nova/images/base.html (+0/-7) src/django_nova/templates/django_nova/images/detail_list.html (+0/-207) src/django_nova/templates/django_nova/images/edit.html (+0/-35) src/django_nova/templates/django_nova/images/index.html (+0/-70) src/django_nova/templates/django_nova/images/launch.html (+0/-32) src/django_nova/templates/django_nova/instances/_instances_list.html (+0/-104) src/django_nova/templates/django_nova/instances/base.html (+0/-7) src/django_nova/templates/django_nova/instances/detail_list.html (+0/-33) src/django_nova/templates/django_nova/instances/edit.html (+0/-34) src/django_nova/templates/django_nova/instances/index.html (+0/-98) src/django_nova/templates/django_nova/instances/performance.html (+0/-58) src/django_nova/templates/django_nova/keypairs/_create_form.html (+0/-5) src/django_nova/templates/django_nova/keypairs/_list.html (+0/-31) src/django_nova/templates/django_nova/keypairs/base.html (+0/-7) src/django_nova/templates/django_nova/keypairs/index.html (+0/-77) src/django_nova/templates/django_nova/projects/edit_user.html (+0/-72) src/django_nova/templates/django_nova/projects/index.html (+0/-26) src/django_nova/templates/django_nova/projects/manage.html (+0/-45) src/django_nova/templates/django_nova/securitygroups/_authorize_form.html (+0/-5) src/django_nova/templates/django_nova/securitygroups/_create_form.html (+0/-5) src/django_nova/templates/django_nova/securitygroups/_revoke_form.html (+0/-3) src/django_nova/templates/django_nova/securitygroups/base.html (+0/-7) src/django_nova/templates/django_nova/securitygroups/detail.html (+0/-62) src/django_nova/templates/django_nova/securitygroups/index.html (+0/-59) src/django_nova/templates/django_nova/volumes/_attach_form.html (+0/-5) src/django_nova/templates/django_nova/volumes/_create_form.html (+0/-5) src/django_nova/templates/django_nova/volumes/base.html (+0/-7) src/django_nova/templates/django_nova/volumes/index.html (+0/-84) src/django_nova/templatetags/admin_extras.py (+0/-50) src/django_nova/templatetags/django_nova_tags.py (+0/-37) src/django_nova/templatetags/project_tags.py (+0/-39) src/django_nova/templatetags/region_tags.py (+0/-40) src/django_nova/templatetags/sidebar_tags.py (+0/-46) src/django_nova/templatetags/truncate_filter.py (+0/-31) src/django_nova/tests/__init__.py (+0/-1) src/django_nova/tests/urls.py (+0/-36) src/django_nova/tests/view_tests/__init__.py (+0/-7) src/django_nova/tests/view_tests/base.py (+0/-90) src/django_nova/tests/view_tests/credential_tests.py (+0/-70) src/django_nova/tests/view_tests/image_tests.py (+0/-232) src/django_nova/tests/view_tests/instance_tests.py (+0/-67) src/django_nova/tests/view_tests/keypair_tests.py (+0/-93) src/django_nova/tests/view_tests/region_tests.py (+0/-43) src/django_nova/tests/view_tests/volume_tests.py (+0/-170) src/django_nova/testsettings.py (+0/-21) src/django_nova/urls/admin_project.py (+0/-55) src/django_nova/urls/admin_roles.py (+0/-32) src/django_nova/urls/project.py (+0/-129) src/django_nova/urls/region.py (+0/-29) src/django_nova/views/admin.py (+0/-326) src/django_nova/views/credentials.py (+0/-46) src/django_nova/views/images.py (+0/-229) src/django_nova/views/instances.py (+0/-203) src/django_nova/views/keypairs.py (+0/-122) src/django_nova/views/projects.py (+0/-107) src/django_nova/views/regions.py (+0/-36) src/django_nova/views/securitygroups.py (+0/-180) src/django_nova/views/volumes.py (+0/-151) |
To merge this branch: | bzr merge lp:~devcamcar/django-nova/move-django-nova |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Devin Carlen | Pending | ||
Review via email: mp+52312@code.launchpad.net |
Commit message
Description of the change
The Django-Nova repository is decommissioned. It is now part of the OpenStack Dashboard repository located at:
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === removed file 'LICENSE' | |||
2 | --- LICENSE 2011-01-12 20:02:06 +0000 | |||
3 | +++ LICENSE 1970-01-01 00:00:00 +0000 | |||
4 | @@ -1,176 +0,0 @@ | |||
5 | 1 | |||
6 | 2 | Apache License | ||
7 | 3 | Version 2.0, January 2004 | ||
8 | 4 | http://www.apache.org/licenses/ | ||
9 | 5 | |||
10 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION | ||
11 | 7 | |||
12 | 8 | 1. Definitions. | ||
13 | 9 | |||
14 | 10 | "License" shall mean the terms and conditions for use, reproduction, | ||
15 | 11 | and distribution as defined by Sections 1 through 9 of this document. | ||
16 | 12 | |||
17 | 13 | "Licensor" shall mean the copyright owner or entity authorized by | ||
18 | 14 | the copyright owner that is granting the License. | ||
19 | 15 | |||
20 | 16 | "Legal Entity" shall mean the union of the acting entity and all | ||
21 | 17 | other entities that control, are controlled by, or are under common | ||
22 | 18 | control with that entity. For the purposes of this definition, | ||
23 | 19 | "control" means (i) the power, direct or indirect, to cause the | ||
24 | 20 | direction or management of such entity, whether by contract or | ||
25 | 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the | ||
26 | 22 | outstanding shares, or (iii) beneficial ownership of such entity. | ||
27 | 23 | |||
28 | 24 | "You" (or "Your") shall mean an individual or Legal Entity | ||
29 | 25 | exercising permissions granted by this License. | ||
30 | 26 | |||
31 | 27 | "Source" form shall mean the preferred form for making modifications, | ||
32 | 28 | including but not limited to software source code, documentation | ||
33 | 29 | source, and configuration files. | ||
34 | 30 | |||
35 | 31 | "Object" form shall mean any form resulting from mechanical | ||
36 | 32 | transformation or translation of a Source form, including but | ||
37 | 33 | not limited to compiled object code, generated documentation, | ||
38 | 34 | and conversions to other media types. | ||
39 | 35 | |||
40 | 36 | "Work" shall mean the work of authorship, whether in Source or | ||
41 | 37 | Object form, made available under the License, as indicated by a | ||
42 | 38 | copyright notice that is included in or attached to the work | ||
43 | 39 | (an example is provided in the Appendix below). | ||
44 | 40 | |||
45 | 41 | "Derivative Works" shall mean any work, whether in Source or Object | ||
46 | 42 | form, that is based on (or derived from) the Work and for which the | ||
47 | 43 | editorial revisions, annotations, elaborations, or other modifications | ||
48 | 44 | represent, as a whole, an original work of authorship. For the purposes | ||
49 | 45 | of this License, Derivative Works shall not include works that remain | ||
50 | 46 | separable from, or merely link (or bind by name) to the interfaces of, | ||
51 | 47 | the Work and Derivative Works thereof. | ||
52 | 48 | |||
53 | 49 | "Contribution" shall mean any work of authorship, including | ||
54 | 50 | the original version of the Work and any modifications or additions | ||
55 | 51 | to that Work or Derivative Works thereof, that is intentionally | ||
56 | 52 | submitted to Licensor for inclusion in the Work by the copyright owner | ||
57 | 53 | or by an individual or Legal Entity authorized to submit on behalf of | ||
58 | 54 | the copyright owner. For the purposes of this definition, "submitted" | ||
59 | 55 | means any form of electronic, verbal, or written communication sent | ||
60 | 56 | to the Licensor or its representatives, including but not limited to | ||
61 | 57 | communication on electronic mailing lists, source code control systems, | ||
62 | 58 | and issue tracking systems that are managed by, or on behalf of, the | ||
63 | 59 | Licensor for the purpose of discussing and improving the Work, but | ||
64 | 60 | excluding communication that is conspicuously marked or otherwise | ||
65 | 61 | designated in writing by the copyright owner as "Not a Contribution." | ||
66 | 62 | |||
67 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity | ||
68 | 64 | on behalf of whom a Contribution has been received by Licensor and | ||
69 | 65 | subsequently incorporated within the Work. | ||
70 | 66 | |||
71 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of | ||
72 | 68 | this License, each Contributor hereby grants to You a perpetual, | ||
73 | 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable | ||
74 | 70 | copyright license to reproduce, prepare Derivative Works of, | ||
75 | 71 | publicly display, publicly perform, sublicense, and distribute the | ||
76 | 72 | Work and such Derivative Works in Source or Object form. | ||
77 | 73 | |||
78 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of | ||
79 | 75 | this License, each Contributor hereby grants to You a perpetual, | ||
80 | 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable | ||
81 | 77 | (except as stated in this section) patent license to make, have made, | ||
82 | 78 | use, offer to sell, sell, import, and otherwise transfer the Work, | ||
83 | 79 | where such license applies only to those patent claims licensable | ||
84 | 80 | by such Contributor that are necessarily infringed by their | ||
85 | 81 | Contribution(s) alone or by combination of their Contribution(s) | ||
86 | 82 | with the Work to which such Contribution(s) was submitted. If You | ||
87 | 83 | institute patent litigation against any entity (including a | ||
88 | 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work | ||
89 | 85 | or a Contribution incorporated within the Work constitutes direct | ||
90 | 86 | or contributory patent infringement, then any patent licenses | ||
91 | 87 | granted to You under this License for that Work shall terminate | ||
92 | 88 | as of the date such litigation is filed. | ||
93 | 89 | |||
94 | 90 | 4. Redistribution. You may reproduce and distribute copies of the | ||
95 | 91 | Work or Derivative Works thereof in any medium, with or without | ||
96 | 92 | modifications, and in Source or Object form, provided that You | ||
97 | 93 | meet the following conditions: | ||
98 | 94 | |||
99 | 95 | (a) You must give any other recipients of the Work or | ||
100 | 96 | Derivative Works a copy of this License; and | ||
101 | 97 | |||
102 | 98 | (b) You must cause any modified files to carry prominent notices | ||
103 | 99 | stating that You changed the files; and | ||
104 | 100 | |||
105 | 101 | (c) You must retain, in the Source form of any Derivative Works | ||
106 | 102 | that You distribute, all copyright, patent, trademark, and | ||
107 | 103 | attribution notices from the Source form of the Work, | ||
108 | 104 | excluding those notices that do not pertain to any part of | ||
109 | 105 | the Derivative Works; and | ||
110 | 106 | |||
111 | 107 | (d) If the Work includes a "NOTICE" text file as part of its | ||
112 | 108 | distribution, then any Derivative Works that You distribute must | ||
113 | 109 | include a readable copy of the attribution notices contained | ||
114 | 110 | within such NOTICE file, excluding those notices that do not | ||
115 | 111 | pertain to any part of the Derivative Works, in at least one | ||
116 | 112 | of the following places: within a NOTICE text file distributed | ||
117 | 113 | as part of the Derivative Works; within the Source form or | ||
118 | 114 | documentation, if provided along with the Derivative Works; or, | ||
119 | 115 | within a display generated by the Derivative Works, if and | ||
120 | 116 | wherever such third-party notices normally appear. The contents | ||
121 | 117 | of the NOTICE file are for informational purposes only and | ||
122 | 118 | do not modify the License. You may add Your own attribution | ||
123 | 119 | notices within Derivative Works that You distribute, alongside | ||
124 | 120 | or as an addendum to the NOTICE text from the Work, provided | ||
125 | 121 | that such additional attribution notices cannot be construed | ||
126 | 122 | as modifying the License. | ||
127 | 123 | |||
128 | 124 | You may add Your own copyright statement to Your modifications and | ||
129 | 125 | may provide additional or different license terms and conditions | ||
130 | 126 | for use, reproduction, or distribution of Your modifications, or | ||
131 | 127 | for any such Derivative Works as a whole, provided Your use, | ||
132 | 128 | reproduction, and distribution of the Work otherwise complies with | ||
133 | 129 | the conditions stated in this License. | ||
134 | 130 | |||
135 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, | ||
136 | 132 | any Contribution intentionally submitted for inclusion in the Work | ||
137 | 133 | by You to the Licensor shall be under the terms and conditions of | ||
138 | 134 | this License, without any additional terms or conditions. | ||
139 | 135 | Notwithstanding the above, nothing herein shall supersede or modify | ||
140 | 136 | the terms of any separate license agreement you may have executed | ||
141 | 137 | with Licensor regarding such Contributions. | ||
142 | 138 | |||
143 | 139 | 6. Trademarks. This License does not grant permission to use the trade | ||
144 | 140 | names, trademarks, service marks, or product names of the Licensor, | ||
145 | 141 | except as required for reasonable and customary use in describing the | ||
146 | 142 | origin of the Work and reproducing the content of the NOTICE file. | ||
147 | 143 | |||
148 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or | ||
149 | 145 | agreed to in writing, Licensor provides the Work (and each | ||
150 | 146 | Contributor provides its Contributions) on an "AS IS" BASIS, | ||
151 | 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | ||
152 | 148 | implied, including, without limitation, any warranties or conditions | ||
153 | 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A | ||
154 | 150 | PARTICULAR PURPOSE. You are solely responsible for determining the | ||
155 | 151 | appropriateness of using or redistributing the Work and assume any | ||
156 | 152 | risks associated with Your exercise of permissions under this License. | ||
157 | 153 | |||
158 | 154 | 8. Limitation of Liability. In no event and under no legal theory, | ||
159 | 155 | whether in tort (including negligence), contract, or otherwise, | ||
160 | 156 | unless required by applicable law (such as deliberate and grossly | ||
161 | 157 | negligent acts) or agreed to in writing, shall any Contributor be | ||
162 | 158 | liable to You for damages, including any direct, indirect, special, | ||
163 | 159 | incidental, or consequential damages of any character arising as a | ||
164 | 160 | result of this License or out of the use or inability to use the | ||
165 | 161 | Work (including but not limited to damages for loss of goodwill, | ||
166 | 162 | work stoppage, computer failure or malfunction, or any and all | ||
167 | 163 | other commercial damages or losses), even if such Contributor | ||
168 | 164 | has been advised of the possibility of such damages. | ||
169 | 165 | |||
170 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing | ||
171 | 167 | the Work or Derivative Works thereof, You may choose to offer, | ||
172 | 168 | and charge a fee for, acceptance of support, warranty, indemnity, | ||
173 | 169 | or other liability obligations and/or rights consistent with this | ||
174 | 170 | License. However, in accepting such obligations, You may act only | ||
175 | 171 | on Your own behalf and on Your sole responsibility, not on behalf | ||
176 | 172 | of any other Contributor, and only if You agree to indemnify, | ||
177 | 173 | defend, and hold each Contributor harmless for any liability | ||
178 | 174 | incurred by, or claims asserted against, such Contributor by reason | ||
179 | 175 | of your accepting any such warranty or additional liability. | ||
180 | 176 | |||
181 | 177 | 0 | ||
182 | === modified file 'README' | |||
183 | --- README 2011-01-12 22:23:24 +0000 | |||
184 | +++ README 2011-03-05 22:32:56 +0000 | |||
185 | @@ -1,42 +1,6 @@ | |||
227 | 1 | OpenStack Django-Nova | 1 | Django-Nova has been moved into the OpenStack Dashboard repository. |
228 | 2 | --------------------- | 2 | |
229 | 3 | 3 | It's new home is at: | |
230 | 4 | The Django-Nova project is a Django module that is used to provide web based | 4 | |
231 | 5 | interactions with the OpenStack Nova cloud controller. | 5 | http://launchpad.net/openstack-dashboard |
191 | 6 | |||
192 | 7 | There is a reference implementation that uses this module located at: | ||
193 | 8 | |||
194 | 9 | http://launchpad.net/openstack-dashboard | ||
195 | 10 | |||
196 | 11 | It is highly recommended that you make use of this reference implementation | ||
197 | 12 | so that changes you make can be visualized effectively and are consistent. | ||
198 | 13 | Using this reference implementation as a development environment will greatly | ||
199 | 14 | simplify development of the django-nova module. | ||
200 | 15 | |||
201 | 16 | Of course, if you are developing your own Django site using django-nova, then | ||
202 | 17 | you can disregard this advice. | ||
203 | 18 | |||
204 | 19 | |||
205 | 20 | |||
206 | 21 | Getting Started | ||
207 | 22 | --------------- | ||
208 | 23 | |||
209 | 24 | Django-Nova uses Buildout (http://www.buildout.org/) to manage local | ||
210 | 25 | development. To configure your local Buildout environment: | ||
211 | 26 | |||
212 | 27 | $ python bootstrap.py | ||
213 | 28 | $ bin/buildout | ||
214 | 29 | |||
215 | 30 | This will install all the dependencies of django-nova and provide some useful | ||
216 | 31 | scripts in the bin/ directory: | ||
217 | 32 | |||
218 | 33 | bin/python provides a python shell for the current buildout. | ||
219 | 34 | bin/django provides django functions for the current buildout. | ||
220 | 35 | |||
221 | 36 | |||
222 | 37 | You should now be able to run unit tests as follows: | ||
223 | 38 | |||
224 | 39 | $ bin/django test | ||
225 | 40 | |||
226 | 41 | |||
232 | 42 | 6 | ||
233 | 43 | 7 | ||
234 | === removed file 'bootstrap.py' | |||
235 | --- bootstrap.py 2011-01-12 20:02:06 +0000 | |||
236 | +++ bootstrap.py 1970-01-01 00:00:00 +0000 | |||
237 | @@ -1,260 +0,0 @@ | |||
238 | 1 | ############################################################################## | ||
239 | 2 | # | ||
240 | 3 | # Copyright (c) 2006 Zope Foundation and Contributors. | ||
241 | 4 | # All Rights Reserved. | ||
242 | 5 | # | ||
243 | 6 | # This software is subject to the provisions of the Zope Public License, | ||
244 | 7 | # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. | ||
245 | 8 | # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED | ||
246 | 9 | # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
247 | 10 | # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS | ||
248 | 11 | # FOR A PARTICULAR PURPOSE. | ||
249 | 12 | # | ||
250 | 13 | ############################################################################## | ||
251 | 14 | """Bootstrap a buildout-based project | ||
252 | 15 | |||
253 | 16 | Simply run this script in a directory containing a buildout.cfg. | ||
254 | 17 | The script accepts buildout command-line options, so you can | ||
255 | 18 | use the -c option to specify an alternate configuration file. | ||
256 | 19 | """ | ||
257 | 20 | |||
258 | 21 | import os, shutil, sys, tempfile, textwrap, urllib, urllib2, subprocess | ||
259 | 22 | from optparse import OptionParser | ||
260 | 23 | |||
261 | 24 | if sys.platform == 'win32': | ||
262 | 25 | def quote(c): | ||
263 | 26 | if ' ' in c: | ||
264 | 27 | return '"%s"' % c # work around spawn lamosity on windows | ||
265 | 28 | else: | ||
266 | 29 | return c | ||
267 | 30 | else: | ||
268 | 31 | quote = str | ||
269 | 32 | |||
270 | 33 | # See zc.buildout.easy_install._has_broken_dash_S for motivation and comments. | ||
271 | 34 | stdout, stderr = subprocess.Popen( | ||
272 | 35 | [sys.executable, '-Sc', | ||
273 | 36 | 'try:\n' | ||
274 | 37 | ' import ConfigParser\n' | ||
275 | 38 | 'except ImportError:\n' | ||
276 | 39 | ' print 1\n' | ||
277 | 40 | 'else:\n' | ||
278 | 41 | ' print 0\n'], | ||
279 | 42 | stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate() | ||
280 | 43 | has_broken_dash_S = bool(int(stdout.strip())) | ||
281 | 44 | |||
282 | 45 | # In order to be more robust in the face of system Pythons, we want to | ||
283 | 46 | # run without site-packages loaded. This is somewhat tricky, in | ||
284 | 47 | # particular because Python 2.6's distutils imports site, so starting | ||
285 | 48 | # with the -S flag is not sufficient. However, we'll start with that: | ||
286 | 49 | if not has_broken_dash_S and 'site' in sys.modules: | ||
287 | 50 | # We will restart with python -S. | ||
288 | 51 | args = sys.argv[:] | ||
289 | 52 | args[0:0] = [sys.executable, '-S'] | ||
290 | 53 | args = map(quote, args) | ||
291 | 54 | os.execv(sys.executable, args) | ||
292 | 55 | # Now we are running with -S. We'll get the clean sys.path, import site | ||
293 | 56 | # because distutils will do it later, and then reset the path and clean | ||
294 | 57 | # out any namespace packages from site-packages that might have been | ||
295 | 58 | # loaded by .pth files. | ||
296 | 59 | clean_path = sys.path[:] | ||
297 | 60 | import site | ||
298 | 61 | sys.path[:] = clean_path | ||
299 | 62 | for k, v in sys.modules.items(): | ||
300 | 63 | if k in ('setuptools', 'pkg_resources') or ( | ||
301 | 64 | hasattr(v, '__path__') and | ||
302 | 65 | len(v.__path__)==1 and | ||
303 | 66 | not os.path.exists(os.path.join(v.__path__[0],'__init__.py'))): | ||
304 | 67 | # This is a namespace package. Remove it. | ||
305 | 68 | sys.modules.pop(k) | ||
306 | 69 | |||
307 | 70 | is_jython = sys.platform.startswith('java') | ||
308 | 71 | |||
309 | 72 | setuptools_source = 'http://peak.telecommunity.com/dist/ez_setup.py' | ||
310 | 73 | distribute_source = 'http://python-distribute.org/distribute_setup.py' | ||
311 | 74 | |||
312 | 75 | # parsing arguments | ||
313 | 76 | def normalize_to_url(option, opt_str, value, parser): | ||
314 | 77 | if value: | ||
315 | 78 | if '://' not in value: # It doesn't smell like a URL. | ||
316 | 79 | value = 'file://%s' % ( | ||
317 | 80 | urllib.pathname2url( | ||
318 | 81 | os.path.abspath(os.path.expanduser(value))),) | ||
319 | 82 | if opt_str == '--download-base' and not value.endswith('/'): | ||
320 | 83 | # Download base needs a trailing slash to make the world happy. | ||
321 | 84 | value += '/' | ||
322 | 85 | else: | ||
323 | 86 | value = None | ||
324 | 87 | name = opt_str[2:].replace('-', '_') | ||
325 | 88 | setattr(parser.values, name, value) | ||
326 | 89 | |||
327 | 90 | usage = '''\ | ||
328 | 91 | [DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options] | ||
329 | 92 | |||
330 | 93 | Bootstraps a buildout-based project. | ||
331 | 94 | |||
332 | 95 | Simply run this script in a directory containing a buildout.cfg, using the | ||
333 | 96 | Python that you want bin/buildout to use. | ||
334 | 97 | |||
335 | 98 | Note that by using --setup-source and --download-base to point to | ||
336 | 99 | local resources, you can keep this script from going over the network. | ||
337 | 100 | ''' | ||
338 | 101 | |||
339 | 102 | parser = OptionParser(usage=usage) | ||
340 | 103 | parser.add_option("-v", "--version", dest="version", | ||
341 | 104 | help="use a specific zc.buildout version") | ||
342 | 105 | parser.add_option("-d", "--distribute", | ||
343 | 106 | action="store_true", dest="use_distribute", default=False, | ||
344 | 107 | help="Use Distribute rather than Setuptools.") | ||
345 | 108 | parser.add_option("--setup-source", action="callback", dest="setup_source", | ||
346 | 109 | callback=normalize_to_url, nargs=1, type="string", | ||
347 | 110 | help=("Specify a URL or file location for the setup file. " | ||
348 | 111 | "If you use Setuptools, this will default to " + | ||
349 | 112 | setuptools_source + "; if you use Distribute, this " | ||
350 | 113 | "will default to " + distribute_source +".")) | ||
351 | 114 | parser.add_option("--download-base", action="callback", dest="download_base", | ||
352 | 115 | callback=normalize_to_url, nargs=1, type="string", | ||
353 | 116 | help=("Specify a URL or directory for downloading " | ||
354 | 117 | "zc.buildout and either Setuptools or Distribute. " | ||
355 | 118 | "Defaults to PyPI.")) | ||
356 | 119 | parser.add_option("--eggs", | ||
357 | 120 | help=("Specify a directory for storing eggs. Defaults to " | ||
358 | 121 | "a temporary directory that is deleted when the " | ||
359 | 122 | "bootstrap script completes.")) | ||
360 | 123 | parser.add_option("-t", "--accept-buildout-test-releases", | ||
361 | 124 | dest='accept_buildout_test_releases', | ||
362 | 125 | action="store_true", default=False, | ||
363 | 126 | help=("Normally, if you do not specify a --version, the " | ||
364 | 127 | "bootstrap script and buildout gets the newest " | ||
365 | 128 | "*final* versions of zc.buildout and its recipes and " | ||
366 | 129 | "extensions for you. If you use this flag, " | ||
367 | 130 | "bootstrap and buildout will get the newest releases " | ||
368 | 131 | "even if they are alphas or betas.")) | ||
369 | 132 | parser.add_option("-c", None, action="store", dest="config_file", | ||
370 | 133 | help=("Specify the path to the buildout configuration " | ||
371 | 134 | "file to be used.")) | ||
372 | 135 | |||
373 | 136 | options, args = parser.parse_args() | ||
374 | 137 | |||
375 | 138 | # if -c was provided, we push it back into args for buildout's main function | ||
376 | 139 | if options.config_file is not None: | ||
377 | 140 | args += ['-c', options.config_file] | ||
378 | 141 | |||
379 | 142 | if options.eggs: | ||
380 | 143 | eggs_dir = os.path.abspath(os.path.expanduser(options.eggs)) | ||
381 | 144 | else: | ||
382 | 145 | eggs_dir = tempfile.mkdtemp() | ||
383 | 146 | |||
384 | 147 | if options.setup_source is None: | ||
385 | 148 | if options.use_distribute: | ||
386 | 149 | options.setup_source = distribute_source | ||
387 | 150 | else: | ||
388 | 151 | options.setup_source = setuptools_source | ||
389 | 152 | |||
390 | 153 | if options.accept_buildout_test_releases: | ||
391 | 154 | args.append('buildout:accept-buildout-test-releases=true') | ||
392 | 155 | args.append('bootstrap') | ||
393 | 156 | |||
394 | 157 | try: | ||
395 | 158 | import pkg_resources | ||
396 | 159 | import setuptools # A flag. Sometimes pkg_resources is installed alone. | ||
397 | 160 | if not hasattr(pkg_resources, '_distribute'): | ||
398 | 161 | raise ImportError | ||
399 | 162 | except ImportError: | ||
400 | 163 | ez_code = urllib2.urlopen( | ||
401 | 164 | options.setup_source).read().replace('\r\n', '\n') | ||
402 | 165 | ez = {} | ||
403 | 166 | exec ez_code in ez | ||
404 | 167 | setup_args = dict(to_dir=eggs_dir, download_delay=0) | ||
405 | 168 | if options.download_base: | ||
406 | 169 | setup_args['download_base'] = options.download_base | ||
407 | 170 | if options.use_distribute: | ||
408 | 171 | setup_args['no_fake'] = True | ||
409 | 172 | ez['use_setuptools'](**setup_args) | ||
410 | 173 | if 'pkg_resources' in sys.modules: | ||
411 | 174 | reload(sys.modules['pkg_resources']) | ||
412 | 175 | import pkg_resources | ||
413 | 176 | # This does not (always?) update the default working set. We will | ||
414 | 177 | # do it. | ||
415 | 178 | for path in sys.path: | ||
416 | 179 | if path not in pkg_resources.working_set.entries: | ||
417 | 180 | pkg_resources.working_set.add_entry(path) | ||
418 | 181 | |||
419 | 182 | cmd = [quote(sys.executable), | ||
420 | 183 | '-c', | ||
421 | 184 | quote('from setuptools.command.easy_install import main; main()'), | ||
422 | 185 | '-mqNxd', | ||
423 | 186 | quote(eggs_dir)] | ||
424 | 187 | |||
425 | 188 | if not has_broken_dash_S: | ||
426 | 189 | cmd.insert(1, '-S') | ||
427 | 190 | |||
428 | 191 | find_links = options.download_base | ||
429 | 192 | if not find_links: | ||
430 | 193 | find_links = os.environ.get('bootstrap-testing-find-links') | ||
431 | 194 | if find_links: | ||
432 | 195 | cmd.extend(['-f', quote(find_links)]) | ||
433 | 196 | |||
434 | 197 | if options.use_distribute: | ||
435 | 198 | setup_requirement = 'distribute' | ||
436 | 199 | else: | ||
437 | 200 | setup_requirement = 'setuptools' | ||
438 | 201 | ws = pkg_resources.working_set | ||
439 | 202 | setup_requirement_path = ws.find( | ||
440 | 203 | pkg_resources.Requirement.parse(setup_requirement)).location | ||
441 | 204 | env = dict( | ||
442 | 205 | os.environ, | ||
443 | 206 | PYTHONPATH=setup_requirement_path) | ||
444 | 207 | |||
445 | 208 | requirement = 'zc.buildout' | ||
446 | 209 | version = options.version | ||
447 | 210 | if version is None and not options.accept_buildout_test_releases: | ||
448 | 211 | # Figure out the most recent final version of zc.buildout. | ||
449 | 212 | import setuptools.package_index | ||
450 | 213 | _final_parts = '*final-', '*final' | ||
451 | 214 | def _final_version(parsed_version): | ||
452 | 215 | for part in parsed_version: | ||
453 | 216 | if (part[:1] == '*') and (part not in _final_parts): | ||
454 | 217 | return False | ||
455 | 218 | return True | ||
456 | 219 | index = setuptools.package_index.PackageIndex( | ||
457 | 220 | search_path=[setup_requirement_path]) | ||
458 | 221 | if find_links: | ||
459 | 222 | index.add_find_links((find_links,)) | ||
460 | 223 | req = pkg_resources.Requirement.parse(requirement) | ||
461 | 224 | if index.obtain(req) is not None: | ||
462 | 225 | best = [] | ||
463 | 226 | bestv = None | ||
464 | 227 | for dist in index[req.project_name]: | ||
465 | 228 | distv = dist.parsed_version | ||
466 | 229 | if _final_version(distv): | ||
467 | 230 | if bestv is None or distv > bestv: | ||
468 | 231 | best = [dist] | ||
469 | 232 | bestv = distv | ||
470 | 233 | elif distv == bestv: | ||
471 | 234 | best.append(dist) | ||
472 | 235 | if best: | ||
473 | 236 | best.sort() | ||
474 | 237 | version = best[-1].version | ||
475 | 238 | if version: | ||
476 | 239 | requirement = '=='.join((requirement, version)) | ||
477 | 240 | cmd.append(requirement) | ||
478 | 241 | |||
479 | 242 | if is_jython: | ||
480 | 243 | import subprocess | ||
481 | 244 | exitcode = subprocess.Popen(cmd, env=env).wait() | ||
482 | 245 | else: # Windows prefers this, apparently; otherwise we would prefer subprocess | ||
483 | 246 | exitcode = os.spawnle(*([os.P_WAIT, sys.executable] + cmd + [env])) | ||
484 | 247 | if exitcode != 0: | ||
485 | 248 | sys.stdout.flush() | ||
486 | 249 | sys.stderr.flush() | ||
487 | 250 | print ("An error occurred when trying to install zc.buildout. " | ||
488 | 251 | "Look above this message for any errors that " | ||
489 | 252 | "were output by easy_install.") | ||
490 | 253 | sys.exit(exitcode) | ||
491 | 254 | |||
492 | 255 | ws.add_entry(eggs_dir) | ||
493 | 256 | ws.require(requirement) | ||
494 | 257 | import zc.buildout.buildout | ||
495 | 258 | zc.buildout.buildout.main(args) | ||
496 | 259 | if not options.eggs: # clean up temporary egg directory | ||
497 | 260 | shutil.rmtree(eggs_dir) | ||
498 | 261 | 0 | ||
499 | === removed file 'buildout.cfg' | |||
500 | --- buildout.cfg 2011-01-18 06:02:42 +0000 | |||
501 | +++ buildout.cfg 1970-01-01 00:00:00 +0000 | |||
502 | @@ -1,19 +0,0 @@ | |||
503 | 1 | [buildout] | ||
504 | 2 | parts = python django | ||
505 | 3 | develop = . | ||
506 | 4 | eggs = django-nova | ||
507 | 5 | |||
508 | 6 | [python] | ||
509 | 7 | recipe = zc.recipe.egg | ||
510 | 8 | interpreter = python | ||
511 | 9 | eggs = ${buildout:eggs} | ||
512 | 10 | |||
513 | 11 | [django] | ||
514 | 12 | recipe = djangorecipe | ||
515 | 13 | version = 1.2.4 | ||
516 | 14 | project = django_nova | ||
517 | 15 | projectegg = django_nova | ||
518 | 16 | settings = testsettings | ||
519 | 17 | test = django_nova | ||
520 | 18 | eggs = ${buildout:eggs} | ||
521 | 19 | |||
522 | 20 | 0 | ||
523 | === removed file 'setup.py' | |||
524 | --- setup.py 2011-01-21 22:38:42 +0000 | |||
525 | +++ setup.py 1970-01-01 00:00:00 +0000 | |||
526 | @@ -1,29 +0,0 @@ | |||
527 | 1 | import os | ||
528 | 2 | from setuptools import setup, find_packages | ||
529 | 3 | |||
530 | 4 | def read(fname): | ||
531 | 5 | return open(os.path.join(os.path.dirname(__file__), fname)).read() | ||
532 | 6 | |||
533 | 7 | setup( | ||
534 | 8 | name = "django-nova", | ||
535 | 9 | version = "0.1", | ||
536 | 10 | url = 'https://launchpad.net/django-nova/', | ||
537 | 11 | license = 'Apache 2.0', | ||
538 | 12 | description = "A Django interface for OpenStack Nova.", | ||
539 | 13 | long_description = read('README'), | ||
540 | 14 | author = 'Devin Carlen', | ||
541 | 15 | author_email = 'devin.carlen@gmail.com', | ||
542 | 16 | packages = find_packages('src'), | ||
543 | 17 | package_dir = {'': 'src'}, | ||
544 | 18 | install_requires = ['setuptools', 'boto==1.9b', 'mox>=0.5.0'], | ||
545 | 19 | classifiers = [ | ||
546 | 20 | 'Development Status :: 4 - Beta', | ||
547 | 21 | 'Framework :: Django', | ||
548 | 22 | 'Intended Audience :: Developers', | ||
549 | 23 | 'License :: OSI Approved :: Apache License', | ||
550 | 24 | 'Operating System :: OS Independent', | ||
551 | 25 | 'Programming Language :: Python', | ||
552 | 26 | 'Topic :: Internet :: WWW/HTTP', | ||
553 | 27 | ] | ||
554 | 28 | ) | ||
555 | 29 | |||
556 | 30 | 0 | ||
557 | === removed directory 'src' | |||
558 | === removed directory 'src/django_nova' | |||
559 | === removed file 'src/django_nova/__init__.py' | |||
560 | === removed file 'src/django_nova/adminclient.py' | |||
561 | --- src/django_nova/adminclient.py 2011-01-28 20:35:31 +0000 | |||
562 | +++ src/django_nova/adminclient.py 1970-01-01 00:00:00 +0000 | |||
563 | @@ -1,498 +0,0 @@ | |||
564 | 1 | # vim: tabstop=4 shiftwidth=4 softtabstop=4 | ||
565 | 2 | |||
566 | 3 | # Copyright 2010 United States Government as represented by the | ||
567 | 4 | # Administrator of the National Aeronautics and Space Administration. | ||
568 | 5 | # All Rights Reserved. | ||
569 | 6 | # | ||
570 | 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | ||
571 | 8 | # not use this file except in compliance with the License. You may obtain | ||
572 | 9 | # a copy of the License at | ||
573 | 10 | # | ||
574 | 11 | # http://www.apache.org/licenses/LICENSE-2.0 | ||
575 | 12 | # | ||
576 | 13 | # Unless required by applicable law or agreed to in writing, software | ||
577 | 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
578 | 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
579 | 16 | # License for the specific language governing permissions and limitations | ||
580 | 17 | # under the License. | ||
581 | 18 | """ | ||
582 | 19 | Nova User API client library. | ||
583 | 20 | """ | ||
584 | 21 | |||
585 | 22 | import base64 | ||
586 | 23 | import boto | ||
587 | 24 | import boto.exception | ||
588 | 25 | import httplib | ||
589 | 26 | import re | ||
590 | 27 | import string | ||
591 | 28 | from boto.ec2.regioninfo import RegionInfo | ||
592 | 29 | |||
593 | 30 | |||
594 | 31 | DEFAULT_CLC_URL='http://127.0.0.1:8773' | ||
595 | 32 | DEFAULT_REGION='nova' | ||
596 | 33 | DEFAULT_ACCESS_KEY='admin' | ||
597 | 34 | DEFAULT_SECRET_KEY='admin' | ||
598 | 35 | |||
599 | 36 | |||
600 | 37 | class UserInfo(object): | ||
601 | 38 | """ | ||
602 | 39 | Information about a Nova user, as parsed through SAX | ||
603 | 40 | fields include: | ||
604 | 41 | username | ||
605 | 42 | accesskey | ||
606 | 43 | secretkey | ||
607 | 44 | |||
608 | 45 | and an optional field containing a zip with X509 cert & rc | ||
609 | 46 | file | ||
610 | 47 | """ | ||
611 | 48 | |||
612 | 49 | def __init__(self, connection=None, username=None, endpoint=None): | ||
613 | 50 | self.connection = connection | ||
614 | 51 | self.username = username | ||
615 | 52 | self.endpoint = endpoint | ||
616 | 53 | |||
617 | 54 | def __repr__(self): | ||
618 | 55 | return 'UserInfo:%s' % self.username | ||
619 | 56 | |||
620 | 57 | def startElement(self, name, attrs, connection): | ||
621 | 58 | return None | ||
622 | 59 | |||
623 | 60 | def endElement(self, name, value, connection): | ||
624 | 61 | if name == 'username': | ||
625 | 62 | self.username = str(value) | ||
626 | 63 | elif name == 'file': | ||
627 | 64 | self.file = base64.b64decode(str(value)) | ||
628 | 65 | elif name == 'accesskey': | ||
629 | 66 | self.accesskey = str(value) | ||
630 | 67 | elif name == 'secretkey': | ||
631 | 68 | self.secretkey = str(value) | ||
632 | 69 | |||
633 | 70 | |||
634 | 71 | class UserRole(object): | ||
635 | 72 | """ | ||
636 | 73 | Information about a Nova user's role, as parsed through SAX. | ||
637 | 74 | Fields include: | ||
638 | 75 | role | ||
639 | 76 | """ | ||
640 | 77 | def __init__(self, connection=None): | ||
641 | 78 | self.connection = connection | ||
642 | 79 | self.role = None | ||
643 | 80 | |||
644 | 81 | def __repr__(self): | ||
645 | 82 | return 'UserRole:%s' % self.role | ||
646 | 83 | |||
647 | 84 | def startElement(self, name, attrs, connection): | ||
648 | 85 | return None | ||
649 | 86 | |||
650 | 87 | def endElement(self, name, value, connection): | ||
651 | 88 | if name == 'role': | ||
652 | 89 | self.role = value | ||
653 | 90 | else: | ||
654 | 91 | setattr(self, name, str(value)) | ||
655 | 92 | |||
656 | 93 | |||
657 | 94 | class ProjectInfo(object): | ||
658 | 95 | """ | ||
659 | 96 | Information about a Nova project, as parsed through SAX | ||
660 | 97 | Fields include: | ||
661 | 98 | projectname | ||
662 | 99 | description | ||
663 | 100 | projectManagerId | ||
664 | 101 | memberIds | ||
665 | 102 | """ | ||
666 | 103 | |||
667 | 104 | def __init__(self, connection=None): | ||
668 | 105 | self.connection = connection | ||
669 | 106 | self.projectname = None | ||
670 | 107 | self.description = None | ||
671 | 108 | self.projectManagerId = None | ||
672 | 109 | self.memberIds = [] | ||
673 | 110 | |||
674 | 111 | def __repr__(self): | ||
675 | 112 | return 'ProjectInfo:%s' % self.projectname | ||
676 | 113 | |||
677 | 114 | def startElement(self, name, attrs, connection): | ||
678 | 115 | return None | ||
679 | 116 | |||
680 | 117 | def endElement(self, name, value, connection): | ||
681 | 118 | if name == 'projectname': | ||
682 | 119 | self.projectname = value | ||
683 | 120 | elif name == 'description': | ||
684 | 121 | self.description = value | ||
685 | 122 | elif name == 'projectManagerId': | ||
686 | 123 | self.projectManagerId = value | ||
687 | 124 | elif name == 'memberId': | ||
688 | 125 | self.memberIds.append(value) | ||
689 | 126 | else: | ||
690 | 127 | setattr(self, name, str(value)) | ||
691 | 128 | |||
692 | 129 | |||
693 | 130 | class ProjectMember(object): | ||
694 | 131 | """ | ||
695 | 132 | Information about a Nova project member, as parsed through SAX. | ||
696 | 133 | Fields include: | ||
697 | 134 | memberId | ||
698 | 135 | """ | ||
699 | 136 | |||
700 | 137 | def __init__(self, connection=None): | ||
701 | 138 | self.connection = connection | ||
702 | 139 | self.memberId = None | ||
703 | 140 | |||
704 | 141 | def __repr__(self): | ||
705 | 142 | return 'ProjectMember:%s' % self.memberId | ||
706 | 143 | |||
707 | 144 | def startElement(self, name, attrs, connection): | ||
708 | 145 | return None | ||
709 | 146 | |||
710 | 147 | def endElement(self, name, value, connection): | ||
711 | 148 | if name == 'member': | ||
712 | 149 | self.memberId = value | ||
713 | 150 | else: | ||
714 | 151 | setattr(self, name, str(value)) | ||
715 | 152 | |||
716 | 153 | |||
717 | 154 | class HostInfo(object): | ||
718 | 155 | """ | ||
719 | 156 | Information about a Nova Host, as parsed through SAX: | ||
720 | 157 | Hostname | ||
721 | 158 | Compute Service Status | ||
722 | 159 | Volume Service Status | ||
723 | 160 | """ | ||
724 | 161 | |||
725 | 162 | def __init__(self, connection=None): | ||
726 | 163 | self.connection = connection | ||
727 | 164 | self.hostname = None | ||
728 | 165 | self.compute = None | ||
729 | 166 | self.volume = None | ||
730 | 167 | self.instance_count = 0 | ||
731 | 168 | self.volume_count = 0 | ||
732 | 169 | |||
733 | 170 | def __repr__(self): | ||
734 | 171 | return 'Host:%s' % self.hostname | ||
735 | 172 | |||
736 | 173 | # this is needed by the sax parser, so ignore the ugly name | ||
737 | 174 | def startElement(self, name, attrs, connection): | ||
738 | 175 | return None | ||
739 | 176 | |||
740 | 177 | # this is needed by the sax parser, so ignore the ugly name | ||
741 | 178 | def endElement(self, name, value, connection): | ||
742 | 179 | fixed_name = string.lower(re.sub(r'([A-Z])', r'_\1', name)) | ||
743 | 180 | setattr(self, fixed_name, value) | ||
744 | 181 | |||
745 | 182 | |||
746 | 183 | class Vpn(object): | ||
747 | 184 | """ | ||
748 | 185 | Information about a Vpn, as parsed through SAX | ||
749 | 186 | fields include: | ||
750 | 187 | instance_id | ||
751 | 188 | project_id | ||
752 | 189 | public_ip | ||
753 | 190 | public_port | ||
754 | 191 | created_at | ||
755 | 192 | internal_ip | ||
756 | 193 | state | ||
757 | 194 | """ | ||
758 | 195 | |||
759 | 196 | def __init__(self, connection=None): | ||
760 | 197 | self.connection = connection | ||
761 | 198 | self.instance_id = None | ||
762 | 199 | self.project_id = None | ||
763 | 200 | |||
764 | 201 | def __repr__(self): | ||
765 | 202 | return 'Vpn:%s:%s' % (self.project_id, self.instance_id) | ||
766 | 203 | |||
767 | 204 | def startElement(self, name, attrs, connection): | ||
768 | 205 | return None | ||
769 | 206 | |||
770 | 207 | def endElement(self, name, value, connection): | ||
771 | 208 | if name == 'instanceId': | ||
772 | 209 | self.instance_id = str(value) | ||
773 | 210 | elif name == 'projectId': | ||
774 | 211 | self.project_id = str(value) | ||
775 | 212 | elif name == 'publicIp': | ||
776 | 213 | self.public_ip = str(value) | ||
777 | 214 | elif name == 'publicPort': | ||
778 | 215 | self.public_port = str(value) | ||
779 | 216 | elif name == 'createdAt': | ||
780 | 217 | self.created_at = str(value) | ||
781 | 218 | elif name == 'internalIp': | ||
782 | 219 | self.internal_ip = str(value) | ||
783 | 220 | else: | ||
784 | 221 | setattr(self, name, str(value)) | ||
785 | 222 | |||
786 | 223 | |||
787 | 224 | class InstanceType(object): | ||
788 | 225 | """ | ||
789 | 226 | Information about a Nova instance type, as parsed through SAX. | ||
790 | 227 | |||
791 | 228 | **Fields include** | ||
792 | 229 | |||
793 | 230 | * name | ||
794 | 231 | * vcpus | ||
795 | 232 | * disk_gb | ||
796 | 233 | * memory_mb | ||
797 | 234 | * flavor_id | ||
798 | 235 | |||
799 | 236 | """ | ||
800 | 237 | |||
801 | 238 | def __init__(self, connection=None): | ||
802 | 239 | self.connection = connection | ||
803 | 240 | self.name = None | ||
804 | 241 | self.vcpus = None | ||
805 | 242 | self.disk_gb = None | ||
806 | 243 | self.memory_mb = None | ||
807 | 244 | self.flavor_id = None | ||
808 | 245 | |||
809 | 246 | def __repr__(self): | ||
810 | 247 | return 'InstanceType:%s' % self.name | ||
811 | 248 | |||
812 | 249 | def startElement(self, name, attrs, connection): | ||
813 | 250 | return None | ||
814 | 251 | |||
815 | 252 | def endElement(self, name, value, connection): | ||
816 | 253 | if name == "memoryMb": | ||
817 | 254 | self.memory_mb = str(value) | ||
818 | 255 | elif name == "flavorId": | ||
819 | 256 | self.flavor_id = str(value) | ||
820 | 257 | elif name == "diskGb": | ||
821 | 258 | self.disk_gb = str(value) | ||
822 | 259 | else: | ||
823 | 260 | setattr(self, name, str(value)) | ||
824 | 261 | |||
825 | 262 | |||
826 | 263 | class StatusResponse(object): | ||
827 | 264 | def __init__(self, connection=None): | ||
828 | 265 | self.connection = connection | ||
829 | 266 | self.status = None | ||
830 | 267 | |||
831 | 268 | def __repr__(self): | ||
832 | 269 | return 'Status:%s' % self.status | ||
833 | 270 | |||
834 | 271 | def startElement(self, name, attrs, connection): | ||
835 | 272 | return None | ||
836 | 273 | |||
837 | 274 | def endElement(self, name, value, connection): | ||
838 | 275 | setattr(self, name, str(value)) | ||
839 | 276 | |||
840 | 277 | |||
841 | 278 | class NovaAdminClient(object): | ||
842 | 279 | def __init__(self, clc_url=DEFAULT_CLC_URL, region=DEFAULT_REGION, | ||
843 | 280 | access_key=DEFAULT_ACCESS_KEY, secret_key=DEFAULT_SECRET_KEY, | ||
844 | 281 | **kwargs): | ||
845 | 282 | parts = self.split_clc_url(clc_url) | ||
846 | 283 | |||
847 | 284 | self.clc_url = clc_url | ||
848 | 285 | self.region = region | ||
849 | 286 | self.access = access_key | ||
850 | 287 | self.secret = secret_key | ||
851 | 288 | self.apiconn = boto.connect_ec2(aws_access_key_id=access_key, | ||
852 | 289 | aws_secret_access_key=secret_key, | ||
853 | 290 | is_secure=parts['is_secure'], | ||
854 | 291 | region=RegionInfo(None, | ||
855 | 292 | region, | ||
856 | 293 | parts['ip']), | ||
857 | 294 | port=parts['port'], | ||
858 | 295 | path='/services/Admin', | ||
859 | 296 | **kwargs) | ||
860 | 297 | self.apiconn.APIVersion = 'nova' | ||
861 | 298 | |||
862 | 299 | def connection_for(self, username, project, clc_url=None, region=None, | ||
863 | 300 | **kwargs): | ||
864 | 301 | """ | ||
865 | 302 | Returns a boto ec2 connection for the given username. | ||
866 | 303 | """ | ||
867 | 304 | if not clc_url: | ||
868 | 305 | clc_url = self.clc_url | ||
869 | 306 | if not region: | ||
870 | 307 | region = self.region | ||
871 | 308 | parts = self.split_clc_url(clc_url) | ||
872 | 309 | user = self.get_user(username) | ||
873 | 310 | access_key = '%s:%s' % (user.accesskey, project) | ||
874 | 311 | return boto.connect_ec2(aws_access_key_id=access_key, | ||
875 | 312 | aws_secret_access_key=user.secretkey, | ||
876 | 313 | is_secure=parts['is_secure'], | ||
877 | 314 | region=RegionInfo(None, | ||
878 | 315 | self.region, | ||
879 | 316 | parts['ip']), | ||
880 | 317 | port=parts['port'], | ||
881 | 318 | path='/services/Cloud', | ||
882 | 319 | **kwargs) | ||
883 | 320 | |||
884 | 321 | def split_clc_url(self, clc_url): | ||
885 | 322 | """ | ||
886 | 323 | Splits a cloud controller endpoint url. | ||
887 | 324 | """ | ||
888 | 325 | parts = httplib.urlsplit(clc_url) | ||
889 | 326 | is_secure = parts.scheme == 'https' | ||
890 | 327 | ip, port = parts.netloc.split(':') | ||
891 | 328 | return {'ip': ip, 'port': int(port), 'is_secure': is_secure} | ||
892 | 329 | |||
893 | 330 | def get_users(self): | ||
894 | 331 | """ grabs the list of all users """ | ||
895 | 332 | return self.apiconn.get_list('DescribeUsers', {}, [('item', UserInfo)]) | ||
896 | 333 | |||
897 | 334 | def get_user(self, name): | ||
898 | 335 | """ grab a single user by name """ | ||
899 | 336 | try: | ||
900 | 337 | return self.apiconn.get_object('DescribeUser', {'Name': name}, UserInfo) | ||
901 | 338 | except boto.exception.BotoServerError, e: | ||
902 | 339 | if e.status == 400 and e.error_code == 'NotFound': | ||
903 | 340 | return None | ||
904 | 341 | raise | ||
905 | 342 | |||
906 | 343 | def has_user(self, username): | ||
907 | 344 | """ determine if user exists """ | ||
908 | 345 | return self.get_user(username) != None | ||
909 | 346 | |||
910 | 347 | def create_user(self, username): | ||
911 | 348 | """ creates a new user, returning the userinfo object with access/secret """ | ||
912 | 349 | return self.apiconn.get_object('RegisterUser', {'Name': username}, UserInfo) | ||
913 | 350 | |||
914 | 351 | def delete_user(self, username): | ||
915 | 352 | """ deletes a user """ | ||
916 | 353 | return self.apiconn.get_object('DeregisterUser', {'Name': username}, UserInfo) | ||
917 | 354 | |||
918 | 355 | def get_roles(self, project_roles=True): | ||
919 | 356 | """Returns a list of available roles.""" | ||
920 | 357 | return self.apiconn.get_list('DescribeRoles', | ||
921 | 358 | {'ProjectRoles': project_roles}, | ||
922 | 359 | [('item', UserRole)]) | ||
923 | 360 | |||
924 | 361 | def get_user_roles(self, user, project=None): | ||
925 | 362 | """Returns a list of roles for the given user. | ||
926 | 363 | Omitting project will return any global roles that the user has. | ||
927 | 364 | Specifying project will return only project specific roles. | ||
928 | 365 | """ | ||
929 | 366 | params = {'User':user} | ||
930 | 367 | if project: | ||
931 | 368 | params['Project'] = project | ||
932 | 369 | return self.apiconn.get_list('DescribeUserRoles', | ||
933 | 370 | params, | ||
934 | 371 | [('item', UserRole)]) | ||
935 | 372 | |||
936 | 373 | def add_user_role(self, user, role, project=None): | ||
937 | 374 | """ | ||
938 | 375 | Add a role to a user either globally or for a specific project. | ||
939 | 376 | """ | ||
940 | 377 | return self.modify_user_role(user, role, project=project, | ||
941 | 378 | operation='add') | ||
942 | 379 | |||
943 | 380 | def remove_user_role(self, user, role, project=None): | ||
944 | 381 | """ | ||
945 | 382 | Remove a role from a user either globally or for a specific project. | ||
946 | 383 | """ | ||
947 | 384 | return self.modify_user_role(user, role, project=project, | ||
948 | 385 | operation='remove') | ||
949 | 386 | |||
950 | 387 | def modify_user_role(self, user, role, project=None, operation='add', | ||
951 | 388 | **kwargs): | ||
952 | 389 | """ | ||
953 | 390 | Add or remove a role for a user and project. | ||
954 | 391 | """ | ||
955 | 392 | params = {'User': user, | ||
956 | 393 | 'Role': role, | ||
957 | 394 | 'Project': project, | ||
958 | 395 | 'Operation': operation} | ||
959 | 396 | return self.apiconn.get_status('ModifyUserRole', params) | ||
960 | 397 | |||
961 | 398 | def get_projects(self, user=None): | ||
962 | 399 | """ | ||
963 | 400 | Returns a list of all projects. | ||
964 | 401 | """ | ||
965 | 402 | if user: | ||
966 | 403 | params = {'User': user} | ||
967 | 404 | else: | ||
968 | 405 | params = {} | ||
969 | 406 | return self.apiconn.get_list('DescribeProjects', | ||
970 | 407 | params, | ||
971 | 408 | [('item', ProjectInfo)]) | ||
972 | 409 | |||
973 | 410 | def get_project(self, name): | ||
974 | 411 | """ | ||
975 | 412 | Returns a single project with the specified name. | ||
976 | 413 | """ | ||
977 | 414 | project = self.apiconn.get_object('DescribeProject', | ||
978 | 415 | {'Name': name}, | ||
979 | 416 | ProjectInfo) | ||
980 | 417 | |||
981 | 418 | if project.projectname != None: | ||
982 | 419 | return project | ||
983 | 420 | |||
984 | 421 | def create_project(self, projectname, manager_user, description=None, | ||
985 | 422 | member_users=None): | ||
986 | 423 | """ | ||
987 | 424 | Creates a new project. | ||
988 | 425 | """ | ||
989 | 426 | params = {'Name': projectname, | ||
990 | 427 | 'ManagerUser': manager_user, | ||
991 | 428 | 'Description': description, | ||
992 | 429 | 'MemberUsers': member_users} | ||
993 | 430 | return self.apiconn.get_object('RegisterProject', params, ProjectInfo) | ||
994 | 431 | |||
995 | 432 | def delete_project(self, projectname): | ||
996 | 433 | """ | ||
997 | 434 | Permanently deletes the specified project. | ||
998 | 435 | """ | ||
999 | 436 | return self.apiconn.get_object('DeregisterProject', | ||
1000 | 437 | {'Name': projectname}, | ||
1001 | 438 | ProjectInfo) | ||
1002 | 439 | |||
1003 | 440 | def get_project_members(self, name): | ||
1004 | 441 | """ | ||
1005 | 442 | Returns a list of members of a project. | ||
1006 | 443 | """ | ||
1007 | 444 | return self.apiconn.get_list('DescribeProjectMembers', | ||
1008 | 445 | {'Name': name}, | ||
1009 | 446 | [('item', ProjectMember)]) | ||
1010 | 447 | |||
1011 | 448 | def add_project_member(self, user, project): | ||
1012 | 449 | """ | ||
1013 | 450 | Adds a user to a project. | ||
1014 | 451 | """ | ||
1015 | 452 | return self.modify_project_member(user, project, operation='add') | ||
1016 | 453 | |||
1017 | 454 | def remove_project_member(self, user, project): | ||
1018 | 455 | """ | ||
1019 | 456 | Removes a user from a project. | ||
1020 | 457 | """ | ||
1021 | 458 | return self.modify_project_member(user, project, operation='remove') | ||
1022 | 459 | |||
1023 | 460 | def modify_project_member(self, user, project, operation='add'): | ||
1024 | 461 | """ | ||
1025 | 462 | Adds or removes a user from a project. | ||
1026 | 463 | """ | ||
1027 | 464 | params = {'User': user, | ||
1028 | 465 | 'Project': project, | ||
1029 | 466 | 'Operation': operation} | ||
1030 | 467 | return self.apiconn.get_status('ModifyProjectMember', params) | ||
1031 | 468 | |||
1032 | 469 | def get_zip(self, user, project): | ||
1033 | 470 | """ | ||
1034 | 471 | Returns the content of a zip file containing novarc and access credentials. | ||
1035 | 472 | """ | ||
1036 | 473 | params = {'Name': user, 'Project': project} | ||
1037 | 474 | zip = self.apiconn.get_object('GenerateX509ForUser', params, UserInfo) | ||
1038 | 475 | return zip.file | ||
1039 | 476 | |||
1040 | 477 | def start_vpn(self, project): | ||
1041 | 478 | """ | ||
1042 | 479 | Starts the vpn for a user | ||
1043 | 480 | """ | ||
1044 | 481 | return self.apiconn.get_object('StartVpn', {'Project': project}, Vpn) | ||
1045 | 482 | |||
1046 | 483 | def get_vpns(self): | ||
1047 | 484 | """Return a list of vpn with project name""" | ||
1048 | 485 | return self.apiconn.get_list('DescribeVpns', {}, [('item', Vpn)]) | ||
1049 | 486 | |||
1050 | 487 | def get_hosts(self): | ||
1051 | 488 | return self.apiconn.get_list('DescribeHosts', {}, [('item', HostInfo)]) | ||
1052 | 489 | |||
1053 | 490 | def get_instance_types(self): | ||
1054 | 491 | """Grabs the list of all users.""" | ||
1055 | 492 | return self.apiconn.get_list('DescribeInstanceTypes', {}, | ||
1056 | 493 | [('item', InstanceType)]) | ||
1057 | 494 | |||
1058 | 495 | def disable_project_credentials(self, project): | ||
1059 | 496 | """Revoke project credentials and kill the cloudpipe/vpn instance""" | ||
1060 | 497 | return self.apiconn.get_object('DisableProjectCredentials', | ||
1061 | 498 | {'Project': project}, StatusResponse) | ||
1062 | 499 | 0 | ||
1063 | === removed file 'src/django_nova/connection.py' | |||
1064 | --- src/django_nova/connection.py 2011-01-12 20:02:06 +0000 | |||
1065 | +++ src/django_nova/connection.py 1970-01-01 00:00:00 +0000 | |||
1066 | @@ -1,38 +0,0 @@ | |||
1067 | 1 | # vim: tabstop=4 shiftwidth=4 softtabstop=4 | ||
1068 | 2 | |||
1069 | 3 | # Copyright 2010 United States Government as represented by the | ||
1070 | 4 | # Administrator of the National Aeronautics and Space Administration. | ||
1071 | 5 | # All Rights Reserved. | ||
1072 | 6 | # | ||
1073 | 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | ||
1074 | 8 | # not use this file except in compliance with the License. You may obtain | ||
1075 | 9 | # a copy of the License at | ||
1076 | 10 | # | ||
1077 | 11 | # http://www.apache.org/licenses/LICENSE-2.0 | ||
1078 | 12 | # | ||
1079 | 13 | # Unless required by applicable law or agreed to in writing, software | ||
1080 | 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
1081 | 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
1082 | 16 | # License for the specific language governing permissions and limitations | ||
1083 | 17 | # under the License. | ||
1084 | 18 | """ | ||
1085 | 19 | Manage connections to Nova's admin API. | ||
1086 | 20 | """ | ||
1087 | 21 | |||
1088 | 22 | from django.conf import settings | ||
1089 | 23 | from django_nova import adminclient | ||
1090 | 24 | |||
1091 | 25 | |||
1092 | 26 | def get_nova_admin_connection(): | ||
1093 | 27 | """ | ||
1094 | 28 | Returns a Nova administration connection. | ||
1095 | 29 | """ | ||
1096 | 30 | return adminclient.NovaAdminClient ( | ||
1097 | 31 | clc_url=settings.NOVA_DEFAULT_ENDPOINT, | ||
1098 | 32 | region=settings.NOVA_DEFAULT_REGION, | ||
1099 | 33 | access_key=settings.NOVA_ACCESS_KEY, | ||
1100 | 34 | secret_key=settings.NOVA_SECRET_KEY | ||
1101 | 35 | ) | ||
1102 | 36 | |||
1103 | 37 | |||
1104 | 38 | |||
1105 | 39 | 0 | ||
1106 | === removed file 'src/django_nova/exceptions.py' | |||
1107 | --- src/django_nova/exceptions.py 2011-01-18 23:07:26 +0000 | |||
1108 | +++ src/django_nova/exceptions.py 1970-01-01 00:00:00 +0000 | |||
1109 | @@ -1,95 +0,0 @@ | |||
1110 | 1 | # vim: tabstop=4 shiftwidth=4 softtabstop=4 | ||
1111 | 2 | |||
1112 | 3 | # Copyright 2010 United States Government as represented by the | ||
1113 | 4 | # Administrator of the National Aeronautics and Space Administration. | ||
1114 | 5 | # All Rights Reserved. | ||
1115 | 6 | # | ||
1116 | 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | ||
1117 | 8 | # not use this file except in compliance with the License. You may obtain | ||
1118 | 9 | # a copy of the License at | ||
1119 | 10 | # | ||
1120 | 11 | # http://www.apache.org/licenses/LICENSE-2.0 | ||
1121 | 12 | # | ||
1122 | 13 | # Unless required by applicable law or agreed to in writing, software | ||
1123 | 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
1124 | 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
1125 | 16 | # License for the specific language governing permissions and limitations | ||
1126 | 17 | # under the License. | ||
1127 | 18 | |||
1128 | 19 | """ | ||
1129 | 20 | Better wrappers for errors from Nova's admin api. | ||
1130 | 21 | """ | ||
1131 | 22 | |||
1132 | 23 | import boto.exception | ||
1133 | 24 | from django.shortcuts import redirect | ||
1134 | 25 | from django.core import exceptions as core_exceptions | ||
1135 | 26 | |||
1136 | 27 | |||
1137 | 28 | class NovaServerError(Exception): | ||
1138 | 29 | """ | ||
1139 | 30 | Consumes a BotoServerError and gives more meaningful errors. | ||
1140 | 31 | """ | ||
1141 | 32 | def __init__(self, ec2error): | ||
1142 | 33 | self.status = ec2error.status | ||
1143 | 34 | self.message = ec2error.reason | ||
1144 | 35 | |||
1145 | 36 | def __str__(self): | ||
1146 | 37 | return self.message | ||
1147 | 38 | |||
1148 | 39 | |||
1149 | 40 | class NovaApiError(Exception): | ||
1150 | 41 | """ | ||
1151 | 42 | Used when Nova returns a 400 Bad Request status. | ||
1152 | 43 | """ | ||
1153 | 44 | def __init__(self, ec2error): | ||
1154 | 45 | self.message = ec2error.error_message | ||
1155 | 46 | |||
1156 | 47 | def __str__(self): | ||
1157 | 48 | return self.message | ||
1158 | 49 | |||
1159 | 50 | |||
1160 | 51 | class NovaUnavailableError(NovaServerError): | ||
1161 | 52 | """ | ||
1162 | 53 | Used when Nova returns a 503 Service Unavailable status. | ||
1163 | 54 | """ | ||
1164 | 55 | pass | ||
1165 | 56 | |||
1166 | 57 | |||
1167 | 58 | class NovaUnauthorizedError(core_exceptions.PermissionDenied): | ||
1168 | 59 | """ | ||
1169 | 60 | Used when Nova returns a 401 Not Authorized status. | ||
1170 | 61 | """ | ||
1171 | 62 | pass | ||
1172 | 63 | |||
1173 | 64 | |||
1174 | 65 | def wrap_nova_error(func): | ||
1175 | 66 | """ | ||
1176 | 67 | Used to decorate a function that interacts with boto. It will catch | ||
1177 | 68 | and convert boto server errors and reraise as a more specific nova error. | ||
1178 | 69 | """ | ||
1179 | 70 | def decorator(*args, **kwargs): | ||
1180 | 71 | try: | ||
1181 | 72 | return func(*args, **kwargs) | ||
1182 | 73 | except boto.exception.BotoServerError, e: | ||
1183 | 74 | if e.status == 400 and e.error_code == 'ApiError': | ||
1184 | 75 | raise NovaApiError(e) | ||
1185 | 76 | elif e.status == 401: | ||
1186 | 77 | raise NovaUnauthorizedError() | ||
1187 | 78 | elif e.status == 503: | ||
1188 | 79 | raise NovaUnavailableError(e) | ||
1189 | 80 | raise NovaServerError(e) | ||
1190 | 81 | return decorator | ||
1191 | 82 | |||
1192 | 83 | |||
1193 | 84 | def handle_nova_error(func): | ||
1194 | 85 | """ | ||
1195 | 86 | Decorator for handling nova errors in a generalized way. | ||
1196 | 87 | """ | ||
1197 | 88 | def decorator(*args, **kwargs): | ||
1198 | 89 | try: | ||
1199 | 90 | return func(*args, **kwargs) | ||
1200 | 91 | except NovaUnavailableError: | ||
1201 | 92 | return redirect('nova_unavailable') | ||
1202 | 93 | return decorator | ||
1203 | 94 | |||
1204 | 95 | |||
1205 | 96 | 0 | ||
1206 | === removed file 'src/django_nova/forms.py' | |||
1207 | --- src/django_nova/forms.py 2011-01-21 22:38:42 +0000 | |||
1208 | +++ src/django_nova/forms.py 1970-01-01 00:00:00 +0000 | |||
1209 | @@ -1,262 +0,0 @@ | |||
1210 | 1 | # vim: tabstop=4 shiftwidth=4 softtabstop=4 | ||
1211 | 2 | |||
1212 | 3 | # Copyright 2010 United States Government as represented by the | ||
1213 | 4 | # Administrator of the National Aeronautics and Space Administration. | ||
1214 | 5 | # All Rights Reserved. | ||
1215 | 6 | # | ||
1216 | 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | ||
1217 | 8 | # not use this file except in compliance with the License. You may obtain | ||
1218 | 9 | # a copy of the License at | ||
1219 | 10 | # | ||
1220 | 11 | # http://www.apache.org/licenses/LICENSE-2.0 | ||
1221 | 12 | # | ||
1222 | 13 | # Unless required by applicable law or agreed to in writing, software | ||
1223 | 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
1224 | 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
1225 | 16 | # License for the specific language governing permissions and limitations | ||
1226 | 17 | # under the License. | ||
1227 | 18 | |||
1228 | 19 | """ | ||
1229 | 20 | Forms used by various views. | ||
1230 | 21 | """ | ||
1231 | 22 | |||
1232 | 23 | import re | ||
1233 | 24 | |||
1234 | 25 | from django import forms | ||
1235 | 26 | from django.contrib.auth import models as auth_models | ||
1236 | 27 | from django_nova.connection import get_nova_admin_connection | ||
1237 | 28 | from django_nova.exceptions import wrap_nova_error | ||
1238 | 29 | |||
1239 | 30 | |||
1240 | 31 | # TODO: Store this in settings. | ||
1241 | 32 | MAX_VOLUME_SIZE = 100 | ||
1242 | 33 | |||
1243 | 34 | alphanumeric_re = re.compile(r'^\w+$') | ||
1244 | 35 | |||
1245 | 36 | |||
1246 | 37 | @wrap_nova_error | ||
1247 | 38 | def get_instance_type_choices(): | ||
1248 | 39 | """ | ||
1249 | 40 | Returns list of instance types from nova admin api | ||
1250 | 41 | """ | ||
1251 | 42 | nova = get_nova_admin_connection() | ||
1252 | 43 | instance_types = nova.get_instance_types() | ||
1253 | 44 | rv = [] | ||
1254 | 45 | for t in instance_types: | ||
1255 | 46 | rv.append((t.name, "%s (%sMB memory, %s cpu, %sGB space)" % \ | ||
1256 | 47 | (t.name, t.memory_mb, t.vcpus, t.disk_gb))) | ||
1257 | 48 | return rv | ||
1258 | 49 | |||
1259 | 50 | def get_instance_choices(project): | ||
1260 | 51 | choices = [(i.id, i.id) for i in project.get_instances()] | ||
1261 | 52 | if not len(choices): | ||
1262 | 53 | choices = [('', 'none available')] | ||
1263 | 54 | return choices | ||
1264 | 55 | |||
1265 | 56 | def get_key_pair_choices(project): | ||
1266 | 57 | choices = [(k.name, k.name) for k in project.get_key_pairs()] | ||
1267 | 58 | if not len(choices): | ||
1268 | 59 | choices = [('', 'none available')] | ||
1269 | 60 | return choices | ||
1270 | 61 | |||
1271 | 62 | #def get_security_group_choices(project): | ||
1272 | 63 | # choices = [(g.name, g.description) for g in project.get_security_groups()] | ||
1273 | 64 | # if len(choices) == 0: | ||
1274 | 65 | # choices = [('', 'none available')] | ||
1275 | 66 | # return choices | ||
1276 | 67 | |||
1277 | 68 | def get_available_volume_choices(project): | ||
1278 | 69 | choices = [(v.id, '%s %s - %dGB' % (v.id, v.displayName, v.size)) for v in \ | ||
1279 | 70 | project.get_volumes() if v.status != "in-use"] | ||
1280 | 71 | if not len(choices): | ||
1281 | 72 | choices = [('', 'none available')] | ||
1282 | 73 | return choices | ||
1283 | 74 | |||
1284 | 75 | def get_protocols(): | ||
1285 | 76 | return ( | ||
1286 | 77 | ('tcp', 'tcp'), | ||
1287 | 78 | ('udp', 'udp'), | ||
1288 | 79 | ) | ||
1289 | 80 | |||
1290 | 81 | @wrap_nova_error | ||
1291 | 82 | def get_roles(project_roles=True): | ||
1292 | 83 | nova = get_nova_admin_connection() | ||
1293 | 84 | roles = nova.get_roles(project_roles=project_roles) | ||
1294 | 85 | return [(role.role, role.role) for role in roles] | ||
1295 | 86 | |||
1296 | 87 | @wrap_nova_error | ||
1297 | 88 | def get_members(project): | ||
1298 | 89 | nova = get_nova_admin_connection() | ||
1299 | 90 | members = nova.get_project_members(project) | ||
1300 | 91 | return [str(user.memberId) for user in members] | ||
1301 | 92 | |||
1302 | 93 | @wrap_nova_error | ||
1303 | 94 | def set_project_roles(projectname, username, roles): | ||
1304 | 95 | nova = get_nova_admin_connection() | ||
1305 | 96 | # hacky work around to interface correctly with multiple select form | ||
1306 | 97 | _remove_roles(projectname, username) | ||
1307 | 98 | |||
1308 | 99 | for role in roles: | ||
1309 | 100 | nova.add_user_role(username, str(role), projectname) | ||
1310 | 101 | |||
1311 | 102 | def _remove_roles(project, username): | ||
1312 | 103 | nova = get_nova_admin_connection() | ||
1313 | 104 | userroles = nova.get_user_roles(username, project) | ||
1314 | 105 | roles = [str(role.role) for role in userroles] | ||
1315 | 106 | |||
1316 | 107 | for role in roles: | ||
1317 | 108 | if role == "developer": | ||
1318 | 109 | nova.remove_user_role(username, "developer", project) | ||
1319 | 110 | if role == "sysadmin": | ||
1320 | 111 | nova.remove_user_role(username, "sysadmin", project) | ||
1321 | 112 | if role == "netadmin": | ||
1322 | 113 | nova.remove_user_role(username, "netadmin", project) | ||
1323 | 114 | |||
1324 | 115 | |||
1325 | 116 | class ProjectFormBase(forms.Form): | ||
1326 | 117 | def __init__(self, project, *args, **kwargs): | ||
1327 | 118 | self.project = project | ||
1328 | 119 | super(ProjectFormBase, self).__init__(*args, **kwargs) | ||
1329 | 120 | |||
1330 | 121 | |||
1331 | 122 | class LaunchInstanceForm(forms.Form): | ||
1332 | 123 | # nickname = forms.CharField() | ||
1333 | 124 | # description = forms.CharField() | ||
1334 | 125 | |||
1335 | 126 | count = forms.ChoiceField(choices=[(x, x) for x in range(1, 6)]) | ||
1336 | 127 | size = forms.ChoiceField() | ||
1337 | 128 | key_name = forms.ChoiceField() | ||
1338 | 129 | #security_group = forms.ChoiceField() | ||
1339 | 130 | user_data = forms.CharField(required=False, widget=forms.widgets.Textarea(attrs={'rows': 4})) | ||
1340 | 131 | |||
1341 | 132 | def __init__(self, project, *args, **kwargs): | ||
1342 | 133 | forms.Form.__init__(self, *args, **kwargs) | ||
1343 | 134 | #self.fields['security_group'].choices = get_security_group_choices(project) | ||
1344 | 135 | self.fields['key_name'].choices = get_key_pair_choices(project) | ||
1345 | 136 | self.fields['size'].choices = get_instance_type_choices() | ||
1346 | 137 | |||
1347 | 138 | |||
1348 | 139 | class UpdateInstanceForm(forms.Form): | ||
1349 | 140 | nickname = forms.CharField(required=False, label="Name") | ||
1350 | 141 | description = forms.CharField(required=False, widget=forms.Textarea, max_length=70) | ||
1351 | 142 | |||
1352 | 143 | def __init__(self, instance, *args, **kwargs): | ||
1353 | 144 | forms.Form.__init__(self, *args, **kwargs) | ||
1354 | 145 | self.fields['nickname'].initial = instance.displayName | ||
1355 | 146 | self.fields['description'].initial = instance.displayDescription | ||
1356 | 147 | |||
1357 | 148 | |||
1358 | 149 | class UpdateImageForm(forms.Form): | ||
1359 | 150 | nickname = forms.CharField(required=False, label="Name") | ||
1360 | 151 | description = forms.CharField(required=False, widget=forms.Textarea, max_length=70) | ||
1361 | 152 | |||
1362 | 153 | def __init__(self, image, *args, **kwargs): | ||
1363 | 154 | forms.Form.__init__(self, *args, **kwargs) | ||
1364 | 155 | self.fields['nickname'].initial = image.displayName | ||
1365 | 156 | self.fields['description'].initial = image.description | ||
1366 | 157 | |||
1367 | 158 | |||
1368 | 159 | class CreateKeyPairForm(ProjectFormBase): | ||
1369 | 160 | name = forms.RegexField(regex=alphanumeric_re) | ||
1370 | 161 | |||
1371 | 162 | def clean_name(self): | ||
1372 | 163 | name = self.cleaned_data['name'] | ||
1373 | 164 | |||
1374 | 165 | if self.project.has_key_pair(name): | ||
1375 | 166 | raise forms.ValidationError('A key named %s already exists.' % name) | ||
1376 | 167 | |||
1377 | 168 | return name | ||
1378 | 169 | |||
1379 | 170 | |||
1380 | 171 | class CreateSecurityGroupForm(ProjectFormBase): | ||
1381 | 172 | name = forms.RegexField(regex=alphanumeric_re) | ||
1382 | 173 | description = forms.CharField() | ||
1383 | 174 | |||
1384 | 175 | def clean_name(self): | ||
1385 | 176 | name = self.cleaned_data['name'] | ||
1386 | 177 | |||
1387 | 178 | if self.project.has_security_group(name): | ||
1388 | 179 | raise forms.ValidationError('A security group named %s already exists.' % name) | ||
1389 | 180 | |||
1390 | 181 | return name | ||
1391 | 182 | |||
1392 | 183 | |||
1393 | 184 | class AuthorizeSecurityGroupRuleForm(forms.Form): | ||
1394 | 185 | protocol = forms.ChoiceField(choices=get_protocols()) | ||
1395 | 186 | from_port = forms.IntegerField(min_value=1, max_value=65535) | ||
1396 | 187 | to_port = forms.IntegerField(min_value=1, max_value=65535) | ||
1397 | 188 | |||
1398 | 189 | |||
1399 | 190 | class CreateVolumeForm(forms.Form): | ||
1400 | 191 | size = forms.IntegerField(label='Size (in GB)', min_value=1, max_value=MAX_VOLUME_SIZE) | ||
1401 | 192 | nickname = forms.CharField() | ||
1402 | 193 | description = forms.CharField() | ||
1403 | 194 | |||
1404 | 195 | |||
1405 | 196 | class AttachVolumeForm(ProjectFormBase): | ||
1406 | 197 | volume = forms.ChoiceField() | ||
1407 | 198 | instance = forms.ChoiceField() | ||
1408 | 199 | device = forms.CharField(initial='/dev/vdb') | ||
1409 | 200 | |||
1410 | 201 | def __init__(self, project, *args, **kwargs): | ||
1411 | 202 | super(AttachVolumeForm, self).__init__(project, *args, **kwargs) | ||
1412 | 203 | self.fields['volume'].choices = get_available_volume_choices(project) | ||
1413 | 204 | self.fields['instance'].choices = get_instance_choices(project) | ||
1414 | 205 | |||
1415 | 206 | |||
1416 | 207 | class ProjectForm(forms.Form): | ||
1417 | 208 | projectname = forms.CharField(label="Project Name", max_length=20) | ||
1418 | 209 | description = forms.CharField(label="Description", | ||
1419 | 210 | widget=forms.widgets.Textarea()) | ||
1420 | 211 | manager = forms.ModelChoiceField(queryset=auth_models.User.objects.all(), | ||
1421 | 212 | label="Project Manager") | ||
1422 | 213 | |||
1423 | 214 | |||
1424 | 215 | class GlobalRolesForm(forms.Form): | ||
1425 | 216 | role = forms.MultipleChoiceField(label='Roles', required=False) | ||
1426 | 217 | |||
1427 | 218 | def __init__(self, *args, **kwargs): | ||
1428 | 219 | super(GlobalRolesForm, self).__init__(*args, **kwargs) | ||
1429 | 220 | self.fields['role'].choices = get_roles(project_roles=False) | ||
1430 | 221 | |||
1431 | 222 | |||
1432 | 223 | class ProjectUserForm(forms.Form): | ||
1433 | 224 | role = forms.MultipleChoiceField(label='Roles', required=False) | ||
1434 | 225 | |||
1435 | 226 | def __init__(self, project, user, *args, **kwargs): | ||
1436 | 227 | super(ProjectUserForm, self).__init__(*args, **kwargs) | ||
1437 | 228 | self.project = project | ||
1438 | 229 | self.user = user | ||
1439 | 230 | self.fields['role'].choices = get_roles() | ||
1440 | 231 | |||
1441 | 232 | def save(self): | ||
1442 | 233 | set_project_roles(self.project.projectname, | ||
1443 | 234 | self.user.username, | ||
1444 | 235 | self.cleaned_data['role']) | ||
1445 | 236 | |||
1446 | 237 | |||
1447 | 238 | class AddProjectUserForm(forms.Form): | ||
1448 | 239 | username = forms.ModelChoiceField(queryset='', | ||
1449 | 240 | label='Username', | ||
1450 | 241 | empty_label='Select a Username') | ||
1451 | 242 | role = forms.MultipleChoiceField(label='Roles') | ||
1452 | 243 | |||
1453 | 244 | def __init__(self, *args, **kwargs): | ||
1454 | 245 | project = kwargs.pop('project') | ||
1455 | 246 | super(AddProjectUserForm, self).__init__(*args, **kwargs) | ||
1456 | 247 | members = get_members(project) | ||
1457 | 248 | |||
1458 | 249 | self.fields['username'].queryset = \ | ||
1459 | 250 | auth_models.User.objects.exclude(username__in=members) | ||
1460 | 251 | self.fields['role'].choices = get_roles() | ||
1461 | 252 | |||
1462 | 253 | |||
1463 | 254 | class SendCredentialsForm(forms.Form): | ||
1464 | 255 | users = forms.MultipleChoiceField(label='Users', required=True) | ||
1465 | 256 | |||
1466 | 257 | def __init__(self, *args, **kwargs): | ||
1467 | 258 | query_list = kwargs.pop('query_list') | ||
1468 | 259 | super(SendCredentialsForm, self).__init__(*args, **kwargs) | ||
1469 | 260 | |||
1470 | 261 | self.fields['users'].choices = [(choices, choices) for choices in query_list] | ||
1471 | 262 | |||
1472 | 263 | 0 | ||
1473 | === removed directory 'src/django_nova/management' | |||
1474 | === removed file 'src/django_nova/management/__init__.py' | |||
1475 | === removed directory 'src/django_nova/management/commands' | |||
1476 | === removed file 'src/django_nova/management/commands/__init__.py' | |||
1477 | === removed file 'src/django_nova/management/commands/createnovausers.py' | |||
1478 | --- src/django_nova/management/commands/createnovausers.py 2011-01-12 20:02:06 +0000 | |||
1479 | +++ src/django_nova/management/commands/createnovausers.py 1970-01-01 00:00:00 +0000 | |||
1480 | @@ -1,37 +0,0 @@ | |||
1481 | 1 | # vim: tabstop=4 shiftwidth=4 softtabstop=4 | ||
1482 | 2 | |||
1483 | 3 | # Copyright 2010 United States Government as represented by the | ||
1484 | 4 | # Administrator of the National Aeronautics and Space Administration. | ||
1485 | 5 | # All Rights Reserved. | ||
1486 | 6 | # | ||
1487 | 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | ||
1488 | 8 | # not use this file except in compliance with the License. You may obtain | ||
1489 | 9 | # a copy of the License at | ||
1490 | 10 | # | ||
1491 | 11 | # http://www.apache.org/licenses/LICENSE-2.0 | ||
1492 | 12 | # | ||
1493 | 13 | # Unless required by applicable law or agreed to in writing, software | ||
1494 | 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
1495 | 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
1496 | 16 | # License for the specific language governing permissions and limitations | ||
1497 | 17 | # under the License. | ||
1498 | 18 | """ | ||
1499 | 19 | Management commands for synchronizing the Django auth database and Nova | ||
1500 | 20 | users database. | ||
1501 | 21 | """ | ||
1502 | 22 | |||
1503 | 23 | from django.core.management.base import NoArgsCommand | ||
1504 | 24 | from django.contrib.auth.models import User | ||
1505 | 25 | from django_nova.connection import get_nova_admin_connection | ||
1506 | 26 | |||
1507 | 27 | class Command(NoArgsCommand): | ||
1508 | 28 | help = 'Creates nova users for all users in the django auth database.' | ||
1509 | 29 | |||
1510 | 30 | def handle_noargs(self, **options): | ||
1511 | 31 | nova = get_nova_admin_connection() | ||
1512 | 32 | users = User.objects.all() | ||
1513 | 33 | for user in users: | ||
1514 | 34 | if not nova.has_user(user.username): | ||
1515 | 35 | self.stdout.write('creating user %s... ' % user.username) | ||
1516 | 36 | nova.create_user(user.username) | ||
1517 | 37 | self.stdout.write('ok\n') | ||
1518 | 38 | 0 | ||
1519 | === removed file 'src/django_nova/manager.py' | |||
1520 | --- src/django_nova/manager.py 2011-01-24 00:02:34 +0000 | |||
1521 | +++ src/django_nova/manager.py 1970-01-01 00:00:00 +0000 | |||
1522 | @@ -1,340 +0,0 @@ | |||
1523 | 1 | # vim: tabstop=4 shiftwidth=4 softtabstop=4 | ||
1524 | 2 | |||
1525 | 3 | # Copyright 2010 United States Government as represented by the | ||
1526 | 4 | # Administrator of the National Aeronautics and Space Administration. | ||
1527 | 5 | # All Rights Reserved. | ||
1528 | 6 | # | ||
1529 | 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | ||
1530 | 8 | # not use this file except in compliance with the License. You may obtain | ||
1531 | 9 | # a copy of the License at | ||
1532 | 10 | # | ||
1533 | 11 | # http://www.apache.org/licenses/LICENSE-2.0 | ||
1534 | 12 | # | ||
1535 | 13 | # Unless required by applicable law or agreed to in writing, software | ||
1536 | 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
1537 | 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
1538 | 16 | # License for the specific language governing permissions and limitations | ||
1539 | 17 | # under the License. | ||
1540 | 18 | """ | ||
1541 | 19 | Simple API for interacting with Nova projects. | ||
1542 | 20 | """ | ||
1543 | 21 | |||
1544 | 22 | import boto | ||
1545 | 23 | import boto.ec2.volume | ||
1546 | 24 | import boto.exception | ||
1547 | 25 | import boto.s3 | ||
1548 | 26 | from django.conf import settings | ||
1549 | 27 | from django_nova.connection import get_nova_admin_connection | ||
1550 | 28 | from django_nova.exceptions import wrap_nova_error | ||
1551 | 29 | |||
1552 | 30 | |||
1553 | 31 | class ProjectManager(object): | ||
1554 | 32 | def __init__(self, username, project, region): | ||
1555 | 33 | self.username = username | ||
1556 | 34 | self.projectname = project.projectname | ||
1557 | 35 | self.projectManagerId = project.projectManagerId | ||
1558 | 36 | self.region = region | ||
1559 | 37 | |||
1560 | 38 | def get_nova_connection(self): | ||
1561 | 39 | """ | ||
1562 | 40 | Returns a boto connection for a user's project. | ||
1563 | 41 | """ | ||
1564 | 42 | nova = get_nova_admin_connection() | ||
1565 | 43 | return nova.connection_for(self.username, | ||
1566 | 44 | self.projectname, | ||
1567 | 45 | clc_url=self.region['endpoint'], | ||
1568 | 46 | region=self.region['name']) | ||
1569 | 47 | |||
1570 | 48 | def get_zip(self): | ||
1571 | 49 | """ | ||
1572 | 50 | Returns a buffer of a zip file containing signed credentials | ||
1573 | 51 | for the project's Nova user. | ||
1574 | 52 | """ | ||
1575 | 53 | nova = get_nova_admin_connection() | ||
1576 | 54 | return nova.get_zip(self.username, self.projectname) | ||
1577 | 55 | |||
1578 | 56 | def get_images(self, image_ids=None): | ||
1579 | 57 | conn = self.get_nova_connection() | ||
1580 | 58 | images = conn.get_all_images(image_ids=image_ids) | ||
1581 | 59 | sorted_images = [i for i in images if i.ownerId == self.username] + \ | ||
1582 | 60 | [i for i in images if i.ownerId != self.username] | ||
1583 | 61 | |||
1584 | 62 | return [i for i in sorted_images if i.type == 'machine' and i.location.split('/')[0] != 'nova'] | ||
1585 | 63 | |||
1586 | 64 | def get_image(self, image_id): | ||
1587 | 65 | try: | ||
1588 | 66 | return self.get_images(image_ids=[image_id,])[0] | ||
1589 | 67 | except IndexError: | ||
1590 | 68 | return None | ||
1591 | 69 | |||
1592 | 70 | @wrap_nova_error | ||
1593 | 71 | def deregister_image(self, image_id): | ||
1594 | 72 | """ | ||
1595 | 73 | Removes the image's listing but leaves the image | ||
1596 | 74 | and manifest in the object store in tact. | ||
1597 | 75 | """ | ||
1598 | 76 | conn = self.get_nova_connection() | ||
1599 | 77 | return conn.deregister_image(image_id) | ||
1600 | 78 | |||
1601 | 79 | @wrap_nova_error | ||
1602 | 80 | def update_image(self, image_id, display_name=None, description=None): | ||
1603 | 81 | conn = self.get_nova_connection() | ||
1604 | 82 | params = { | ||
1605 | 83 | 'ImageId': image_id, | ||
1606 | 84 | 'DisplayName': display_name, | ||
1607 | 85 | 'Description': description | ||
1608 | 86 | } | ||
1609 | 87 | return conn.get_object('UpdateImage', params, boto.ec2.image.Image) | ||
1610 | 88 | |||
1611 | 89 | @wrap_nova_error | ||
1612 | 90 | def modify_image_attribute(self, image_id, attribute=None, operation=None, | ||
1613 | 91 | groups='all'): | ||
1614 | 92 | conn = self.get_nova_connection() | ||
1615 | 93 | return conn.modify_image_attribute(image_id, | ||
1616 | 94 | attribute='launchPermission', | ||
1617 | 95 | operation='remove', | ||
1618 | 96 | groups='all',) | ||
1619 | 97 | |||
1620 | 98 | |||
1621 | 99 | @wrap_nova_error | ||
1622 | 100 | def run_instances(self, image_id, **kwargs): | ||
1623 | 101 | """ | ||
1624 | 102 | Runs instances of the specified image id. | ||
1625 | 103 | """ | ||
1626 | 104 | conn = self.get_nova_connection() | ||
1627 | 105 | return conn.run_instances(image_id, **kwargs) | ||
1628 | 106 | |||
1629 | 107 | def get_instance_count(self): | ||
1630 | 108 | """ | ||
1631 | 109 | Returns the number of active instances in this project or None if unknown. | ||
1632 | 110 | """ | ||
1633 | 111 | try: | ||
1634 | 112 | return len(self.get_instances()) | ||
1635 | 113 | except: | ||
1636 | 114 | return None | ||
1637 | 115 | |||
1638 | 116 | @wrap_nova_error | ||
1639 | 117 | def get_instances(self): | ||
1640 | 118 | """ | ||
1641 | 119 | Returns all instances in this project. | ||
1642 | 120 | """ | ||
1643 | 121 | conn = self.get_nova_connection() | ||
1644 | 122 | reservations = conn.get_all_instances() | ||
1645 | 123 | instances = [] | ||
1646 | 124 | for reservation in reservations: | ||
1647 | 125 | for instance in reservation.instances: | ||
1648 | 126 | instances.append(instance) | ||
1649 | 127 | return instances | ||
1650 | 128 | |||
1651 | 129 | @wrap_nova_error | ||
1652 | 130 | def get_instance(self, instance_id): | ||
1653 | 131 | """ | ||
1654 | 132 | Returns detail about the specified instance. | ||
1655 | 133 | """ | ||
1656 | 134 | conn = self.get_nova_connection() | ||
1657 | 135 | # TODO: Refactor this once nova's describe_instances filters by instance_id. | ||
1658 | 136 | reservations = conn.get_all_instances() | ||
1659 | 137 | for reservation in reservations: | ||
1660 | 138 | for instance in reservation.instances: | ||
1661 | 139 | if instance.id == instance_id: | ||
1662 | 140 | return instance | ||
1663 | 141 | return None | ||
1664 | 142 | |||
1665 | 143 | @wrap_nova_error | ||
1666 | 144 | def update_instance(self, instance_id, updates): | ||
1667 | 145 | conn = self.get_nova_connection() | ||
1668 | 146 | params = {'InstanceId': instance_id, 'DisplayName': updates['nickname'], | ||
1669 | 147 | 'DisplayDescription': updates['description']} | ||
1670 | 148 | return conn.get_object('UpdateInstance', params, | ||
1671 | 149 | boto.ec2.instance.Instance) | ||
1672 | 150 | |||
1673 | 151 | def get_instance_graph(self, region, instance_id, graph_name): | ||
1674 | 152 | # TODO(devcamcar): Need better support for multiple regions. | ||
1675 | 153 | # Need a way to get object store by region. | ||
1676 | 154 | s3 = boto.s3.connection.S3Connection ( | ||
1677 | 155 | aws_access_key_id=settings.NOVA_ACCESS_KEY, | ||
1678 | 156 | aws_secret_access_key=settings.NOVA_SECRET_KEY, | ||
1679 | 157 | is_secure=False, | ||
1680 | 158 | calling_format=boto.s3.connection.OrdinaryCallingFormat(), | ||
1681 | 159 | port=3333, | ||
1682 | 160 | host=settings.NOVA_CLC_IP | ||
1683 | 161 | ) | ||
1684 | 162 | key = '_%s.monitor' % instance_id | ||
1685 | 163 | |||
1686 | 164 | try: | ||
1687 | 165 | bucket = s3.get_bucket(key, validate=False) | ||
1688 | 166 | except boto.exception.S3ResponseError, e: | ||
1689 | 167 | if e.code == "NoSuchBucket": | ||
1690 | 168 | return None | ||
1691 | 169 | else: | ||
1692 | 170 | raise e | ||
1693 | 171 | |||
1694 | 172 | key = bucket.get_key(graph_name) | ||
1695 | 173 | |||
1696 | 174 | return key.read() | ||
1697 | 175 | |||
1698 | 176 | @wrap_nova_error | ||
1699 | 177 | def terminate_instance(self, instance_id): | ||
1700 | 178 | """ Terminates the specified instance within this project. """ | ||
1701 | 179 | conn = self.get_nova_connection() | ||
1702 | 180 | conn.terminate_instances([instance_id]) | ||
1703 | 181 | |||
1704 | 182 | @wrap_nova_error | ||
1705 | 183 | def get_security_groups(self): | ||
1706 | 184 | """ | ||
1707 | 185 | Returns all security groups associated with this project. | ||
1708 | 186 | """ | ||
1709 | 187 | conn = self.get_nova_connection() | ||
1710 | 188 | groups = [] | ||
1711 | 189 | |||
1712 | 190 | for g in conn.get_all_security_groups(): | ||
1713 | 191 | # Do not show vpn group. | ||
1714 | 192 | #if g.name != 'vpn-secgroup': | ||
1715 | 193 | groups.append(g) | ||
1716 | 194 | |||
1717 | 195 | return groups | ||
1718 | 196 | |||
1719 | 197 | @wrap_nova_error | ||
1720 | 198 | def get_security_group(self, name): | ||
1721 | 199 | """ | ||
1722 | 200 | Returns the specified security group for this project. | ||
1723 | 201 | """ | ||
1724 | 202 | conn = self.get_nova_connection() | ||
1725 | 203 | |||
1726 | 204 | try: | ||
1727 | 205 | return conn.get_all_security_groups(groupnames=name.encode('ASCII'))[0] | ||
1728 | 206 | except IndexError: | ||
1729 | 207 | return None | ||
1730 | 208 | |||
1731 | 209 | @wrap_nova_error | ||
1732 | 210 | def has_security_group(self, name): | ||
1733 | 211 | """ | ||
1734 | 212 | Indicates whether a security group with the specified name exists in this project. | ||
1735 | 213 | """ | ||
1736 | 214 | return self.get_security_group(name) is not None | ||
1737 | 215 | |||
1738 | 216 | @wrap_nova_error | ||
1739 | 217 | def create_security_group(self, name, description): | ||
1740 | 218 | """ | ||
1741 | 219 | Creates a new security group in this project. | ||
1742 | 220 | """ | ||
1743 | 221 | conn = self.get_nova_connection() | ||
1744 | 222 | return conn.create_security_group(name, description) | ||
1745 | 223 | |||
1746 | 224 | @wrap_nova_error | ||
1747 | 225 | def delete_security_group(self, name): | ||
1748 | 226 | """ | ||
1749 | 227 | Deletes a security group from the project. | ||
1750 | 228 | """ | ||
1751 | 229 | conn = self.get_nova_connection() | ||
1752 | 230 | return conn.delete_security_group(name = name) | ||
1753 | 231 | |||
1754 | 232 | @wrap_nova_error | ||
1755 | 233 | def authorize_security_group(self, group_name, ip_protocol, from_port, to_port): | ||
1756 | 234 | """ | ||
1757 | 235 | Authorizes a rule for the specified security group. | ||
1758 | 236 | """ | ||
1759 | 237 | conn = self.get_nova_connection() | ||
1760 | 238 | return conn.authorize_security_group ( | ||
1761 | 239 | group_name = group_name, | ||
1762 | 240 | ip_protocol = ip_protocol, | ||
1763 | 241 | from_port = from_port, | ||
1764 | 242 | to_port = to_port, | ||
1765 | 243 | cidr_ip = '0.0.0.0/0' | ||
1766 | 244 | ) | ||
1767 | 245 | |||
1768 | 246 | @wrap_nova_error | ||
1769 | 247 | def revoke_security_group(self, group_name, ip_protocol, from_port, to_port): | ||
1770 | 248 | """ | ||
1771 | 249 | Revokes a rule for the specified security group. | ||
1772 | 250 | """ | ||
1773 | 251 | conn = self.get_nova_connection() | ||
1774 | 252 | return conn.revoke_security_group ( | ||
1775 | 253 | group_name = group_name, | ||
1776 | 254 | ip_protocol = ip_protocol, | ||
1777 | 255 | from_port = from_port, | ||
1778 | 256 | to_port = to_port, | ||
1779 | 257 | cidr_ip = '0.0.0.0/0' | ||
1780 | 258 | ) | ||
1781 | 259 | |||
1782 | 260 | @wrap_nova_error | ||
1783 | 261 | def get_key_pairs(self): | ||
1784 | 262 | """ | ||
1785 | 263 | Returns all key pairs associated with this project. | ||
1786 | 264 | """ | ||
1787 | 265 | conn = self.get_nova_connection() | ||
1788 | 266 | keys = [] | ||
1789 | 267 | |||
1790 | 268 | for k in conn.get_all_key_pairs(): | ||
1791 | 269 | # Do not show vpn key. | ||
1792 | 270 | if k.name != 'vpn-key': | ||
1793 | 271 | keys.append(k) | ||
1794 | 272 | |||
1795 | 273 | return keys | ||
1796 | 274 | |||
1797 | 275 | @wrap_nova_error | ||
1798 | 276 | def get_key_pair(self, name): | ||
1799 | 277 | """ | ||
1800 | 278 | Returns the specified security group for this project. | ||
1801 | 279 | """ | ||
1802 | 280 | conn = self.get_nova_connection() | ||
1803 | 281 | |||
1804 | 282 | try: | ||
1805 | 283 | return conn.get_all_key_pairs(keynames=name.encode('ASCII'))[0] | ||
1806 | 284 | except IndexError: | ||
1807 | 285 | return None | ||
1808 | 286 | |||
1809 | 287 | @wrap_nova_error | ||
1810 | 288 | def has_key_pair(self, name): | ||
1811 | 289 | """ | ||
1812 | 290 | Indicates whether a key pair with the specified name exists in this project. | ||
1813 | 291 | """ | ||
1814 | 292 | return self.get_key_pair(name) != None | ||
1815 | 293 | |||
1816 | 294 | @wrap_nova_error | ||
1817 | 295 | def create_key_pair(self, name): | ||
1818 | 296 | """ | ||
1819 | 297 | Creates a new key pair for this project. | ||
1820 | 298 | """ | ||
1821 | 299 | conn = self.get_nova_connection() | ||
1822 | 300 | return conn.create_key_pair(name) | ||
1823 | 301 | |||
1824 | 302 | @wrap_nova_error | ||
1825 | 303 | def delete_key_pair(self, name): | ||
1826 | 304 | """ | ||
1827 | 305 | Deletes a new key pair from this project. | ||
1828 | 306 | """ | ||
1829 | 307 | conn = self.get_nova_connection() | ||
1830 | 308 | conn.delete_key_pair(name) | ||
1831 | 309 | |||
1832 | 310 | @wrap_nova_error | ||
1833 | 311 | def get_volumes(self): | ||
1834 | 312 | """ | ||
1835 | 313 | Returns all volumes in this project. | ||
1836 | 314 | """ | ||
1837 | 315 | conn = self.get_nova_connection() | ||
1838 | 316 | return conn.get_all_volumes() | ||
1839 | 317 | |||
1840 | 318 | @wrap_nova_error | ||
1841 | 319 | def create_volume(self, size, display_name=None, display_description=None, | ||
1842 | 320 | snapshot=None): | ||
1843 | 321 | conn = self.get_nova_connection() | ||
1844 | 322 | params = {'Size': size, 'DisplayName': display_name, | ||
1845 | 323 | 'DisplayDescription': display_description} | ||
1846 | 324 | return conn.get_object('CreateVolume', params, boto.ec2.volume.Volume) | ||
1847 | 325 | |||
1848 | 326 | @wrap_nova_error | ||
1849 | 327 | def delete_volume(self, volume_id): | ||
1850 | 328 | conn = self.get_nova_connection() | ||
1851 | 329 | return conn.delete_volume(volume_id) | ||
1852 | 330 | |||
1853 | 331 | @wrap_nova_error | ||
1854 | 332 | def attach_volume(self, volume_id, instance_id, device): | ||
1855 | 333 | conn = self.get_nova_connection() | ||
1856 | 334 | return conn.attach_volume(volume_id, instance_id, device) | ||
1857 | 335 | |||
1858 | 336 | @wrap_nova_error | ||
1859 | 337 | def detach_volume(self, volume_id): | ||
1860 | 338 | conn = self.get_nova_connection() | ||
1861 | 339 | return conn.detach_volume(volume_id) | ||
1862 | 340 | |||
1863 | 341 | 0 | ||
1864 | === removed file 'src/django_nova/models.py' | |||
1865 | --- src/django_nova/models.py 2011-01-15 11:26:01 +0000 | |||
1866 | +++ src/django_nova/models.py 1970-01-01 00:00:00 +0000 | |||
1867 | @@ -1,121 +0,0 @@ | |||
1868 | 1 | # vim: tabstop=4 shiftwidth=4 softtabstop=4 | ||
1869 | 2 | |||
1870 | 3 | # Copyright 2010 United States Government as represented by the | ||
1871 | 4 | # Administrator of the National Aeronautics and Space Administration. | ||
1872 | 5 | # All Rights Reserved. | ||
1873 | 6 | # | ||
1874 | 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | ||
1875 | 8 | # not use this file except in compliance with the License. You may obtain | ||
1876 | 9 | # a copy of the License at | ||
1877 | 10 | # | ||
1878 | 11 | # http://www.apache.org/licenses/LICENSE-2.0 | ||
1879 | 12 | # | ||
1880 | 13 | # Unless required by applicable law or agreed to in writing, software | ||
1881 | 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
1882 | 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
1883 | 16 | # License for the specific language governing permissions and limitations | ||
1884 | 17 | # under the License. | ||
1885 | 18 | """ | ||
1886 | 19 | Database models for authorization credentials and synchronizing Nova users. | ||
1887 | 20 | """ | ||
1888 | 21 | |||
1889 | 22 | import datetime | ||
1890 | 23 | import random | ||
1891 | 24 | import re | ||
1892 | 25 | import sha | ||
1893 | 26 | from django.conf import settings | ||
1894 | 27 | from django.contrib.auth import models as auth_models | ||
1895 | 28 | from django.contrib.sites import models as site_models | ||
1896 | 29 | from django.core import mail | ||
1897 | 30 | from django.db import models | ||
1898 | 31 | from django.db.models.signals import post_save | ||
1899 | 32 | from django.template.loader import render_to_string | ||
1900 | 33 | from django_nova.connection import get_nova_admin_connection | ||
1901 | 34 | |||
1902 | 35 | |||
1903 | 36 | SHA1_RE=re.compile('^[a-f0-9]{40}$') | ||
1904 | 37 | |||
1905 | 38 | |||
1906 | 39 | class CredentialsAuthorization(models.Model): | ||
1907 | 40 | username = models.CharField(max_length=128) | ||
1908 | 41 | project = models.CharField(max_length=128) | ||
1909 | 42 | auth_token = models.CharField(max_length=40) | ||
1910 | 43 | auth_date = models.DateTimeField(auto_now_add=True) | ||
1911 | 44 | |||
1912 | 45 | def __str__(self): | ||
1913 | 46 | return '%s/%s:%s' % (self.username, self.project, self.auth_token) | ||
1914 | 47 | |||
1915 | 48 | @classmethod | ||
1916 | 49 | def get_by_token(cls, token): | ||
1917 | 50 | if SHA1_RE.search(token): | ||
1918 | 51 | try: | ||
1919 | 52 | credentials = cls.objects.get(auth_token=token) | ||
1920 | 53 | except cls.DoesNotExist: | ||
1921 | 54 | return None | ||
1922 | 55 | if not credentials.auth_token_expired(): | ||
1923 | 56 | return credentials | ||
1924 | 57 | return None | ||
1925 | 58 | |||
1926 | 59 | @classmethod | ||
1927 | 60 | def authorize(cls, username, project): | ||
1928 | 61 | return cls.objects.create(username=username, | ||
1929 | 62 | project=project, | ||
1930 | 63 | auth_token=cls.create_auth_token(username)) | ||
1931 | 64 | |||
1932 | 65 | @staticmethod | ||
1933 | 66 | def create_auth_token(username): | ||
1934 | 67 | salt = sha.new(str(random.random())).hexdigest()[:5] | ||
1935 | 68 | return sha.new(salt+username).hexdigest() | ||
1936 | 69 | |||
1937 | 70 | def auth_token_expired(self): | ||
1938 | 71 | expiration_date = datetime.timedelta(days=int(settings.CREDENTIAL_AUTHORIZATION_DAYS)) | ||
1939 | 72 | |||
1940 | 73 | return self.auth_date + expiration_date <= datetime.datetime.now() | ||
1941 | 74 | |||
1942 | 75 | def get_download_url(self): | ||
1943 | 76 | return settings.CREDENTIAL_DOWNLOAD_URL + self.auth_token | ||
1944 | 77 | |||
1945 | 78 | def get_zip(self): | ||
1946 | 79 | nova = get_nova_admin_connection() | ||
1947 | 80 | self.delete() | ||
1948 | 81 | return nova.get_zip(self.username, self.project) | ||
1949 | 82 | |||
1950 | 83 | |||
1951 | 84 | def credentials_post_save(sender, instance, created, *args, **kwargs): | ||
1952 | 85 | """ | ||
1953 | 86 | Creates a Nova User when a new Django User is created. | ||
1954 | 87 | """ | ||
1955 | 88 | if created: | ||
1956 | 89 | site = site_models.Site.objects.get_current() | ||
1957 | 90 | user = auth_models.User.objects.get(username=instance.username) | ||
1958 | 91 | context = { | ||
1959 | 92 | 'user': user, | ||
1960 | 93 | 'download_url': instance.get_download_url(), | ||
1961 | 94 | 'dashboard_url': 'http://%s/' % site.domain | ||
1962 | 95 | } | ||
1963 | 96 | subject = render_to_string('credentials/credentials_email_subject.txt') | ||
1964 | 97 | body = render_to_string('credentials/credentials_email.txt', context) | ||
1965 | 98 | |||
1966 | 99 | message = mail.EmailMessage(subject=subject, body=body, to=[user.email]) | ||
1967 | 100 | message.send(fail_silently=False) | ||
1968 | 101 | post_save.connect(credentials_post_save, | ||
1969 | 102 | CredentialsAuthorization, | ||
1970 | 103 | dispatch_uid='django_nova.CredentialsAuthorization.post_save') | ||
1971 | 104 | |||
1972 | 105 | |||
1973 | 106 | def user_post_save(sender, instance, created, *args, **kwargs): | ||
1974 | 107 | """ | ||
1975 | 108 | Creates a Nova User when a new Django User is created. | ||
1976 | 109 | """ | ||
1977 | 110 | |||
1978 | 111 | # NOTE(devcamcar): If running unit tests, don't use a real endpoint. | ||
1979 | 112 | if settings.NOVA_DEFAULT_ENDPOINT == 'none': | ||
1980 | 113 | return | ||
1981 | 114 | |||
1982 | 115 | if created: | ||
1983 | 116 | nova = get_nova_admin_connection() | ||
1984 | 117 | if not nova.has_user(instance.username): | ||
1985 | 118 | nova.create_user(instance.username) | ||
1986 | 119 | post_save.connect(user_post_save, | ||
1987 | 120 | auth_models.User, | ||
1988 | 121 | dispatch_uid='django_nova.User.post_save') | ||
1989 | 122 | 0 | ||
1990 | === removed file 'src/django_nova/shortcuts.py' | |||
1991 | --- src/django_nova/shortcuts.py 2011-01-31 20:24:02 +0000 | |||
1992 | +++ src/django_nova/shortcuts.py 1970-01-01 00:00:00 +0000 | |||
1993 | @@ -1,131 +0,0 @@ | |||
1994 | 1 | # vim: tabstop=4 shiftwidth=4 softtabstop=4 | ||
1995 | 2 | |||
1996 | 3 | # Copyright 2010 United States Government as represented by the | ||
1997 | 4 | # Administrator of the National Aeronautics and Space Administration. | ||
1998 | 5 | # All Rights Reserved. | ||
1999 | 6 | # | ||
2000 | 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | ||
2001 | 8 | # not use this file except in compliance with the License. You may obtain | ||
2002 | 9 | # a copy of the License at | ||
2003 | 10 | # | ||
2004 | 11 | # http://www.apache.org/licenses/LICENSE-2.0 | ||
2005 | 12 | # | ||
2006 | 13 | # Unless required by applicable law or agreed to in writing, software | ||
2007 | 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
2008 | 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
2009 | 16 | # License for the specific language governing permissions and limitations | ||
2010 | 17 | # under the License. | ||
2011 | 18 | |||
2012 | 19 | """ | ||
2013 | 20 | Helper methods for commonly used operations. | ||
2014 | 21 | """ | ||
2015 | 22 | |||
2016 | 23 | from django.conf import settings | ||
2017 | 24 | from django.core.cache import cache | ||
2018 | 25 | from django.core.exceptions import PermissionDenied | ||
2019 | 26 | from django.http import Http404 | ||
2020 | 27 | from django_nova import manager | ||
2021 | 28 | from django_nova.connection import get_nova_admin_connection | ||
2022 | 29 | from django_nova.exceptions import wrap_nova_error | ||
2023 | 30 | |||
2024 | 31 | |||
2025 | 32 | @wrap_nova_error | ||
2026 | 33 | def get_project_or_404(request, project_id): | ||
2027 | 34 | """ | ||
2028 | 35 | Returns a project or 404s if it doesn't exist. | ||
2029 | 36 | """ | ||
2030 | 37 | |||
2031 | 38 | # Ensure that a connection is never attempted for a user that is unauthenticated. | ||
2032 | 39 | if not request.user.is_authenticated: | ||
2033 | 40 | raise PermissionDenied('User not authenticated') | ||
2034 | 41 | |||
2035 | 42 | nova = get_nova_admin_connection() | ||
2036 | 43 | project = nova.get_project(project_id) | ||
2037 | 44 | region = get_current_region(request) | ||
2038 | 45 | |||
2039 | 46 | if not project: | ||
2040 | 47 | raise Http404('Project %s does not exist.' % project_id) | ||
2041 | 48 | |||
2042 | 49 | return manager.ProjectManager(request.user, project, region) | ||
2043 | 50 | |||
2044 | 51 | |||
2045 | 52 | @wrap_nova_error | ||
2046 | 53 | def get_projects(user): | ||
2047 | 54 | """ | ||
2048 | 55 | Returns a list of projects for a user. | ||
2049 | 56 | """ | ||
2050 | 57 | #key = 'projects.%s' % user | ||
2051 | 58 | #projects = cache.get(key) | ||
2052 | 59 | |||
2053 | 60 | #if not projects: | ||
2054 | 61 | # nova = get_nova_admin_connection() | ||
2055 | 62 | # projects = nova.get_projects(user=user) | ||
2056 | 63 | # cache.set(key, projects, 30) | ||
2057 | 64 | |||
2058 | 65 | #return projects | ||
2059 | 66 | nova = get_nova_admin_connection() | ||
2060 | 67 | return nova.get_projects(user=user) | ||
2061 | 68 | |||
2062 | 69 | |||
2063 | 70 | @wrap_nova_error | ||
2064 | 71 | def get_all_regions(): | ||
2065 | 72 | """ | ||
2066 | 73 | Returns a list of all regions. | ||
2067 | 74 | """ | ||
2068 | 75 | regions = cache.get('regions') | ||
2069 | 76 | |||
2070 | 77 | if not regions: | ||
2071 | 78 | nova = get_nova_admin_connection() | ||
2072 | 79 | conn = nova.connection_for(settings.NOVA_ADMIN_USER, settings.NOVA_PROJECT) | ||
2073 | 80 | results = conn.get_all_regions() | ||
2074 | 81 | regions = [{'name': r.name, 'endpoint': r.endpoint} for r in results] | ||
2075 | 82 | cache.set('regions', regions, 60 * 60 * 24) | ||
2076 | 83 | |||
2077 | 84 | return regions | ||
2078 | 85 | |||
2079 | 86 | |||
2080 | 87 | def get_region(region_name): | ||
2081 | 88 | regions = get_all_regions() | ||
2082 | 89 | try: | ||
2083 | 90 | return [r for r in regions if r['name'] == region_name][0] | ||
2084 | 91 | except IndexError: | ||
2085 | 92 | return None | ||
2086 | 93 | |||
2087 | 94 | |||
2088 | 95 | def get_current_region(request): | ||
2089 | 96 | """ | ||
2090 | 97 | Returns the currently selected region for a user. | ||
2091 | 98 | """ | ||
2092 | 99 | region_name = request.session.get('region', settings.NOVA_DEFAULT_REGION) | ||
2093 | 100 | return get_region(region_name) | ||
2094 | 101 | |||
2095 | 102 | |||
2096 | 103 | def set_current_region(request, region_name): | ||
2097 | 104 | """ | ||
2098 | 105 | Sets the current region selection for a user. | ||
2099 | 106 | """ | ||
2100 | 107 | request.session['region'] = region_name | ||
2101 | 108 | |||
2102 | 109 | |||
2103 | 110 | @wrap_nova_error | ||
2104 | 111 | def get_user_image_permissions(username, project_name): | ||
2105 | 112 | """ | ||
2106 | 113 | Returns true if user is a sysadmin and can modify image attributes. | ||
2107 | 114 | """ | ||
2108 | 115 | nova = get_nova_admin_connection() | ||
2109 | 116 | user_has_modify_permissions = False | ||
2110 | 117 | |||
2111 | 118 | # checks global roles, if user is a sysadmin they can modify image attribtues. | ||
2112 | 119 | if not user_has_modify_permissions: | ||
2113 | 120 | for role in nova.get_user_roles(username): | ||
2114 | 121 | if role.role == "sysadmin": | ||
2115 | 122 | user_has_modify_permissions = True | ||
2116 | 123 | |||
2117 | 124 | # checks project roles, if user is a sysadmin they can modify image attribtues. | ||
2118 | 125 | if not user_has_modify_permissions: | ||
2119 | 126 | for role in nova.get_user_roles(username, project_name): | ||
2120 | 127 | if role.role == "sysadmin": | ||
2121 | 128 | user_has_modify_permissions = True | ||
2122 | 129 | |||
2123 | 130 | return user_has_modify_permissions | ||
2124 | 131 | |||
2125 | 132 | 0 | ||
2126 | === removed directory 'src/django_nova/templates' | |||
2127 | === removed directory 'src/django_nova/templates/admin' | |||
2128 | === removed directory 'src/django_nova/templates/admin/django_nova' | |||
2129 | === removed directory 'src/django_nova/templates/admin/django_nova/project' | |||
2130 | === removed file 'src/django_nova/templates/admin/django_nova/project/add_project.html' | |||
2131 | --- src/django_nova/templates/admin/django_nova/project/add_project.html 2011-01-12 20:02:06 +0000 | |||
2132 | +++ src/django_nova/templates/admin/django_nova/project/add_project.html 1970-01-01 00:00:00 +0000 | |||
2133 | @@ -1,45 +0,0 @@ | |||
2134 | 1 | {% extends "admin/django_nova/project/base_projects.html" %} | ||
2135 | 2 | {% load admin_modify adminmedia %} | ||
2136 | 3 | |||
2137 | 4 | {% block extrahead %} | ||
2138 | 5 | {{ block.super }} | ||
2139 | 6 | {{ media }} | ||
2140 | 7 | {% endblock %} | ||
2141 | 8 | |||
2142 | 9 | {% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% admin_media_prefix %}css/forms.css" />{% endblock %} | ||
2143 | 10 | |||
2144 | 11 | {% block coltype %}colMS{% endblock %} | ||
2145 | 12 | |||
2146 | 13 | {% block bodyclass %} change-form{% endblock %} | ||
2147 | 14 | |||
2148 | 15 | {% block breadcrumbs %} | ||
2149 | 16 | <div class="breadcrumbs"> | ||
2150 | 17 | <a href="/admin">Home</a> › | ||
2151 | 18 | <a href="../../projects">Projects</a> › | ||
2152 | 19 | Add Project | ||
2153 | 20 | </div> | ||
2154 | 21 | {% endblock %} | ||
2155 | 22 | |||
2156 | 23 | {% block content %} | ||
2157 | 24 | <div id="content-main"> | ||
2158 | 25 | {% block object-tools %} | ||
2159 | 26 | {% endblock %} | ||
2160 | 27 | <form action="." method="post" enctype="multipart/form-data"> | ||
2161 | 28 | {% csrf_token %} | ||
2162 | 29 | <fieldset class="module aligned {{ fieldset.classes }}"> | ||
2163 | 30 | {% for field in form.visible_fields %} | ||
2164 | 31 | <div class="form-row"> | ||
2165 | 32 | {{ field.errors }} | ||
2166 | 33 | {{ field.label_tag }}{{ field }} | ||
2167 | 34 | {% if field.field.help_text %}<p class="help">{{ field.field.help_text|safe }}</p>{% endif %} | ||
2168 | 35 | </div> | ||
2169 | 36 | {% endfor %} | ||
2170 | 37 | {% for field in form.hidden_fields %} | ||
2171 | 38 | {{ field }} | ||
2172 | 39 | {% endfor %} | ||
2173 | 40 | |||
2174 | 41 | </fieldset> | ||
2175 | 42 | <input type="submit" value="Save" /> | ||
2176 | 43 | </form> | ||
2177 | 44 | </div> | ||
2178 | 45 | {% endblock %} | ||
2179 | 46 | 0 | ||
2180 | === removed file 'src/django_nova/templates/admin/django_nova/project/add_project_user.html' | |||
2181 | --- src/django_nova/templates/admin/django_nova/project/add_project_user.html 2011-01-12 20:02:06 +0000 | |||
2182 | +++ src/django_nova/templates/admin/django_nova/project/add_project_user.html 1970-01-01 00:00:00 +0000 | |||
2183 | @@ -1,69 +0,0 @@ | |||
2184 | 1 | {% extends "admin/django_nova/project/base_projects.html" %} | ||
2185 | 2 | {% load admin_modify adminmedia %} | ||
2186 | 3 | |||
2187 | 4 | {% block extrahead %} | ||
2188 | 5 | {{ block.super }} | ||
2189 | 6 | {{ media }} | ||
2190 | 7 | |||
2191 | 8 | <script type="text/javascript" src="/media/admin/js/jquery.min.js"></script> | ||
2192 | 9 | <script type="text/javascript" src="/media/admin/js/jquery.init.js"></script> | ||
2193 | 10 | |||
2194 | 11 | <script type="text/javascript" src="/media/dashboard/js/django-admin.multiselect.js"></script> | ||
2195 | 12 | <link rel="stylesheet" type="text/css" href="/media/dashboard/css/django-admin-widgets.css" /> | ||
2196 | 13 | |||
2197 | 14 | <script type="text/javascript" charset="utf-8"> | ||
2198 | 15 | django.jQuery(function(){ | ||
2199 | 16 | django.jQuery.each(django.jQuery(".edit_user_roles select[multiple]"), function () { | ||
2200 | 17 | // "Locations" can be any label you want | ||
2201 | 18 | SelectFilter.init(this.id, "Roles", 0, "/media/admin/"); | ||
2202 | 19 | }); | ||
2203 | 20 | }) | ||
2204 | 21 | </script> | ||
2205 | 22 | {% endblock %} | ||
2206 | 23 | |||
2207 | 24 | {% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% admin_media_prefix %}css/forms.css" />{% endblock %} | ||
2208 | 25 | |||
2209 | 26 | {% block coltype %}colMS{% endblock %} | ||
2210 | 27 | |||
2211 | 28 | {% block bodyclass %} change-form{% endblock %} | ||
2212 | 29 | |||
2213 | 30 | {% block breadcrumbs %} | ||
2214 | 31 | <div class="breadcrumbs"> | ||
2215 | 32 | <a href="/admin">Home</a> › | ||
2216 | 33 | <a href="{% url admin_projects %}">Projects</a> › | ||
2217 | 34 | <a href="{% url admin_project project.projectname %}">{{project.projectname}}</a> › | ||
2218 | 35 | User | ||
2219 | 36 | {{form.ProjectUserForm}} | ||
2220 | 37 | </div> | ||
2221 | 38 | {% endblock %} | ||
2222 | 39 | |||
2223 | 40 | {% block content %} | ||
2224 | 41 | <div id="content-main"> | ||
2225 | 42 | {% block object-tools %} | ||
2226 | 43 | {% endblock %} | ||
2227 | 44 | <form class="edit_user_roles" action="." method="post" enctype="multipart/form-data"> | ||
2228 | 45 | {% csrf_token %} | ||
2229 | 46 | <fieldset class="module aligned {{ fieldset.classes }}"> | ||
2230 | 47 | <input type="hidden" name="username" value="{{user.id}}" id="username" /> | ||
2231 | 48 | {% for field in form.visible_fields %} | ||
2232 | 49 | <div class="form-row"> | ||
2233 | 50 | {{ field.errors }} | ||
2234 | 51 | {{ field.label_tag }}{{ field }} | ||
2235 | 52 | {% if field.field.help_text %}<p class="help">{{ field.field.help_text|safe }}</p>{% endif %} | ||
2236 | 53 | </div> | ||
2237 | 54 | {% endfor %} | ||
2238 | 55 | {% for field in form.hidden_fields %} | ||
2239 | 56 | {{ field }} | ||
2240 | 57 | {% endfor %} | ||
2241 | 58 | |||
2242 | 59 | </fieldset> | ||
2243 | 60 | <div class="submit-row"> | ||
2244 | 61 | <p class="deletelink-box"> | ||
2245 | 62 | <a href="{% url admin_project_delete_user project.projectname user.username %}" class="deletelink">Delete</a> | ||
2246 | 63 | </p> | ||
2247 | 64 | <input type="submit" value="Save" class="default" /> | ||
2248 | 65 | </div> | ||
2249 | 66 | |||
2250 | 67 | </form> | ||
2251 | 68 | </div> | ||
2252 | 69 | {% endblock %} | ||
2253 | 70 | 0 | ||
2254 | === removed file 'src/django_nova/templates/admin/django_nova/project/base_projects.html' | |||
2255 | --- src/django_nova/templates/admin/django_nova/project/base_projects.html 2011-01-12 20:02:06 +0000 | |||
2256 | +++ src/django_nova/templates/admin/django_nova/project/base_projects.html 1970-01-01 00:00:00 +0000 | |||
2257 | @@ -1,16 +0,0 @@ | |||
2258 | 1 | {% extends "admin/change_list.html" %} | ||
2259 | 2 | |||
2260 | 3 | {% block extrastyle %} | ||
2261 | 4 | {{block.super}} | ||
2262 | 5 | <link rel="stylesheet" type="text/css" href="{{settings.MEDIA_URL}}/stylesheets/extra_admin.css" /> | ||
2263 | 6 | {% endblock %} | ||
2264 | 7 | {% block breadcrumbs %}<div class="breadcrumbs"><a href="/admin/">Home</a> › Projects</div>{% endblock %} | ||
2265 | 8 | {% block content %} | ||
2266 | 9 | <div id="content-main"> | ||
2267 | 10 | <div class="module filtered" id="changelist"> | ||
2268 | 11 | <div id="toolbartable"> | ||
2269 | 12 | {% block innercontent %}{% endblock %} | ||
2270 | 13 | </div> | ||
2271 | 14 | </div> | ||
2272 | 15 | </div> | ||
2273 | 16 | {% endblock %} | ||
2274 | 17 | 0 | ||
2275 | === removed file 'src/django_nova/templates/admin/django_nova/project/change_list.html' | |||
2276 | --- src/django_nova/templates/admin/django_nova/project/change_list.html 2011-01-12 20:02:06 +0000 | |||
2277 | +++ src/django_nova/templates/admin/django_nova/project/change_list.html 1970-01-01 00:00:00 +0000 | |||
2278 | @@ -1,3 +0,0 @@ | |||
2279 | 1 | {% extends "admin/change_list.html" %} | ||
2280 | 2 | {% load admin_extras %} | ||
2281 | 3 | {% block result_list %}{% project_result_list cl %}{% endblock %} | ||
2282 | 4 | \ No newline at end of file | 0 | \ No newline at end of file |
2283 | 5 | 1 | ||
2284 | === removed file 'src/django_nova/templates/admin/django_nova/project/delete_project.html' | |||
2285 | --- src/django_nova/templates/admin/django_nova/project/delete_project.html 2011-01-12 20:02:06 +0000 | |||
2286 | +++ src/django_nova/templates/admin/django_nova/project/delete_project.html 1970-01-01 00:00:00 +0000 | |||
2287 | @@ -1,25 +0,0 @@ | |||
2288 | 1 | {% extends "admin/change_list.html" %} | ||
2289 | 2 | |||
2290 | 3 | {% block extrastyle %} | ||
2291 | 4 | {{block.super}} | ||
2292 | 5 | <link rel="stylesheet" type="text/css" href="{{settings.MEDIA_URL}}/stylesheets/extra_admin.css" /> | ||
2293 | 6 | {% endblock %} | ||
2294 | 7 | {% block breadcrumbs %}<div class="breadcrumbs"><a href="/admin/">Home</a> › <a href="/admin/projects">Projects</a> › <a href="{% url admin_project project.projectname %}">{{project.projectname}}</a> › Delete</div>{% endblock %} | ||
2295 | 8 | {% block content %} | ||
2296 | 9 | <div id="content-main"> | ||
2297 | 10 | <div class="module filtered" id="changelist"> | ||
2298 | 11 | <div id="toolbartable"> | ||
2299 | 12 | <h1>Delete Project</h1> | ||
2300 | 13 | <p>Do you really want to delete this project?</p> | ||
2301 | 14 | <ul> | ||
2302 | 15 | <li><a href="{% url admin_project project.projectname %}">{{project.projectname}}</a></li> | ||
2303 | 16 | </ul> | ||
2304 | 17 | |||
2305 | 18 | <form action="." method="post"> | ||
2306 | 19 | {% csrf_token %} | ||
2307 | 20 | <p><input type="submit" value="Delete"></p> | ||
2308 | 21 | </form> | ||
2309 | 22 | </div> | ||
2310 | 23 | </div> | ||
2311 | 24 | </div> | ||
2312 | 25 | {% endblock %} | ||
2313 | 26 | 0 | ||
2314 | === removed file 'src/django_nova/templates/admin/django_nova/project/delete_project_user.html' | |||
2315 | --- src/django_nova/templates/admin/django_nova/project/delete_project_user.html 2011-01-12 20:02:06 +0000 | |||
2316 | +++ src/django_nova/templates/admin/django_nova/project/delete_project_user.html 1970-01-01 00:00:00 +0000 | |||
2317 | @@ -1,25 +0,0 @@ | |||
2318 | 1 | {% extends "admin/change_list.html" %} | ||
2319 | 2 | |||
2320 | 3 | {% block extrastyle %} | ||
2321 | 4 | {{block.super}} | ||
2322 | 5 | <link rel="stylesheet" type="text/css" href="{{settings.MEDIA_URL}}/stylesheets/extra_admin.css" /> | ||
2323 | 6 | {% endblock %} | ||
2324 | 7 | {% block breadcrumbs %}<div class="breadcrumbs"><a href="/admin/">Home</a> › <a href="/admin/projects">Projects</a> › <a href="{% url admin_project project.projectname %}">{{project.projectname}}</a> › Delete</div>{% endblock %} | ||
2325 | 8 | {% block content %} | ||
2326 | 9 | <div id="content-main"> | ||
2327 | 10 | <div class="module filtered" id="changelist"> | ||
2328 | 11 | <div id="toolbartable"> | ||
2329 | 12 | <h1>Remove User From Project</h1> | ||
2330 | 13 | <p>Do you really want to remove this user from project?</p> | ||
2331 | 14 | <ul> | ||
2332 | 15 | <li><a href="{% url project_user project.projectname user.username %}">{{user.username}}</a> from <a href="{% url admin_project project.projectname %}">{{project.projectname}}</a></li> | ||
2333 | 16 | </ul> | ||
2334 | 17 | |||
2335 | 18 | <form action="." method="post"> | ||
2336 | 19 | {% csrf_token %} | ||
2337 | 20 | <p><input type="submit" value="Delete"></p> | ||
2338 | 21 | </form> | ||
2339 | 22 | </div> | ||
2340 | 23 | </div> | ||
2341 | 24 | </div> | ||
2342 | 25 | {% endblock %} | ||
2343 | 26 | 0 | ||
2344 | === removed file 'src/django_nova/templates/admin/django_nova/project/edit_project.html' | |||
2345 | --- src/django_nova/templates/admin/django_nova/project/edit_project.html 2011-01-12 20:02:06 +0000 | |||
2346 | +++ src/django_nova/templates/admin/django_nova/project/edit_project.html 1970-01-01 00:00:00 +0000 | |||
2347 | @@ -1,95 +0,0 @@ | |||
2348 | 1 | {% extends "admin/django_nova/project/base_projects.html" %} | ||
2349 | 2 | {% load admin_modify adminmedia %} | ||
2350 | 3 | |||
2351 | 4 | {% block extrahead %} | ||
2352 | 5 | {{ block.super }} | ||
2353 | 6 | {{ media }} | ||
2354 | 7 | {% endblock %} | ||
2355 | 8 | |||
2356 | 9 | {% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% admin_media_prefix %}css/forms.css" />{% endblock %} | ||
2357 | 10 | |||
2358 | 11 | {% block coltype %}colMS{% endblock %} | ||
2359 | 12 | |||
2360 | 13 | {% block bodyclass %} change-form{% endblock %} | ||
2361 | 14 | |||
2362 | 15 | {% block breadcrumbs %} | ||
2363 | 16 | <div class="breadcrumbs"> | ||
2364 | 17 | <a href="/admin">Home</a> › | ||
2365 | 18 | <a href="{% url admin_projects %}">Projects</a> › | ||
2366 | 19 | <a href="{% url admin_project project.projectname %}">{{project.projectname}}</a> › | ||
2367 | 20 | Edit Project | ||
2368 | 21 | {{form.ProjectEditForm}} | ||
2369 | 22 | </div> | ||
2370 | 23 | {% endblock %} | ||
2371 | 24 | |||
2372 | 25 | {% block content %} | ||
2373 | 26 | <div id="content-main"> | ||
2374 | 27 | {% block object-tools %} | ||
2375 | 28 | {% endblock %} | ||
2376 | 29 | <form action="#" method="post" enctype="multipart/form-data"> | ||
2377 | 30 | {% csrf_token %} | ||
2378 | 31 | <fieldset class="module aligned {{ fieldset.classes }}"> | ||
2379 | 32 | {% for field in form.visible_fields %} | ||
2380 | 33 | <div class="form-row"> | ||
2381 | 34 | {{ field.errors }} | ||
2382 | 35 | {{ field.label_tag }}{{ field }} | ||
2383 | 36 | {% if field.field.help_text %}<p class="help">{{ field.field.help_text|safe }}</p>{% endif %} | ||
2384 | 37 | </div> | ||
2385 | 38 | {% endfor %} | ||
2386 | 39 | {% for field in form.hidden_fields %} | ||
2387 | 40 | {{ field }} | ||
2388 | 41 | {% endfor %} | ||
2389 | 42 | <div class="form-row"> | ||
2390 | 43 | <label for="project_name">Project Name</label> | ||
2391 | 44 | <span id="project_name" style="display: block; padding-top: 5px; padding-left: 5px; float: left;"><em>{{projectname}}</em></span> | ||
2392 | 45 | </div> | ||
2393 | 46 | <div class="form-row"> | ||
2394 | 47 | <label for="project_description">Description</label> | ||
2395 | 48 | <span id="project_description" style="display: block; padding-top: 5px; padding-left: 5px; float: left;"><em>{{description}}</em></span> | ||
2396 | 49 | </div> | ||
2397 | 50 | <div class="form-row"> | ||
2398 | 51 | <label for="project_manager">Project Manager</label> | ||
2399 | 52 | <span id="project_manager" style="display: block; padding-top: 5px; padding-left: 5px; float: left;"><em>{{manager}}</em></span> | ||
2400 | 53 | </div> | ||
2401 | 54 | </fieldset> | ||
2402 | 55 | <div class="submit-row"> | ||
2403 | 56 | <p class="deletelink-box"> | ||
2404 | 57 | <a href="{% url delete_project project.projectname %}" class="deletelink">Delete Project</a> | ||
2405 | 58 | </p> | ||
2406 | 59 | {# <input type="submit" value="Save" class="default" /> #} | ||
2407 | 60 | </div> | ||
2408 | 61 | |||
2409 | 62 | </form> | ||
2410 | 63 | |||
2411 | 64 | |||
2412 | 65 | <table cellspacing="0" style="margin-top: 20px;"> | ||
2413 | 66 | <thead> | ||
2414 | 67 | <tr> | ||
2415 | 68 | <th>Username</th> | ||
2416 | 69 | <th>Project Roles</th> | ||
2417 | 70 | <th>Global Roles</th> | ||
2418 | 71 | </tr> | ||
2419 | 72 | </thead> | ||
2420 | 73 | {% for user in users %} | ||
2421 | 74 | <tr class="{% cycle 'row1' 'row2' %}"> | ||
2422 | 75 | <td> | ||
2423 | 76 | <a href="{%url project_user project.projectname user.memberId %}">{{user.memberId}} {% if user.memberId == project.projectManagerId %}(<em>project manager</em>){%endif %}</a> | ||
2424 | 77 | |||
2425 | 78 | </td> | ||
2426 | 79 | <td> | ||
2427 | 80 | {{user.project_roles}} | ||
2428 | 81 | </td> | ||
2429 | 82 | <td> | ||
2430 | 83 | {{user.global_roles}} | ||
2431 | 84 | </td> | ||
2432 | 85 | </tr> | ||
2433 | 86 | {% endfor %} | ||
2434 | 87 | </table> | ||
2435 | 88 | <ul class="object-tools"> | ||
2436 | 89 | <li> | ||
2437 | 90 | <a class="addlink" href="{% url add_project_user project.projectname %}">Add User</a> | ||
2438 | 91 | </li> | ||
2439 | 92 | </ul> | ||
2440 | 93 | |||
2441 | 94 | </div> | ||
2442 | 95 | {% endblock %} | ||
2443 | 96 | 0 | ||
2444 | === removed file 'src/django_nova/templates/admin/django_nova/project/global_edit_user.html' | |||
2445 | --- src/django_nova/templates/admin/django_nova/project/global_edit_user.html 2011-01-12 20:02:06 +0000 | |||
2446 | +++ src/django_nova/templates/admin/django_nova/project/global_edit_user.html 1970-01-01 00:00:00 +0000 | |||
2447 | @@ -1,71 +0,0 @@ | |||
2448 | 1 | {% extends "admin/django_nova/project/base_projects.html" %} | ||
2449 | 2 | {% load admin_modify adminmedia %} | ||
2450 | 3 | |||
2451 | 4 | {% block extrahead %} | ||
2452 | 5 | {{ block.super }} | ||
2453 | 6 | {{ media }} | ||
2454 | 7 | |||
2455 | 8 | <script type="text/javascript" src="/media/admin/js/jquery.min.js"></script> | ||
2456 | 9 | <script type="text/javascript" src="/media/admin/js/jquery.init.js"></script> | ||
2457 | 10 | |||
2458 | 11 | <script type="text/javascript" src="/media/dashboard/js/django-admin.multiselect.js"></script> | ||
2459 | 12 | <link rel="stylesheet" type="text/css" href="/media/dashboard/css/django-admin-widgets.css" /> | ||
2460 | 13 | |||
2461 | 14 | <script type="text/javascript" charset="utf-8"> | ||
2462 | 15 | django.jQuery(function(){ | ||
2463 | 16 | django.jQuery.each(django.jQuery("#global_users select"), function () { | ||
2464 | 17 | // "Locations" can be any label you want | ||
2465 | 18 | SelectFilter.init(this.id, "Roles", 0, "/media/admin/"); | ||
2466 | 19 | }); | ||
2467 | 20 | }) | ||
2468 | 21 | </script> | ||
2469 | 22 | {% endblock %} | ||
2470 | 23 | |||
2471 | 24 | {% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% admin_media_prefix %}css/forms.css" />{% endblock %} | ||
2472 | 25 | |||
2473 | 26 | {% block coltype %}colMS{% endblock %} | ||
2474 | 27 | |||
2475 | 28 | {% block bodyclass %} change-form{% endblock %} | ||
2476 | 29 | |||
2477 | 30 | {% block breadcrumbs %} | ||
2478 | 31 | <div class="breadcrumbs"> | ||
2479 | 32 | <a href="/admin">Home</a> › | ||
2480 | 33 | <a href="{% url admin_users_list %}">Global Roles</a> › | ||
2481 | 34 | {{user.username}} | ||
2482 | 35 | </div> | ||
2483 | 36 | {% endblock %} | ||
2484 | 37 | |||
2485 | 38 | {% block content %} | ||
2486 | 39 | <div id="content-main"> | ||
2487 | 40 | {% block object-tools %} | ||
2488 | 41 | {% endblock %} | ||
2489 | 42 | <form action="." method="post" enctype="multipart/form-data" id="global_users"> | ||
2490 | 43 | {% csrf_token %} | ||
2491 | 44 | <fieldset class="module aligned {{ fieldset.classes }}"> | ||
2492 | 45 | <div class="form-row"> | ||
2493 | 46 | <label for="id_username">Username</label> | ||
2494 | 47 | <span>{{user.username}}</span> | ||
2495 | 48 | </div> | ||
2496 | 49 | <input type="hidden" name="username" value="{{user.id}}" id="username" /> | ||
2497 | 50 | {% for field in form.visible_fields %} | ||
2498 | 51 | <div class="form-row"> | ||
2499 | 52 | {{ field.errors }} | ||
2500 | 53 | {{ field.label_tag }}{{ field }} | ||
2501 | 54 | {% if field.field.help_text %}<p class="help">{{ field.field.help_text|safe }}</p>{% endif %} | ||
2502 | 55 | </div> | ||
2503 | 56 | {% endfor %} | ||
2504 | 57 | {% for field in form.hidden_fields %} | ||
2505 | 58 | {{ field }} | ||
2506 | 59 | {% endfor %} | ||
2507 | 60 | |||
2508 | 61 | </fieldset> | ||
2509 | 62 | <div class="submit-row"> | ||
2510 | 63 | <p class="deletelink-box"> | ||
2511 | 64 | {# <a href="{% url admin_project_delete_user project.projectname user.username %}" class="deletelink">Delete</a> #} | ||
2512 | 65 | </p> | ||
2513 | 66 | <input type="submit" value="Save" class="default" /> | ||
2514 | 67 | </div> | ||
2515 | 68 | |||
2516 | 69 | </form> | ||
2517 | 70 | </div> | ||
2518 | 71 | {% endblock %} | ||
2519 | 72 | 0 | ||
2520 | === removed file 'src/django_nova/templates/admin/django_nova/project/project_list.html' | |||
2521 | --- src/django_nova/templates/admin/django_nova/project/project_list.html 2011-01-12 20:02:06 +0000 | |||
2522 | +++ src/django_nova/templates/admin/django_nova/project/project_list.html 1970-01-01 00:00:00 +0000 | |||
2523 | @@ -1,42 +0,0 @@ | |||
2524 | 1 | {% extends "admin/django_nova/project/base_projects.html" %} | ||
2525 | 2 | {% block extrahead %} | ||
2526 | 3 | {{ block.super }} | ||
2527 | 4 | {% endblock %} | ||
2528 | 5 | {% block innercontent %} | ||
2529 | 6 | <ul class="object-tools"> | ||
2530 | 7 | <li> | ||
2531 | 8 | <a class="addlink" href="{% url add_project %}">Add Project</a> | ||
2532 | 9 | </li> | ||
2533 | 10 | </ul> | ||
2534 | 11 | <table cellspacing="0" style="margin-top: 20px;"> | ||
2535 | 12 | <thead> | ||
2536 | 13 | <tr> | ||
2537 | 14 | <th>Name</th> | ||
2538 | 15 | <th>Description</th> | ||
2539 | 16 | <th>Project Manager</th> | ||
2540 | 17 | <th>Send Credentials</th> | ||
2541 | 18 | <th>Start VPN</th> | ||
2542 | 19 | </tr> | ||
2543 | 20 | </thead> | ||
2544 | 21 | {% for project in projects %} | ||
2545 | 22 | <tr class="{% cycle 'row1' 'row2' %}"> | ||
2546 | 23 | <td> | ||
2547 | 24 | <a href="{%url admin_project project.projectname %}">{{project.projectname}}</a> | ||
2548 | 25 | </td> | ||
2549 | 26 | <td> | ||
2550 | 27 | {{project.description}} | ||
2551 | 28 | </td> | ||
2552 | 29 | <td> | ||
2553 | 30 | {{project.projectManagerId}} | ||
2554 | 31 | </td> | ||
2555 | 32 | <td> | ||
2556 | 33 | <a href="{% url admin_project_sendcredentials project.projectname %}">Send Credentials</a> | ||
2557 | 34 | </td> | ||
2558 | 35 | <td> | ||
2559 | 36 | <a href="{% url admin_project_start_vpn project.projectname %}">Start VPN</a> | ||
2560 | 37 | </td> | ||
2561 | 38 | |||
2562 | 39 | </tr> | ||
2563 | 40 | {% endfor %} | ||
2564 | 41 | </table> | ||
2565 | 42 | {% endblock %} | ||
2566 | 43 | 0 | ||
2567 | === removed file 'src/django_nova/templates/admin/django_nova/project/project_user.html' | |||
2568 | --- src/django_nova/templates/admin/django_nova/project/project_user.html 2011-01-12 20:02:06 +0000 | |||
2569 | +++ src/django_nova/templates/admin/django_nova/project/project_user.html 1970-01-01 00:00:00 +0000 | |||
2570 | @@ -1,76 +0,0 @@ | |||
2571 | 1 | {% extends "admin/django_nova/project/base_projects.html" %} | ||
2572 | 2 | {% load admin_modify adminmedia %} | ||
2573 | 3 | |||
2574 | 4 | {% block extrahead %} | ||
2575 | 5 | {{ block.super }} | ||
2576 | 6 | {{ media }} | ||
2577 | 7 | |||
2578 | 8 | <script type="text/javascript" src="/media/admin/js/jquery.min.js"></script> | ||
2579 | 9 | <script type="text/javascript" src="/media/admin/js/jquery.init.js"></script> | ||
2580 | 10 | |||
2581 | 11 | <script type="text/javascript" src="/media/dashboard/js/django-admin.multiselect.js"></script> | ||
2582 | 12 | <link rel="stylesheet" type="text/css" href="/media/dashboard/css/django-admin-widgets.css" /> | ||
2583 | 13 | |||
2584 | 14 | <script type="text/javascript" charset="utf-8"> | ||
2585 | 15 | django.jQuery(function(){ | ||
2586 | 16 | django.jQuery.each(django.jQuery(".edit_user_roles select[multiple]"), function () { | ||
2587 | 17 | // "Locations" can be any label you want | ||
2588 | 18 | SelectFilter.init(this.id, "Roles", 0, "/media/admin/"); | ||
2589 | 19 | }); | ||
2590 | 20 | }) | ||
2591 | 21 | </script> | ||
2592 | 22 | {% endblock %} | ||
2593 | 23 | |||
2594 | 24 | {% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% admin_media_prefix %}css/forms.css" />{% endblock %} | ||
2595 | 25 | |||
2596 | 26 | {% block coltype %}colMS{% endblock %} | ||
2597 | 27 | |||
2598 | 28 | {% block bodyclass %} change-form{% endblock %} | ||
2599 | 29 | |||
2600 | 30 | {% block breadcrumbs %} | ||
2601 | 31 | <div class="breadcrumbs"> | ||
2602 | 32 | <a href="/admin">Home</a> › | ||
2603 | 33 | <a href="{% url admin_projects %}">Projects</a> › | ||
2604 | 34 | <a href="{% url admin_project project.projectname %}">{{project.projectname}}</a> › | ||
2605 | 35 | User | ||
2606 | 36 | {{form.ProjectUserForm}} | ||
2607 | 37 | </div> | ||
2608 | 38 | {% endblock %} | ||
2609 | 39 | |||
2610 | 40 | {% block content %} | ||
2611 | 41 | <div id="content-main"> | ||
2612 | 42 | {% block object-tools %} | ||
2613 | 43 | {% endblock %} | ||
2614 | 44 | <form class="edit_user_roles" action="." method="post" enctype="multipart/form-data"> | ||
2615 | 45 | {% csrf_token %} | ||
2616 | 46 | <fieldset class="module aligned {{ fieldset.classes }}"> | ||
2617 | 47 | <div class="form-row"> | ||
2618 | 48 | <label for="id_username">Username</label> | ||
2619 | 49 | <span>{{user.username}}</span> | ||
2620 | 50 | </div> | ||
2621 | 51 | <input type="hidden" name="username" value="{{user.id}}" id="username" /> | ||
2622 | 52 | {% for field in form.visible_fields %} | ||
2623 | 53 | <div class="form-row"> | ||
2624 | 54 | {{ field.errors }} | ||
2625 | 55 | {{ field.label_tag }}{{ field }} | ||
2626 | 56 | {% if field.field.help_text %}<p class="help">{{ field.field.help_text|safe }}</p>{% endif %} | ||
2627 | 57 | </div> | ||
2628 | 58 | {% endfor %} | ||
2629 | 59 | {% for field in form.hidden_fields %} | ||
2630 | 60 | {{ field }} | ||
2631 | 61 | {% endfor %} | ||
2632 | 62 | |||
2633 | 63 | </fieldset> | ||
2634 | 64 | <div class="submit-row"> | ||
2635 | 65 | {% if project.projectManagerId != user.username %} | ||
2636 | 66 | <p class="deletelink-box"> | ||
2637 | 67 | <a href="{% url admin_project_delete_user project.projectname user.username %}" class="deletelink">Remove User From Project</a> | ||
2638 | 68 | </p> | ||
2639 | 69 | {% endif %} | ||
2640 | 70 | |||
2641 | 71 | <input type="submit" value="Save" class="default" /> | ||
2642 | 72 | </div> | ||
2643 | 73 | |||
2644 | 74 | </form> | ||
2645 | 75 | </div> | ||
2646 | 76 | {% endblock %} | ||
2647 | 77 | 0 | ||
2648 | === removed file 'src/django_nova/templates/admin/django_nova/project/send_credentials.html' | |||
2649 | --- src/django_nova/templates/admin/django_nova/project/send_credentials.html 2011-01-12 20:02:06 +0000 | |||
2650 | +++ src/django_nova/templates/admin/django_nova/project/send_credentials.html 1970-01-01 00:00:00 +0000 | |||
2651 | @@ -1,87 +0,0 @@ | |||
2652 | 1 | {% extends "admin/base_site.html" %} | ||
2653 | 2 | {% load i18n admin_modify adminmedia %} | ||
2654 | 3 | |||
2655 | 4 | {% block title %}Send project credentials{{ block.super }}{% endblock %} | ||
2656 | 5 | |||
2657 | 6 | {% block extrahead %} | ||
2658 | 7 | {{ block.super }} | ||
2659 | 8 | {{ media }} | ||
2660 | 9 | |||
2661 | 10 | <script type="text/javascript" src="/media/admin/js/jquery.min.js"></script> | ||
2662 | 11 | <script type="text/javascript" src="/media/admin/js/jquery.init.js"></script> | ||
2663 | 12 | |||
2664 | 13 | <script type="text/javascript" src="/media/dashboard/js/django-admin.multiselect.js"></script> | ||
2665 | 14 | <link rel="stylesheet" type="text/css" href="/media/dashboard/css/django-admin-widgets.css" /> | ||
2666 | 15 | |||
2667 | 16 | <script type="text/javascript" charset="utf-8"> | ||
2668 | 17 | django.jQuery(function(){ | ||
2669 | 18 | django.jQuery.each(django.jQuery("#send_credentials select"), function () { | ||
2670 | 19 | // "Locations" can be any label you want | ||
2671 | 20 | SelectFilter.init(this.id, "Users", 0, "/media/admin/"); | ||
2672 | 21 | }); | ||
2673 | 22 | }) | ||
2674 | 23 | </script> | ||
2675 | 24 | |||
2676 | 25 | <style type="text/css" media="screen"> | ||
2677 | 26 | .errorlist, .successlist {background:#fcc;border:1px solid #c66;color:#600;list-style:none; padding: 10px 5px; margin: 25px 0 25px 0; float: left; width: 100%;} | ||
2678 | 27 | .successlist {background: #CBFBD7; color: #1E5024; border-color: #6FBA5C;} | ||
2679 | 28 | </style> | ||
2680 | 29 | {% endblock %} | ||
2681 | 30 | |||
2682 | 31 | |||
2683 | 32 | {% block breadcrumbs %} | ||
2684 | 33 | <div class="breadcrumbs"> | ||
2685 | 34 | <a href="/admin">Home</a> › | ||
2686 | 35 | <a href="{% url admin_projects %}">Projects</a> › | ||
2687 | 36 | <a href="{% url admin_project project.projectname %}">{{project.projectname}}</a> › | ||
2688 | 37 | Send Credentials | ||
2689 | 38 | </div> | ||
2690 | 39 | {% endblock %} | ||
2691 | 40 | |||
2692 | 41 | {% block content %} | ||
2693 | 42 | <div id="content-main"> | ||
2694 | 43 | |||
2695 | 44 | |||
2696 | 45 | {% if not success %} | ||
2697 | 46 | <h1>Send Credentials</h1> | ||
2698 | 47 | <h3>Select which users you would like to send credentials to from the '{{ project.projectname }}' project.</h3> | ||
2699 | 48 | {% else %} | ||
2700 | 49 | <h1>Credentials sent successfully</h1> | ||
2701 | 50 | {% endif %} | ||
2702 | 51 | |||
2703 | 52 | <div class="status"> | ||
2704 | 53 | {% if error %} | ||
2705 | 54 | <span class="errorlist">{{ error }}</span> | ||
2706 | 55 | {% endif %} | ||
2707 | 56 | |||
2708 | 57 | {% if success %} | ||
2709 | 58 | <span class="successlist">{{ success }}</span> | ||
2710 | 59 | {% endif %} | ||
2711 | 60 | |||
2712 | 61 | </div> | ||
2713 | 62 | |||
2714 | 63 | {% if not success %} | ||
2715 | 64 | <form id="send_credentials" action="{% url admin_project_sendcredentials project.projectname %}" method="post"> | ||
2716 | 65 | {% csrf_token %} | ||
2717 | 66 | <fieldset class="module aligned"> | ||
2718 | 67 | |||
2719 | 68 | {% for field in form.visible_fields %} | ||
2720 | 69 | <div class="form-row"> | ||
2721 | 70 | {{ field.errors }} | ||
2722 | 71 | {{ field }} | ||
2723 | 72 | {% if field.field.help_text %}<p class="help">{{ field.field.help_text|safe }}</p>{% endif %} | ||
2724 | 73 | </div> | ||
2725 | 74 | {% endfor %} | ||
2726 | 75 | {% for field in form.hidden_fields %} | ||
2727 | 76 | {{ field }} | ||
2728 | 77 | {% endfor %} | ||
2729 | 78 | |||
2730 | 79 | </fieldset> | ||
2731 | 80 | <div class="submit-row"> | ||
2732 | 81 | <input style="margin-top:20px; margin-left:10px;" type="submit" value="Send Credentials" /> | ||
2733 | 82 | </div> | ||
2734 | 83 | |||
2735 | 84 | </form> | ||
2736 | 85 | {% endif %} | ||
2737 | 86 | </div> | ||
2738 | 87 | {% endblock %} | ||
2739 | 88 | 0 | ||
2740 | === removed file 'src/django_nova/templates/admin/django_nova/project/user_list.html' | |||
2741 | --- src/django_nova/templates/admin/django_nova/project/user_list.html 2011-01-12 20:02:06 +0000 | |||
2742 | +++ src/django_nova/templates/admin/django_nova/project/user_list.html 1970-01-01 00:00:00 +0000 | |||
2743 | @@ -1,39 +0,0 @@ | |||
2744 | 1 | {% extends "admin/django_nova/project/base_projects.html" %} | ||
2745 | 2 | {% block extrahead %} | ||
2746 | 3 | {{ block.super }} | ||
2747 | 4 | {% endblock %} | ||
2748 | 5 | |||
2749 | 6 | {% block breadcrumbs %} | ||
2750 | 7 | <div class="breadcrumbs"> | ||
2751 | 8 | <a href="/admin">Home</a> › | ||
2752 | 9 | Global Roles | ||
2753 | 10 | </div> | ||
2754 | 11 | {% endblock %} | ||
2755 | 12 | |||
2756 | 13 | {% block innercontent %} | ||
2757 | 14 | <h1>Select a User</h1> | ||
2758 | 15 | |||
2759 | 16 | <table cellspacing="0" style="margin-top: 20px;"> | ||
2760 | 17 | <thead> | ||
2761 | 18 | <tr> | ||
2762 | 19 | <th>Username</th> | ||
2763 | 20 | <th>Global Roles</th> | ||
2764 | 21 | <th>Actions</th> | ||
2765 | 22 | </tr> | ||
2766 | 23 | </thead> | ||
2767 | 24 | {% for user in users %} | ||
2768 | 25 | <tr class="{% cycle 'row1' 'row2' %}"> | ||
2769 | 26 | <td> | ||
2770 | 27 | {{user.username}} | ||
2771 | 28 | </td> | ||
2772 | 29 | <td> | ||
2773 | 30 | (temporarily hidden) | ||
2774 | 31 | {#user.roles#} | ||
2775 | 32 | </td> | ||
2776 | 33 | <td> | ||
2777 | 34 | <a href="{%url admin_user_roles user.username %}">Edit</a> | ||
2778 | 35 | </td> | ||
2779 | 36 | </tr> | ||
2780 | 37 | {% endfor %} | ||
2781 | 38 | </table> | ||
2782 | 39 | {% endblock %} | ||
2783 | 40 | 0 | ||
2784 | === removed directory 'src/django_nova/templates/django_nova' | |||
2785 | === removed file 'src/django_nova/templates/django_nova/_messages.html' | |||
2786 | --- src/django_nova/templates/django_nova/_messages.html 2011-01-12 20:02:06 +0000 | |||
2787 | +++ src/django_nova/templates/django_nova/_messages.html 1970-01-01 00:00:00 +0000 | |||
2788 | @@ -1,41 +0,0 @@ | |||
2789 | 1 | {% for message in messages %} | ||
2790 | 2 | <div class="message ui-widget"> | ||
2791 | 3 | {% if message.tags == "info" %} | ||
2792 | 4 | <div class="ui-state-highlight ui-corner-all"> | ||
2793 | 5 | <span class="close ui-icon ui-icon-circle-close"></span> | ||
2794 | 6 | <p> | ||
2795 | 7 | <span class="ui-icon ui-icon-info"></span> | ||
2796 | 8 | {{ message }} | ||
2797 | 9 | </p> | ||
2798 | 10 | </div> | ||
2799 | 11 | {% endif %} | ||
2800 | 12 | {% if message.tags == "warning" %} | ||
2801 | 13 | <div class="ui-state-highlight ui-corner-all" > | ||
2802 | 14 | <span class="close ui-icon ui-icon-circle-close"></span> | ||
2803 | 15 | <p> | ||
2804 | 16 | <span class="ui-icon ui-icon-alert"></span> | ||
2805 | 17 | {{ message }} | ||
2806 | 18 | </p> | ||
2807 | 19 | </div> | ||
2808 | 20 | {% endif %} | ||
2809 | 21 | {% if message.tags == "success" %} | ||
2810 | 22 | <div class="ui-state-highlight ui-corner-all success" > | ||
2811 | 23 | <span class="close ui-icon ui-icon-circle-close"></span> | ||
2812 | 24 | <p> | ||
2813 | 25 | <span class="ui-icon ui-icon-check"></span> | ||
2814 | 26 | {{ message }} | ||
2815 | 27 | </p> | ||
2816 | 28 | </div> | ||
2817 | 29 | {% endif %} | ||
2818 | 30 | {% if message.tags == "error" %} | ||
2819 | 31 | <div class="ui-state-error ui-corner-all" > | ||
2820 | 32 | <span class="close ui-icon ui-icon-circle-close"></span> | ||
2821 | 33 | <p> | ||
2822 | 34 | <span class="ui-icon ui-icon-alert"></span> | ||
2823 | 35 | {{ message }} | ||
2824 | 36 | </p> | ||
2825 | 37 | </div> | ||
2826 | 38 | {% endif %} | ||
2827 | 39 | </div> | ||
2828 | 40 | {% endfor %} | ||
2829 | 41 | |||
2830 | 42 | 0 | ||
2831 | === removed file 'src/django_nova/templates/django_nova/base.html' | |||
2832 | --- src/django_nova/templates/django_nova/base.html 2011-01-18 21:53:47 +0000 | |||
2833 | +++ src/django_nova/templates/django_nova/base.html 1970-01-01 00:00:00 +0000 | |||
2834 | @@ -1,85 +0,0 @@ | |||
2835 | 1 | {% extends "base-sidebar.html" %} | ||
2836 | 2 | {% load region_tags %} | ||
2837 | 3 | {% load project_tags %} | ||
2838 | 4 | |||
2839 | 5 | {% block headerjs %} | ||
2840 | 6 | {{ block.super }} | ||
2841 | 7 | {% endblock %} | ||
2842 | 8 | |||
2843 | 9 | {% block region %} | ||
2844 | 10 | <div id="region_selector"> | ||
2845 | 11 | {% load_regions %} | ||
2846 | 12 | <span id="project_name"><strong>Project:</strong> {{ project.projectname }}</span> | ||
2847 | 13 | |||
2848 | 14 | <form id="frm_region" method="post" action="{% url region_change %}"> | ||
2849 | 15 | {% csrf_token %} | ||
2850 | 16 | <fieldset> | ||
2851 | 17 | <input name="redirect_url" type="hidden" value="{{ request.get_full_path }}" /> | ||
2852 | 18 | <noscript> | ||
2853 | 19 | <input id="btn_region_change" type="submit" value="Change" /> | ||
2854 | 20 | </noscript> | ||
2855 | 21 | |||
2856 | 22 | <div id="region_form"> | ||
2857 | 23 | <label for="sel_region">Region: </label> | ||
2858 | 24 | <select id="sel_region" name="region"> | ||
2859 | 25 | {% for region in regions %} | ||
2860 | 26 | <option{% if region.name == current_region.name %} selected{% endif %}> | ||
2861 | 27 | {{ region.name }} | ||
2862 | 28 | </option> | ||
2863 | 29 | {% endfor %} | ||
2864 | 30 | </select> | ||
2865 | 31 | </div> | ||
2866 | 32 | |||
2867 | 33 | </fieldset> | ||
2868 | 34 | </form> | ||
2869 | 35 | </div> | ||
2870 | 36 | {% endblock %} | ||
2871 | 37 | |||
2872 | 38 | {% block nav_projects %} | ||
2873 | 39 | {% load_projects %} | ||
2874 | 40 | <li> | ||
2875 | 41 | <h3 class="active"><a href="/">Projects</a></h3> | ||
2876 | 42 | <div id="projects"> | ||
2877 | 43 | {% for p in projects %} | ||
2878 | 44 | <div id="{{ p.projectname }}" class="project{% if p.projectname == project.projectname %} active{% endif %}"> | ||
2879 | 45 | <h4> | ||
2880 | 46 | <a class="project_link" href="/project/{{ p.projectname }}">{{ p.projectname }}</a> | ||
2881 | 47 | {% if p.projectManagerId == user.username %} | ||
2882 | 48 | <a id="manage_project_{{p.projectname}}" | ||
2883 | 49 | class="manage_link" | ||
2884 | 50 | href="{% url nova_project_manage p.projectname %}" | ||
2885 | 51 | title="Manage User Roles">Manage Project</a> | ||
2886 | 52 | {% endif %} | ||
2887 | 53 | </h4> | ||
2888 | 54 | {% if project.projectname == p.projectname %} | ||
2889 | 55 | <ul> | ||
2890 | 56 | <li {% if p.projectname == project.projectname and sidebar_selected == "instances" %}class="active"{% endif %}> | ||
2891 | 57 | <a id="lnk_instances_{{p.projectname}}" href="{% url nova_instances p.projectname %}">Instances</a> | ||
2892 | 58 | </li> | ||
2893 | 59 | <li {% if p.projectname == project.projectname and sidebar_selected == "images" %}class="active"{% endif %}> | ||
2894 | 60 | <a id="lnk_images_{{p.projectname}}" href="{% url nova_images p.projectname %}">Images</a> | ||
2895 | 61 | </li> | ||
2896 | 62 | <li {% if p.projectname == project.projectname and sidebar_selected == "keys" %}class="active"{% endif %}> | ||
2897 | 63 | <a id="lnk_keypairs_{{p.projectname}}" href="{% url nova_keypairs p.projectname %}">Keys</a> | ||
2898 | 64 | </li> | ||
2899 | 65 | <li {% if p.projectname == project.projectname and sidebar_selected == "volumes" %}class="active"{% endif %}> | ||
2900 | 66 | <a id="lnk_volumes_{{p.projectname}}" href="{% url nova_volumes p.projectname %}">Volumes</a> | ||
2901 | 67 | </li> | ||
2902 | 68 | </ul> | ||
2903 | 69 | {% endif %} | ||
2904 | 70 | </div> | ||
2905 | 71 | {% endfor %} | ||
2906 | 72 | </div> | ||
2907 | 73 | </li> | ||
2908 | 74 | {% endblock %} | ||
2909 | 75 | |||
2910 | 76 | {% block footerjs %} | ||
2911 | 77 | {{ block.super }} | ||
2912 | 78 | <script type="text/javascript"> | ||
2913 | 79 | $(function() { | ||
2914 | 80 | $('#sel_region').change(function() { | ||
2915 | 81 | $('#frm_region').submit(); | ||
2916 | 82 | }); | ||
2917 | 83 | }); | ||
2918 | 84 | </script> | ||
2919 | 85 | {% endblock %} | ||
2920 | 86 | 0 | ||
2921 | === removed directory 'src/django_nova/templates/django_nova/credentials' | |||
2922 | === removed file 'src/django_nova/templates/django_nova/credentials/expired.html' | |||
2923 | --- src/django_nova/templates/django_nova/credentials/expired.html 2011-02-01 19:18:59 +0000 | |||
2924 | +++ src/django_nova/templates/django_nova/credentials/expired.html 1970-01-01 00:00:00 +0000 | |||
2925 | @@ -1,17 +0,0 @@ | |||
2926 | 1 | {% load django_nova_tags %} | ||
2927 | 2 | <!DOCTYPE html> | ||
2928 | 3 | <html lang="en" xml:lang="en"> | ||
2929 | 4 | <head> | ||
2930 | 5 | <meta http-equiv="content-type" content="text/html; charset=utf-8" /> | ||
2931 | 6 | <title>Expired Token</title> | ||
2932 | 7 | </head> | ||
2933 | 8 | <body> | ||
2934 | 9 | <center> | ||
2935 | 10 | <h1>The link you clicked has expired.</h1> | ||
2936 | 11 | <p style="width:460px;">This credentials download link you have reached | ||
2937 | 12 | is either invalid or has expired. Each link is only good for one use. If | ||
2938 | 13 | you need to download your credentials again, please contact the | ||
2939 | 14 | {% site_branding %} support team.</p> | ||
2940 | 15 | </center> | ||
2941 | 16 | </body> | ||
2942 | 17 | </html> | ||
2943 | 18 | 0 | ||
2944 | === removed directory 'src/django_nova/templates/django_nova/images' | |||
2945 | === removed file 'src/django_nova/templates/django_nova/images/_launch_form.html' | |||
2946 | --- src/django_nova/templates/django_nova/images/_launch_form.html 2011-01-12 20:02:06 +0000 | |||
2947 | +++ src/django_nova/templates/django_nova/images/_launch_form.html 1970-01-01 00:00:00 +0000 | |||
2948 | @@ -1,7 +0,0 @@ | |||
2949 | 1 | {% for field in form %} | ||
2950 | 2 | <div class="{% cycle 'odd' 'even'%}"> | ||
2951 | 3 | {{ field.label_tag }} | ||
2952 | 4 | {% if field.errors %}{{ field.errors }}{% endif %} | ||
2953 | 5 | {{ field }} | ||
2954 | 6 | </div> | ||
2955 | 7 | {% endfor %} | ||
2956 | 8 | 0 | ||
2957 | === removed file 'src/django_nova/templates/django_nova/images/_list.html' | |||
2958 | --- src/django_nova/templates/django_nova/images/_list.html 2011-03-01 04:13:08 +0000 | |||
2959 | +++ src/django_nova/templates/django_nova/images/_list.html 1970-01-01 00:00:00 +0000 | |||
2960 | @@ -1,112 +0,0 @@ | |||
2961 | 1 | <h3 class="image_list_heading"> {{ heading }} </h3> | ||
2962 | 2 | {% if images %} | ||
2963 | 3 | <table id="image_launch"> | ||
2964 | 4 | <tr> | ||
2965 | 5 | <th>ID</th> | ||
2966 | 6 | <th>Description</th> | ||
2967 | 7 | <th colspan="2">Owner</th> | ||
2968 | 8 | </tr> | ||
2969 | 9 | {% for image in images %} | ||
2970 | 10 | {% if image.id == ami.id %} | ||
2971 | 11 | <td class="detail_wrapper" colspan="4"> | ||
2972 | 12 | <div id="{{ ami.id }}" class="image_detail"> | ||
2973 | 13 | <div class="column"> | ||
2974 | 14 | <div class="image_detail_item"> | ||
2975 | 15 | <span class="label">Owner: </span> | ||
2976 | 16 | <span class="data">{{ ami.ownerId }}</span> | ||
2977 | 17 | </div> | ||
2978 | 18 | |||
2979 | 19 | <div class="image_detail_item"> | ||
2980 | 20 | <span class="label">Description: </span> | ||
2981 | 21 | <span class="data">{{ ami.description }}</span> | ||
2982 | 22 | </div> | ||
2983 | 23 | |||
2984 | 24 | <div class="image_detail_item"> | ||
2985 | 25 | <span class="label">Location: </span> | ||
2986 | 26 | <span class="data">{{ ami.location }}</span> | ||
2987 | 27 | </div> | ||
2988 | 28 | </div> | ||
2989 | 29 | |||
2990 | 30 | <div class="column"> | ||
2991 | 31 | <div class="image_detail_item"> | ||
2992 | 32 | <span class="label">ID: </span> | ||
2993 | 33 | <span class="data">{{ ami.id }}</span> | ||
2994 | 34 | </div> | ||
2995 | 35 | <div class="image_detail_item"> | ||
2996 | 36 | <span class="label">Name: </span> | ||
2997 | 37 | <span class="data">{% if ami.displayName %}{{ ami.displayName }}{%else%}{{ ami.id }}{% endif %}</span> | ||
2998 | 38 | </div> | ||
2999 | 39 | <div class="image_detail_item"> | ||
3000 | 40 | <span class="label">Type: </span> | ||
3001 | 41 | <span class="data">{{ ami.type }}</span> | ||
3002 | 42 | </div> | ||
3003 | 43 | <div class="image_detail_item"> | ||
3004 | 44 | <span class="label">Architecture: </span> | ||
3005 | 45 | <span class="data">{{ ami.architecture }}</span> | ||
3006 | 46 | </div> | ||
3007 | 47 | </div> | ||
3008 | 48 | |||
3009 | 49 | <div id="last" class="column"> | ||
3010 | 50 | {% if ami.is_public %} | ||
3011 | 51 | <div id="public" class="privacy">Public Image</div> | ||
3012 | 52 | {% else %} | ||
3013 | 53 | <div id="private" class="privacy">Private Image</div> | ||
3014 | 54 | {% endif %} | ||
3015 | 55 | |||
3016 | 56 | <a id="launch_{{ image.id }}" class="launch" href="{% url nova_images_launch project.projectname image.id %}" title="Click to launch image">Launch</a> | ||
3017 | 57 | {% if can_modify or user.username == ami.ownerId %} | ||
3018 | 58 | <a id="edit_image_link" href="{% url nova_images_update project.projectname ami.id %}">Edit Image</a> | ||
3019 | 59 | {% endif %} | ||
3020 | 60 | |||
3021 | 61 | </div> | ||
3022 | 62 | |||
3023 | 63 | {% if can_modify or user.username == ami.ownerId %} | ||
3024 | 64 | <span class="image_privacy"> | ||
3025 | 65 | <form id="privacy_{{ ami.id }}" action="{% url nova_images_privacy project.projectname ami.id %}" method="post" accept-charset="utf-8"> | ||
3026 | 66 | {% csrf_token %} | ||
3027 | 67 | {% if ami.is_public %} | ||
3028 | 68 | <input class="private" type="submit" value="Make Private" /> | ||
3029 | 69 | {% else %} | ||
3030 | 70 | <input class="public" type="submit" value="Make Public" /> | ||
3031 | 71 | {% endif %} | ||
3032 | 72 | </form> | ||
3033 | 73 | </span> | ||
3034 | 74 | |||
3035 | 75 | <span class="delete"> | ||
3036 | 76 | <form id="delete_{{ ami.id }}" action="{% url nova_images_remove project.projectname ami.id %}" method="post" accept-charset="utf-8"> | ||
3037 | 77 | {% csrf_token %} | ||
3038 | 78 | <input type="submit" value="Remove Image" /> | ||
3039 | 79 | </form> | ||
3040 | 80 | </span> | ||
3041 | 81 | {% endif %} | ||
3042 | 82 | </div> | ||
3043 | 83 | </td> | ||
3044 | 84 | {% else %} | ||
3045 | 85 | <tr class="{% cycle 'odd' 'even' %}"> | ||
3046 | 86 | <td class="image_id"> | ||
3047 | 87 | <a href="{% url nova_images_detail project.projectname image.id %}">{% if image.displayName %}{{ image.displayName }}{%else%}{{ image.id }}{% endif %}</a> | ||
3048 | 88 | </td> | ||
3049 | 89 | <td class="image_location odd"> | ||
3050 | 90 | {% if image.description %} | ||
3051 | 91 | {{ image.description }} | ||
3052 | 92 | {% else %} | ||
3053 | 93 | {{ image.location }} | ||
3054 | 94 | {% endif %} | ||
3055 | 95 | </td> | ||
3056 | 96 | <td class="image_owner_id">{{ image.ownerId }}</td> | ||
3057 | 97 | <td class="image_launch_btn odd"><a id="launch_{{ image.id }}" class="launch" href="{% url nova_images_launch project.projectname image.id %}">Launch</a></td> | ||
3058 | 98 | {#<td class="odd"><a class="ui-state-default ui-corner-all" onclick="$('#dlg_launch').dialog('open');">Launch</a></td>#} | ||
3059 | 99 | </tr> | ||
3060 | 100 | {% endif %} | ||
3061 | 101 | {% endfor %} | ||
3062 | 102 | </table> | ||
3063 | 103 | {% else %} | ||
3064 | 104 | <div class="ui-widget"> | ||
3065 | 105 | <div class="ui-state-highlight ui-corner-all"> | ||
3066 | 106 | <p> | ||
3067 | 107 | <span class="ui-icon ui-icon-info"></span> | ||
3068 | 108 | No images currently available. | ||
3069 | 109 | </p> | ||
3070 | 110 | </div> | ||
3071 | 111 | </div> | ||
3072 | 112 | {% endif %} | ||
3073 | 113 | 0 | ||
3074 | === removed file 'src/django_nova/templates/django_nova/images/base.html' | |||
3075 | --- src/django_nova/templates/django_nova/images/base.html 2011-01-16 21:28:02 +0000 | |||
3076 | +++ src/django_nova/templates/django_nova/images/base.html 1970-01-01 00:00:00 +0000 | |||
3077 | @@ -1,7 +0,0 @@ | |||
3078 | 1 | {% extends "django_nova/base.html" %} | ||
3079 | 2 | {% load sidebar_tags %} | ||
3080 | 3 | |||
3081 | 4 | {% block nav_projects %} | ||
3082 | 5 | {% sidebar_select images %} | ||
3083 | 6 | {{ block.super }} | ||
3084 | 7 | {% endblock %} | ||
3085 | 8 | \ No newline at end of file | 0 | \ No newline at end of file |
3086 | 9 | 1 | ||
3087 | === removed file 'src/django_nova/templates/django_nova/images/detail_list.html' | |||
3088 | --- src/django_nova/templates/django_nova/images/detail_list.html 2011-03-01 04:13:08 +0000 | |||
3089 | +++ src/django_nova/templates/django_nova/images/detail_list.html 1970-01-01 00:00:00 +0000 | |||
3090 | @@ -1,207 +0,0 @@ | |||
3091 | 1 | {% extends "django_nova/images/base.html" %} | ||
3092 | 2 | |||
3093 | 3 | {% block title %} - Launch an Image{% endblock %} | ||
3094 | 4 | |||
3095 | 5 | {% block headerjs %} | ||
3096 | 6 | <script type="text/javascript" src="/media/django_nova/js/jquery.form.js"></script> | ||
3097 | 7 | {% endblock %} | ||
3098 | 8 | |||
3099 | 9 | |||
3100 | 10 | {% block content %} | ||
3101 | 11 | <div id="right_content"> | ||
3102 | 12 | <div id="page_head"> | ||
3103 | 13 | <h2 id="page_heading">Images</h2> | ||
3104 | 14 | <p id="page_description">Images are snapshots of running systems which can easily be deployed to run one or more instances.</p> | ||
3105 | 15 | </div> | ||
3106 | 16 | |||
3107 | 17 | {% include "django_nova/_messages.html" %} | ||
3108 | 18 | |||
3109 | 19 | {% if images %} | ||
3110 | 20 | <table id="image_launch"> | ||
3111 | 21 | <tr> | ||
3112 | 22 | <th>ID</th> | ||
3113 | 23 | <th>Description</th> | ||
3114 | 24 | <th colspan="2">Owner</th> | ||
3115 | 25 | </tr> | ||
3116 | 26 | {% for image in images %} | ||
3117 | 27 | <tr class="{% cycle 'odd' 'even' %}"> | ||
3118 | 28 | {% if image.id == ami.id %} | ||
3119 | 29 | <td class="detail_wrapper" colspan="4"> | ||
3120 | 30 | <div id="{{ ami.id }}" class="image_detail"> | ||
3121 | 31 | <div class="column"> | ||
3122 | 32 | <div class="image_detail_item"> | ||
3123 | 33 | <span class="label">Owner: </span> | ||
3124 | 34 | <span class="data">{{ ami.ownerId }}</span> | ||
3125 | 35 | </div> | ||
3126 | 36 | |||
3127 | 37 | <div class="image_detail_item"> | ||
3128 | 38 | <span class="label">Description: </span> | ||
3129 | 39 | <span class="data">{{ ami.description }}</span> | ||
3130 | 40 | </div> | ||
3131 | 41 | |||
3132 | 42 | <div class="image_detail_item"> | ||
3133 | 43 | <span class="label">Location: </span> | ||
3134 | 44 | <span class="data">{{ ami.location }}</span> | ||
3135 | 45 | </div> | ||
3136 | 46 | </div> | ||
3137 | 47 | |||
3138 | 48 | <div class="column"> | ||
3139 | 49 | <div class="image_detail_item"> | ||
3140 | 50 | <span class="label">ID: </span> | ||
3141 | 51 | <span class="data">{{ ami.id }}</span> | ||
3142 | 52 | </div> | ||
3143 | 53 | <div class="image_detail_item"> | ||
3144 | 54 | <span class="label">Name: </span> | ||
3145 | 55 | <span class="data">{% if ami.displayName %}{{ ami.displayName }}{%else%}{{ ami.id }}{% endif %}</span> | ||
3146 | 56 | </div> | ||
3147 | 57 | <div class="image_detail_item"> | ||
3148 | 58 | <span class="label">Type: </span> | ||
3149 | 59 | <span class="data">{{ ami.type }}</span> | ||
3150 | 60 | </div> | ||
3151 | 61 | <div class="image_detail_item"> | ||
3152 | 62 | <span class="label">Architecture: </span> | ||
3153 | 63 | <span class="data">{{ ami.architecture }}</span> | ||
3154 | 64 | </div> | ||
3155 | 65 | </div> | ||
3156 | 66 | |||
3157 | 67 | <div id="last" class="column"> | ||
3158 | 68 | {% if ami.is_public %} | ||
3159 | 69 | <div id="public" class="privacy">Public Image</div> | ||
3160 | 70 | {% else %} | ||
3161 | 71 | <div id="private" class="privacy">Private Image</div> | ||
3162 | 72 | {% endif %} | ||
3163 | 73 | |||
3164 | 74 | <a id="launch_{{ image.id }}" class="launch" href="{% url nova_images_launch project.projectname image.id %}" title="Click to launch image">Launch</a> | ||
3165 | 75 | {% if can_modify or user.username == ami.ownerId %} | ||
3166 | 76 | <a id="edit_image_link" href="{% url nova_images_update project.projectname ami.id %}">Edit Image</a> | ||
3167 | 77 | {% endif %} | ||
3168 | 78 | |||
3169 | 79 | </div> | ||
3170 | 80 | |||
3171 | 81 | {% if can_modify or user.username == ami.ownerId %} | ||
3172 | 82 | <span class="image_privacy"> | ||
3173 | 83 | <form id="privacy_{{ ami.id }}" action="{% url nova_images_privacy project.projectname ami.id %}" method="post" accept-charset="utf-8"> | ||
3174 | 84 | {% csrf_token %} | ||
3175 | 85 | {% if ami.is_public %} | ||
3176 | 86 | <input class="private" type="submit" value="Make Private" /> | ||
3177 | 87 | {% else %} | ||
3178 | 88 | <input class="public" type="submit" value="Make Public" /> | ||
3179 | 89 | {% endif %} | ||
3180 | 90 | </form> | ||
3181 | 91 | </span> | ||
3182 | 92 | |||
3183 | 93 | <span class="delete"> | ||
3184 | 94 | <form id="delete_{{ ami.id }}" action="{% url nova_images_remove project.projectname ami.id %}" method="post" accept-charset="utf-8"> | ||
3185 | 95 | {% csrf_token %} | ||
3186 | 96 | <input type="submit" value="Remove Image" /> | ||
3187 | 97 | </form> | ||
3188 | 98 | </span> | ||
3189 | 99 | {% endif %} | ||
3190 | 100 | </div> | ||
3191 | 101 | </td> | ||
3192 | 102 | {% else %} | ||
3193 | 103 | <td class="image_id"><a href="{% url nova_images_detail project.projectname image.id %}">{{ image.id }}</a></td> | ||
3194 | 104 | <td class="image_location odd"> | ||
3195 | 105 | {% if image.description %} | ||
3196 | 106 | {{ image.description }} | ||
3197 | 107 | {% else %} | ||
3198 | 108 | {{ image.location }} | ||
3199 | 109 | {% endif %} | ||
3200 | 110 | </td> | ||
3201 | 111 | <td class="image_owner_id">{{ image.ownerId }}</td> | ||
3202 | 112 | <td class="image_launch_btn odd"><a id="launch_{{ image.id }}" class="launch" href="{% url nova_images_launch project.projectname image.id %}">Launch</a></td> | ||
3203 | 113 | {#<td class="odd"><a class="ui-state-default ui-corner-all" onclick="$('#dlg_launch').dialog('open');">Launch</a></td>#} | ||
3204 | 114 | {% endif %} | ||
3205 | 115 | </tr> | ||
3206 | 116 | {% endfor %} | ||
3207 | 117 | </table> | ||
3208 | 118 | {% else %} | ||
3209 | 119 | <div class="ui-widget"> | ||
3210 | 120 | <div class="ui-state-highlight ui-corner-all"> | ||
3211 | 121 | <p> | ||
3212 | 122 | <span class="ui-icon ui-icon-info"></span> | ||
3213 | 123 | No images currently available. | ||
3214 | 124 | </p> | ||
3215 | 125 | </div> | ||
3216 | 126 | </div> | ||
3217 | 127 | {% endif %} | ||
3218 | 128 | </div> | ||
3219 | 129 | |||
3220 | 130 | <div id="dlg_launch" title="Launch Instance" style="display:none;"> | ||
3221 | 131 | <form id="frm_launch" action="url nova_images_launch project.projectname" method="post"> | ||
3222 | 132 | {% csrf_token %} | ||
3223 | 133 | {% include "django_nova/images/_launch_form.html" %} | ||
3224 | 134 | </form> | ||
3225 | 135 | </div> | ||
3226 | 136 | |||
3227 | 137 | <div id="dlg_confirm" title="Confirm Termination"> | ||
3228 | 138 | <p>Are you sure you wish to unregister the <span id="ami_name"></span> image?</p> | ||
3229 | 139 | </div> | ||
3230 | 140 | |||
3231 | 141 | {% endblock %} | ||
3232 | 142 | |||
3233 | 143 | {% block footerjs %} | ||
3234 | 144 | {{ block.super }} | ||
3235 | 145 | <script type="text/javascript"> | ||
3236 | 146 | var options = { | ||
3237 | 147 | success: handleResponse, | ||
3238 | 148 | beforeSubmit: showRequest, | ||
3239 | 149 | dataType: 'json' | ||
3240 | 150 | } | ||
3241 | 151 | |||
3242 | 152 | // TODO: On dialog open, reset form and validation. | ||
3243 | 153 | $(function() { | ||
3244 | 154 | $('#dlg_launch').dialog({ | ||
3245 | 155 | buttons: { | ||
3246 | 156 | 'Ok': function() { | ||
3247 | 157 | $('#frm_launch').ajaxSubmit(options); | ||
3248 | 158 | }, | ||
3249 | 159 | 'Cancel': function() { | ||
3250 | 160 | $(this).dialog('close'); | ||
3251 | 161 | } | ||
3252 | 162 | }, | ||
3253 | 163 | autoOpen: false, | ||
3254 | 164 | resizable: false, | ||
3255 | 165 | width: 400, | ||
3256 | 166 | height: 400 | ||
3257 | 167 | }); | ||
3258 | 168 | }); | ||
3259 | 169 | |||
3260 | 170 | function showRequest(formData, jqForm, options) { | ||
3261 | 171 | var queryString = $.param(formData); | ||
3262 | 172 | alert('About to submit: \n\n' + queryString); | ||
3263 | 173 | return true; | ||
3264 | 174 | } | ||
3265 | 175 | |||
3266 | 176 | function handleResponse(data, statusText, xhr, $form) { | ||
3267 | 177 | alert('status: ' + statusText + '\nsuccess:\n\n' + data.success); | ||
3268 | 178 | } | ||
3269 | 179 | |||
3270 | 180 | $(function(){ | ||
3271 | 181 | $('.delete form').submit(function() { | ||
3272 | 182 | ami_name = $(this).parent().parent().attr("id"); | ||
3273 | 183 | $('#ami_name').text(ami_name); | ||
3274 | 184 | $('#dlg_confirm').dialog('open'); | ||
3275 | 185 | return false; | ||
3276 | 186 | }); | ||
3277 | 187 | |||
3278 | 188 | $('#dlg_confirm').dialog({ | ||
3279 | 189 | buttons: { | ||
3280 | 190 | 'Ok': onConfirmOK, | ||
3281 | 191 | 'Cancel': function() { $(this).dialog('close'); } | ||
3282 | 192 | }, | ||
3283 | 193 | autoOpen: false, | ||
3284 | 194 | resizable: false, | ||
3285 | 195 | width: 500, | ||
3286 | 196 | height: 200 | ||
3287 | 197 | }); | ||
3288 | 198 | }) | ||
3289 | 199 | |||
3290 | 200 | function onConfirmOK() { | ||
3291 | 201 | $(this).dialog('close'); | ||
3292 | 202 | form = document.getElementById('delete_' + ami_name); | ||
3293 | 203 | if(form) form.submit(); | ||
3294 | 204 | } | ||
3295 | 205 | |||
3296 | 206 | </script> | ||
3297 | 207 | {% endblock %} | ||
3298 | 208 | 0 | ||
3299 | === removed file 'src/django_nova/templates/django_nova/images/edit.html' | |||
3300 | --- src/django_nova/templates/django_nova/images/edit.html 2011-01-16 21:28:02 +0000 | |||
3301 | +++ src/django_nova/templates/django_nova/images/edit.html 1970-01-01 00:00:00 +0000 | |||
3302 | @@ -1,35 +0,0 @@ | |||
3303 | 1 | {% extends "django_nova/images/base.html" %} | ||
3304 | 2 | |||
3305 | 3 | {% block title %} - Cloud Computing{% endblock %} | ||
3306 | 4 | |||
3307 | 5 | {% block headerjs %} | ||
3308 | 6 | <script type="text/javascript" src="{{ COMMON_MEDIA_PREFIX }}js/jquery.form.js"></script> | ||
3309 | 7 | {% endblock %} | ||
3310 | 8 | |||
3311 | 9 | {% block content %} | ||
3312 | 10 | <div id="right_content"> | ||
3313 | 11 | <div id="page_head"> | ||
3314 | 12 | <h2 id="page_heading">Edit Image</h2> | ||
3315 | 13 | <p id="page_description">From this page you can edit the name and description of an image that belongs to you.</p> | ||
3316 | 14 | </div> | ||
3317 | 15 | |||
3318 | 16 | <div class="dash_block first"> | ||
3319 | 17 | <h3 class="image_id">Edit Image: {{ ami.id }}</h3> | ||
3320 | 18 | |||
3321 | 19 | <form class="edit_image" id="rename_{{ ami.id }}" action="{% url nova_images_update project.projectname ami.id %}" method="post"> | ||
3322 | 20 | <fieldset> | ||
3323 | 21 | {% csrf_token %} | ||
3324 | 22 | {% for field in form %} | ||
3325 | 23 | |||
3326 | 24 | {{ field.label_tag }} | ||
3327 | 25 | {% if field.errors %}{{ field.errors }}{% endif %} | ||
3328 | 26 | {{ field }} | ||
3329 | 27 | {% endfor %} | ||
3330 | 28 | <input type="submit" value="Update Image" /> | ||
3331 | 29 | </fieldset> | ||
3332 | 30 | </form> | ||
3333 | 31 | |||
3334 | 32 | </div> | ||
3335 | 33 | </div> | ||
3336 | 34 | |||
3337 | 35 | {% endblock %} | ||
3338 | 36 | 0 | ||
3339 | === removed file 'src/django_nova/templates/django_nova/images/index.html' | |||
3340 | --- src/django_nova/templates/django_nova/images/index.html 2011-01-17 06:58:19 +0000 | |||
3341 | +++ src/django_nova/templates/django_nova/images/index.html 1970-01-01 00:00:00 +0000 | |||
3342 | @@ -1,70 +0,0 @@ | |||
3343 | 1 | {% extends "django_nova/images/base.html" %} | ||
3344 | 2 | |||
3345 | 3 | {% block title %} - Launch an Image{% endblock %} | ||
3346 | 4 | |||
3347 | 5 | {% block headerjs %} | ||
3348 | 6 | <script type="text/javascript" src="/media/django_nova/js/jquery.form.js"></script> | ||
3349 | 7 | {% endblock %} | ||
3350 | 8 | |||
3351 | 9 | |||
3352 | 10 | {% block content %} | ||
3353 | 11 | <div id="right_content"> | ||
3354 | 12 | <div id="page_head"> | ||
3355 | 13 | <h2 id="page_heading">Images</h2> | ||
3356 | 14 | <p id="page_description">Images are snapshots of running systems which can easily be deployed to run one or more instances.</p> | ||
3357 | 15 | </div> | ||
3358 | 16 | |||
3359 | 17 | {% include "django_nova/_messages.html" %} | ||
3360 | 18 | |||
3361 | 19 | {% for heading, images in image_lists.items %} | ||
3362 | 20 | {% include "django_nova/images/_list.html" %} | ||
3363 | 21 | {% endfor %} | ||
3364 | 22 | |||
3365 | 23 | </div> | ||
3366 | 24 | |||
3367 | 25 | <div id="dlg_launch" title="Launch Instance" style="display:none;"> | ||
3368 | 26 | <form id="frm_launch" action="#" method="post"> | ||
3369 | 27 | {% csrf_token %} | ||
3370 | 28 | {% include "django_nova/images/_launch_form.html" %} | ||
3371 | 29 | </form> | ||
3372 | 30 | </div> | ||
3373 | 31 | {% endblock %} | ||
3374 | 32 | |||
3375 | 33 | {% block footerjs %} | ||
3376 | 34 | {{ block.super }} | ||
3377 | 35 | <script type="text/javascript"> | ||
3378 | 36 | var options = { | ||
3379 | 37 | success: handleResponse, | ||
3380 | 38 | beforeSubmit: showRequest, | ||
3381 | 39 | dataType: 'json' | ||
3382 | 40 | } | ||
3383 | 41 | |||
3384 | 42 | // TODO: On dialog open, reset form and validation. | ||
3385 | 43 | $(function() { | ||
3386 | 44 | $('#dlg_launch').dialog({ | ||
3387 | 45 | buttons: { | ||
3388 | 46 | 'Ok': function() { | ||
3389 | 47 | $('#frm_launch').ajaxSubmit(options); | ||
3390 | 48 | }, | ||
3391 | 49 | 'Cancel': function() { | ||
3392 | 50 | $(this).dialog('close'); | ||
3393 | 51 | } | ||
3394 | 52 | }, | ||
3395 | 53 | autoOpen: false, | ||
3396 | 54 | resizable: false, | ||
3397 | 55 | width: 400, | ||
3398 | 56 | height: 400 | ||
3399 | 57 | }); | ||
3400 | 58 | }); | ||
3401 | 59 | |||
3402 | 60 | function showRequest(formData, jqForm, options) { | ||
3403 | 61 | var queryString = $.param(formData); | ||
3404 | 62 | alert('About to submit: \n\n' + queryString); | ||
3405 | 63 | return true; | ||
3406 | 64 | } | ||
3407 | 65 | |||
3408 | 66 | function handleResponse(data, statusText, xhr, $form) { | ||
3409 | 67 | alert('status: ' + statusText + '\nsuccess:\n\n' + data.success); | ||
3410 | 68 | } | ||
3411 | 69 | </script> | ||
3412 | 70 | {% endblock %} | ||
3413 | 71 | 0 | ||
3414 | === removed file 'src/django_nova/templates/django_nova/images/launch.html' | |||
3415 | --- src/django_nova/templates/django_nova/images/launch.html 2011-01-16 21:28:02 +0000 | |||
3416 | +++ src/django_nova/templates/django_nova/images/launch.html 1970-01-01 00:00:00 +0000 | |||
3417 | @@ -1,32 +0,0 @@ | |||
3418 | 1 | {% extends "django_nova/images/base.html" %} | ||
3419 | 2 | |||
3420 | 3 | {% block title %} - Cloud Computing{% endblock %} | ||
3421 | 4 | |||
3422 | 5 | {% block headerjs %} | ||
3423 | 6 | <script type="text/javascript" src="{{ COMMON_MEDIA_PREFIX }}js/jquery.form.js"></script> | ||
3424 | 7 | {% endblock %} | ||
3425 | 8 | |||
3426 | 9 | {% block content %} | ||
3427 | 10 | <div id="right_content"> | ||
3428 | 11 | <div id="page_head"> | ||
3429 | 12 | <h2 id="page_heading">Launch Image</h2> | ||
3430 | 13 | <p id="page_description">You can launch up to five instances of an image at a time. Some images allow for custom configuration to be passed in via User data. (<a href="/kb/show/UserData/">read more</a>)</p> | ||
3431 | 14 | </div> | ||
3432 | 15 | |||
3433 | 16 | <div class="dash_block first"> | ||
3434 | 17 | <form id="frm_launch" action="{% url nova_images_launch project.projectname ami.id %}" method="post"> | ||
3435 | 18 | {% csrf_token %} | ||
3436 | 19 | <fieldset> | ||
3437 | 20 | <h3 class="image_id">Launch Image {{ ami.id }}</h3> | ||
3438 | 21 | <div class="even"> | ||
3439 | 22 | <label>Location</label> | ||
3440 | 23 | <span class="image_location">{{ ami.location }}</span> | ||
3441 | 24 | </div> | ||
3442 | 25 | {% include "django_nova/images/_launch_form.html" %} | ||
3443 | 26 | <input id="launch_image" type="submit" value="Launch" /> | ||
3444 | 27 | </fieldset> | ||
3445 | 28 | </form> | ||
3446 | 29 | </div> | ||
3447 | 30 | </div> | ||
3448 | 31 | |||
3449 | 32 | {% endblock %} | ||
3450 | 33 | 0 | ||
3451 | === removed directory 'src/django_nova/templates/django_nova/instances' | |||
3452 | === removed file 'src/django_nova/templates/django_nova/instances/_instances_list.html' | |||
3453 | --- src/django_nova/templates/django_nova/instances/_instances_list.html 2011-01-12 20:02:06 +0000 | |||
3454 | +++ src/django_nova/templates/django_nova/instances/_instances_list.html 1970-01-01 00:00:00 +0000 | |||
3455 | @@ -1,104 +0,0 @@ | |||
3456 | 1 | {% if instances %} | ||
3457 | 2 | <table style="width: 100%"> | ||
3458 | 3 | <tr> | ||
3459 | 4 | <th>ID</th> | ||
3460 | 5 | <th>Image</th> | ||
3461 | 6 | <th>Size</th> | ||
3462 | 7 | <th>IP</th> | ||
3463 | 8 | <th colspan="2">State</th> | ||
3464 | 9 | </tr> | ||
3465 | 10 | {% for instance in instances %} | ||
3466 | 11 | <tr class="{% cycle 'odd' 'even' %}"> | ||
3467 | 12 | {% if instance.id == selected_instance.id %} | ||
3468 | 13 | <td class="detail_wrapper" colspan="6"> | ||
3469 | 14 | <div id="{{selected_instance.id}}" class="instance_detail"> | ||
3470 | 15 | <div class="column"> | ||
3471 | 16 | <div class="instance_detail_item"> | ||
3472 | 17 | <span class="label">Instance ID: </span> | ||
3473 | 18 | <span class="data">{{ selected_instance.id }}</span> | ||
3474 | 19 | </div> | ||
3475 | 20 | <div class="instance_detail_item"> | ||
3476 | 21 | <span class="label">Name: </span> | ||
3477 | 22 | <span class="data">{% if selected_instance.displayName != "" %}{{ selected_instance.displayName }}{% else %} None {% endif %}</span> | ||
3478 | 23 | </div> | ||
3479 | 24 | <div class="instance_detail_item"> | ||
3480 | 25 | <span class="label">Description: </span> | ||
3481 | 26 | <span class="data" id="desc">{{ selected_instance.displayDescription }}</span> | ||
3482 | 27 | </div> | ||
3483 | 28 | </div> | ||
3484 | 29 | |||
3485 | 30 | <div class="column"> | ||
3486 | 31 | <div class="instance_detail_item"> | ||
3487 | 32 | <span class="label">Region: </span> | ||
3488 | 33 | <span class="data">{{ selected_instance.region.name }}</span> | ||
3489 | 34 | </div> | ||
3490 | 35 | <div class="instance_detail_item"> | ||
3491 | 36 | <span class="label">Size: </span> | ||
3492 | 37 | <span class="data">{{ selected_instance.instance_type }}</span> | ||
3493 | 38 | </div> | ||
3494 | 39 | <div class="instance_detail_item"> | ||
3495 | 40 | <span class="label">State: </span> | ||
3496 | 41 | <span class="data">{{ selected_instance.state }}</span> | ||
3497 | 42 | </div> | ||
3498 | 43 | <div class="instance_detail_item"> | ||
3499 | 44 | <span class="label">Image ID: </span> | ||
3500 | 45 | <span class="data">{{ selected_instance.image_id }}</span> | ||
3501 | 46 | </div> | ||
3502 | 47 | <div class="instance_detail_item"> | ||
3503 | 48 | <span class="label">IP Address: </span> | ||
3504 | 49 | <span class="data">{{ selected_instance.dns_name }}</span> | ||
3505 | 50 | </div> | ||
3506 | 51 | |||
3507 | 52 | </div> | ||
3508 | 53 | |||
3509 | 54 | <div id="last" class="column"> | ||
3510 | 55 | {% if instance.state == "running" %} | ||
3511 | 56 | <a href="{% url nova_instances_console project.projectname instance.id %}" id="console_{{instance.id}}" class="console" target="_blank">Show Console</a>{% endif %} | ||
3512 | 57 | <a id="edit_instance_link" href="{% url nova_instance_update project.projectname instance.id %}">Edit Instance</a> | ||
3513 | 58 | |||
3514 | 59 | |||
3515 | 60 | </div> | ||
3516 | 61 | |||
3517 | 62 | <span class="delete"> | ||
3518 | 63 | <form id="form_terminate_{{ instance.id }}" class="form-terminate" method="post" action="{% url nova_instances_terminate project.projectname %}" > | ||
3519 | 64 | <input name="instance_id" type="hidden" value="{{ instance.id }}" /> | ||
3520 | 65 | <input id="terminate_{{instance.id}}" class="terminate" type="submit" value="Terminate" /> | ||
3521 | 66 | {% csrf_token %} | ||
3522 | 67 | </form> | ||
3523 | 68 | </span> | ||
3524 | 69 | |||
3525 | 70 | </div> | ||
3526 | 71 | |||
3527 | 72 | </td> | ||
3528 | 73 | {% else %} | ||
3529 | 74 | |||
3530 | 75 | <td><a href="{% url nova_instances_detail project.projectname instance.id %}">{{ instance.id }} {% if instance.displayName %}({{ instance.displayName }}){% endif %} | ||
3531 | 76 | </a></td> | ||
3532 | 77 | <td class="odd">{{ instance.image_id }}</td> | ||
3533 | 78 | <td>{{ instance.instance_type }}</td> | ||
3534 | 79 | <td class="odd">{{ instance.dns_name }}</td> | ||
3535 | 80 | <td>{{ instance.state }}</td> | ||
3536 | 81 | <td id="actions" class="odd"> | ||
3537 | 82 | <form id="form_terminate_{{ instance.id }}" class="form-terminate" method="post" action="{% url nova_instances_terminate project.projectname %}" > | ||
3538 | 83 | <input name="instance_id" type="hidden" value="{{ instance.id }}" /> | ||
3539 | 84 | <input id="terminate_{{instance.id}}" class="terminate" type="submit" value="Terminate" /> | ||
3540 | 85 | {% csrf_token %} | ||
3541 | 86 | </form> | ||
3542 | 87 | {% if instance.state == "running" %} | ||
3543 | 88 | <a href="{% url nova_instances_console project.projectname instance.id %}" id="console_{{instance.id}}" class="console" target="_blank">Show Console</a> | ||
3544 | 89 | {% endif %} | ||
3545 | 90 | </td> | ||
3546 | 91 | {% endif %} | ||
3547 | 92 | </tr> | ||
3548 | 93 | {% endfor %} | ||
3549 | 94 | </table> | ||
3550 | 95 | {% else %} | ||
3551 | 96 | <div class="ui-widget"> | ||
3552 | 97 | <div class="ui-state-highlight ui-corner-all"> | ||
3553 | 98 | <p> | ||
3554 | 99 | <span class="ui-icon ui-icon-info"></span> | ||
3555 | 100 | No instances are currently running. You may start a new instance from the <a href="{% url nova_images project.projectname %}">images</a> tab. | ||
3556 | 101 | </p> | ||
3557 | 102 | </div> | ||
3558 | 103 | </div> | ||
3559 | 104 | {% endif %} | ||
3560 | 105 | 0 | ||
3561 | === removed file 'src/django_nova/templates/django_nova/instances/base.html' | |||
3562 | --- src/django_nova/templates/django_nova/instances/base.html 2011-01-17 05:55:41 +0000 | |||
3563 | +++ src/django_nova/templates/django_nova/instances/base.html 1970-01-01 00:00:00 +0000 | |||
3564 | @@ -1,7 +0,0 @@ | |||
3565 | 1 | {% extends "django_nova/base.html" %} | ||
3566 | 2 | {% load sidebar_tags %} | ||
3567 | 3 | |||
3568 | 4 | {% block nav_projects %} | ||
3569 | 5 | {% sidebar_select instances %} | ||
3570 | 6 | {{ block.super }} | ||
3571 | 7 | {% endblock %} | ||
3572 | 8 | \ No newline at end of file | 0 | \ No newline at end of file |
3573 | 9 | 1 | ||
3574 | === removed file 'src/django_nova/templates/django_nova/instances/detail_list.html' | |||
3575 | --- src/django_nova/templates/django_nova/instances/detail_list.html 2011-01-17 05:55:41 +0000 | |||
3576 | +++ src/django_nova/templates/django_nova/instances/detail_list.html 1970-01-01 00:00:00 +0000 | |||
3577 | @@ -1,33 +0,0 @@ | |||
3578 | 1 | {% extends "django_nova/instances/base.html" %} | ||
3579 | 2 | |||
3580 | 3 | {% block title %} - Cloud Computing{% endblock %} | ||
3581 | 4 | |||
3582 | 5 | {% block content %} | ||
3583 | 6 | |||
3584 | 7 | <div id="right_content"> | ||
3585 | 8 | <div id="page_head"> | ||
3586 | 9 | <h2 id="page_heading">Instance ID: {{ instance.id }}</h2> | ||
3587 | 10 | <p id="page_description">Here you can see up to the minute performance data about your instance.</p> | ||
3588 | 11 | </div> | ||
3589 | 12 | |||
3590 | 13 | {% include "django_nova/_messages.html" %} | ||
3591 | 14 | |||
3592 | 15 | |||
3593 | 16 | <div class="dash_block first"> | ||
3594 | 17 | <h3 class="image_id">Edit Instance: {{ instance.id }}</h3> | ||
3595 | 18 | |||
3596 | 19 | <form class="edit_instance" id="rename_{{ instance.id }}" action="{% url nova_instance_update project.projectname instance.id %}" method="post"> | ||
3597 | 20 | <fieldset> | ||
3598 | 21 | {% csrf_token %} | ||
3599 | 22 | {% for field in form %} | ||
3600 | 23 | |||
3601 | 24 | {{ field.label_tag }} | ||
3602 | 25 | {% if field.errors %}{{ field.errors }}{% endif %} | ||
3603 | 26 | {{ field }} | ||
3604 | 27 | {% endfor %} | ||
3605 | 28 | <input type="submit" value="Update Instance" /> | ||
3606 | 29 | </fieldset> | ||
3607 | 30 | </form> | ||
3608 | 31 | </div> | ||
3609 | 32 | |||
3610 | 33 | {% endblock %} | ||
3611 | 34 | 0 | ||
3612 | === removed file 'src/django_nova/templates/django_nova/instances/edit.html' | |||
3613 | --- src/django_nova/templates/django_nova/instances/edit.html 2011-01-17 05:55:41 +0000 | |||
3614 | +++ src/django_nova/templates/django_nova/instances/edit.html 1970-01-01 00:00:00 +0000 | |||
3615 | @@ -1,34 +0,0 @@ | |||
3616 | 1 | {% extends "django_nova/instances/base.html" %} | ||
3617 | 2 | |||
3618 | 3 | {% block title %} - Cloud Computing{% endblock %} | ||
3619 | 4 | |||
3620 | 5 | {% block headerjs %} | ||
3621 | 6 | <script type="text/javascript" src="{{ COMMON_MEDIA_PREFIX }}js/jquery.form.js"></script> | ||
3622 | 7 | {% endblock %} | ||
3623 | 8 | |||
3624 | 9 | {% block content %} | ||
3625 | 10 | <div id="right_content"> | ||
3626 | 11 | <div id="page_head"> | ||
3627 | 12 | <h2 id="page_heading">Edit Instance</h2> | ||
3628 | 13 | <p id="page_description">From this page you can give your instance an alias, so you don't have to remember its unique id.</p> | ||
3629 | 14 | </div> | ||
3630 | 15 | |||
3631 | 16 | <div class="dash_block first"> | ||
3632 | 17 | <h3 class="image_id">Edit Instance: {{ instance.id }}</h3> | ||
3633 | 18 | |||
3634 | 19 | <form class="edit_instance" id="rename_{{ selected_instance.id }}" action="{% url nova_instance_update project.projectname instance.id %}" method="post"> | ||
3635 | 20 | <fieldset> | ||
3636 | 21 | {% csrf_token %} | ||
3637 | 22 | {% for field in update_form %} | ||
3638 | 23 | |||
3639 | 24 | {{ field.label_tag }} | ||
3640 | 25 | {% if field.errors %}{{ field.errors }}{% endif %} | ||
3641 | 26 | {{ field }} | ||
3642 | 27 | {% endfor %} | ||
3643 | 28 | <input type="submit" value="Update Instance" /> | ||
3644 | 29 | </fieldset> | ||
3645 | 30 | </form> | ||
3646 | 31 | </div> | ||
3647 | 32 | </div> | ||
3648 | 33 | |||
3649 | 34 | {% endblock %} | ||
3650 | 35 | 0 | ||
3651 | === removed file 'src/django_nova/templates/django_nova/instances/index.html' | |||
3652 | --- src/django_nova/templates/django_nova/instances/index.html 2011-02-27 21:52:13 +0000 | |||
3653 | +++ src/django_nova/templates/django_nova/instances/index.html 1970-01-01 00:00:00 +0000 | |||
3654 | @@ -1,98 +0,0 @@ | |||
3655 | 1 | {% extends "django_nova/instances/base.html" %} | ||
3656 | 2 | |||
3657 | 3 | {% block title %} - {{ project.projectname|capfirst }} Instances{% endblock %} | ||
3658 | 4 | {% block pageclass %}instances{% endblock %} | ||
3659 | 5 | |||
3660 | 6 | {% block content %} | ||
3661 | 7 | <div id="page_head"> | ||
3662 | 8 | <div id="spinner"></div> | ||
3663 | 9 | |||
3664 | 10 | <h2 id="page_heading">Instances</h2> | ||
3665 | 11 | <p id="page_description">Instances are virtual servers launched from images. You can launch instances from the <a href="{% url nova_images project.projectname %}">images tab</a>.</p> | ||
3666 | 12 | </div> | ||
3667 | 13 | |||
3668 | 14 | {% include "django_nova/_messages.html" %} | ||
3669 | 15 | |||
3670 | 16 | <div id="instances"> | ||
3671 | 17 | {% include "django_nova/instances/_instances_list.html" %} | ||
3672 | 18 | </div> | ||
3673 | 19 | |||
3674 | 20 | <div id="dlg_confirm" title="Confirm Termination" style="display:none;"> | ||
3675 | 21 | <p>Are you sure you wish to terminate instance <span id="spn_terminate"></span>?</p> | ||
3676 | 22 | </div> | ||
3677 | 23 | |||
3678 | 24 | <div id="connection_error" style="display:none;" title="Connection Error"> | ||
3679 | 25 | <p><span class="ui-icon ui-icon-alert"></span>A connection error has occurred. Please ensure you are still connected to VPN.</p> | ||
3680 | 26 | </div> | ||
3681 | 27 | {% endblock %} | ||
3682 | 28 | |||
3683 | 29 | {% block footerjs %} | ||
3684 | 30 | {{ block.super }} | ||
3685 | 31 | <script type="text/javascript"> | ||
3686 | 32 | |||
3687 | 33 | $(function() { | ||
3688 | 34 | setInterval(function() { | ||
3689 | 35 | $('#spinner').show(); | ||
3690 | 36 | {% if detail %} | ||
3691 | 37 | $('#instances').load('{% url nova_instances_refresh_detail project.projectname selected_instance.id %}', onInstancesUpdated); | ||
3692 | 38 | {% else %} | ||
3693 | 39 | $('#instances').load('{% url nova_instances_refresh project.projectname %}', onInstancesUpdated); | ||
3694 | 40 | {% endif %} | ||
3695 | 41 | }, 15000); | ||
3696 | 42 | |||
3697 | 43 | initInstanceForms(); | ||
3698 | 44 | |||
3699 | 45 | $('#dlg_confirm').dialog({ | ||
3700 | 46 | buttons: { | ||
3701 | 47 | 'Ok': onConfirmOK, | ||
3702 | 48 | 'Cancel': function() { $(this).dialog('close'); } | ||
3703 | 49 | }, | ||
3704 | 50 | autoOpen: false, | ||
3705 | 51 | resizable: false, | ||
3706 | 52 | width: 500, | ||
3707 | 53 | height: 200 | ||
3708 | 54 | }); | ||
3709 | 55 | }); | ||
3710 | 56 | |||
3711 | 57 | var _terminateID = null; | ||
3712 | 58 | |||
3713 | 59 | function initInstanceForms() { | ||
3714 | 60 | $('.form-terminate').submit(function() { | ||
3715 | 61 | _terminateID = $(this).children(':first').val() | ||
3716 | 62 | $('#spn_terminate').text(_terminateID); | ||
3717 | 63 | $('#dlg_confirm').dialog('open'); | ||
3718 | 64 | return false; | ||
3719 | 65 | }); | ||
3720 | 66 | } | ||
3721 | 67 | |||
3722 | 68 | function onInstancesUpdated(response, status, xhr) { | ||
3723 | 69 | $('#spinner').hide(); | ||
3724 | 70 | |||
3725 | 71 | switch(xhr.status) { | ||
3726 | 72 | case 200: | ||
3727 | 73 | initInstanceForms(); | ||
3728 | 74 | break; | ||
3729 | 75 | |||
3730 | 76 | case 403: | ||
3731 | 77 | document.location = '{% url auth_login %}'; | ||
3732 | 78 | break; | ||
3733 | 79 | |||
3734 | 80 | default: | ||
3735 | 81 | $('#connection_error').dialog({ | ||
3736 | 82 | dialogClass: 'alert', | ||
3737 | 83 | modal: true, | ||
3738 | 84 | closeOnEscape: true, | ||
3739 | 85 | buttons:{ "Close": function() { $(this).dialog("close"); } }, | ||
3740 | 86 | }); | ||
3741 | 87 | $('#connection_error').dialog('open'); | ||
3742 | 88 | break; | ||
3743 | 89 | } | ||
3744 | 90 | } | ||
3745 | 91 | |||
3746 | 92 | function onConfirmOK() { | ||
3747 | 93 | $(this).dialog('close'); | ||
3748 | 94 | form = document.getElementById('form_terminate_' + _terminateID); | ||
3749 | 95 | if(form) form.submit(); | ||
3750 | 96 | } | ||
3751 | 97 | </script> | ||
3752 | 98 | {% endblock %} | ||
3753 | 99 | 0 | ||
3754 | === removed file 'src/django_nova/templates/django_nova/instances/performance.html' | |||
3755 | --- src/django_nova/templates/django_nova/instances/performance.html 2011-01-17 05:55:41 +0000 | |||
3756 | +++ src/django_nova/templates/django_nova/instances/performance.html 1970-01-01 00:00:00 +0000 | |||
3757 | @@ -1,58 +0,0 @@ | |||
3758 | 1 | {% extends "django_nova/instances/base.html" %} | ||
3759 | 2 | |||
3760 | 3 | {% block title %} - Cloud Computing{% endblock %} | ||
3761 | 4 | |||
3762 | 5 | {% block content %} | ||
3763 | 6 | |||
3764 | 7 | <div id="right_content"> | ||
3765 | 8 | <div id="page_head"> | ||
3766 | 9 | <h2 id="page_heading">Instance ID: {{ instance.id }} Performance</h2> | ||
3767 | 10 | <p id="page_description">Here you can see up to the minute performance data about your instance.</p> | ||
3768 | 11 | </div> | ||
3769 | 12 | |||
3770 | 13 | {% include "django_nova/_messages.html" %} | ||
3771 | 14 | |||
3772 | 15 | <p> | ||
3773 | 16 | <h1>CPU Usage</h1> | ||
3774 | 17 | <h3>Today</h3> | ||
3775 | 18 | <img src="{% url nova_instances_graph project.projectname instance.id "cpu-1d.png" %}" /> | ||
3776 | 19 | </p> | ||
3777 | 20 | <p> | ||
3778 | 21 | <h3>This Week</h3> | ||
3779 | 22 | <img src="{% url nova_instances_graph project.projectname instance.id "cpu-1w.png" %}" /> | ||
3780 | 23 | </p> | ||
3781 | 24 | <p> | ||
3782 | 25 | <h3>This Month</h3> | ||
3783 | 26 | <img src="{% url nova_instances_graph project.projectname instance.id "cpu-1m.png" %}" /> | ||
3784 | 27 | </p> | ||
3785 | 28 | |||
3786 | 29 | <p> | ||
3787 | 30 | <h1>Network Activity</h1> | ||
3788 | 31 | <h3>Today</h3> | ||
3789 | 32 | <img src="{% url nova_instances_graph project.projectname instance.id "net-1d.png" %}" /> | ||
3790 | 33 | </p> | ||
3791 | 34 | <p> | ||
3792 | 35 | <h3>This Week</h3> | ||
3793 | 36 | <img src="{% url nova_instances_graph project.projectname instance.id "net-1w.png" %}" /> | ||
3794 | 37 | </p> | ||
3795 | 38 | <p> | ||
3796 | 39 | <h3>This Month</h3> | ||
3797 | 40 | <img src="{% url nova_instances_graph project.projectname instance.id "net-1m.png" %}" /> | ||
3798 | 41 | </p> | ||
3799 | 42 | |||
3800 | 43 | <p> | ||
3801 | 44 | <h1>Disk Activity</h3> | ||
3802 | 45 | <h3>Today</h3> | ||
3803 | 46 | <img src="{% url nova_instances_graph project.projectname instance.id "disk-1d.png" %}" /> | ||
3804 | 47 | </p> | ||
3805 | 48 | <p> | ||
3806 | 49 | <h3>This Week</h3> | ||
3807 | 50 | <img src="{% url nova_instances_graph project.projectname instance.id "disk-1w.png" %}" /> | ||
3808 | 51 | </p> | ||
3809 | 52 | <p> | ||
3810 | 53 | <h3>This Month</h3> | ||
3811 | 54 | <img src="{% url nova_instances_graph project.projectname instance.id "disk-1m.png" %}" /> | ||
3812 | 55 | </p> | ||
3813 | 56 | </div> | ||
3814 | 57 | |||
3815 | 58 | {% endblock %} | ||
3816 | 59 | 0 | ||
3817 | === removed directory 'src/django_nova/templates/django_nova/keypairs' | |||
3818 | === removed file 'src/django_nova/templates/django_nova/keypairs/_create_form.html' | |||
3819 | --- src/django_nova/templates/django_nova/keypairs/_create_form.html 2011-01-12 20:02:06 +0000 | |||
3820 | +++ src/django_nova/templates/django_nova/keypairs/_create_form.html 1970-01-01 00:00:00 +0000 | |||
3821 | @@ -1,5 +0,0 @@ | |||
3822 | 1 | {% for field in create_form %} | ||
3823 | 2 | {{ field.label_tag }} | ||
3824 | 3 | {% if field.errors %}{{ field.errors }}{% endif %} | ||
3825 | 4 | {{ field }} | ||
3826 | 5 | {% endfor %} | ||
3827 | 6 | 0 | ||
3828 | === removed file 'src/django_nova/templates/django_nova/keypairs/_list.html' | |||
3829 | --- src/django_nova/templates/django_nova/keypairs/_list.html 2011-01-12 20:02:06 +0000 | |||
3830 | +++ src/django_nova/templates/django_nova/keypairs/_list.html 1970-01-01 00:00:00 +0000 | |||
3831 | @@ -1,31 +0,0 @@ | |||
3832 | 1 | {% if keypairs %} | ||
3833 | 2 | <table style="width: 100%"> | ||
3834 | 3 | <tr> | ||
3835 | 4 | <th>Key Pair Name</th> | ||
3836 | 5 | <th>Fingerprint</th> | ||
3837 | 6 | <th> </th> | ||
3838 | 7 | </tr> | ||
3839 | 8 | {% for keypair in keypairs %} | ||
3840 | 9 | <tr class="{% cycle 'odd' 'even' %}"> | ||
3841 | 10 | <td>{{ keypair.name }}</td> | ||
3842 | 11 | <td class="odd">{{ keypair.fingerprint }}</td> | ||
3843 | 12 | <td> | ||
3844 | 13 | <form id="form_key_delete_{{keypair.name}}" class="form-key-delete" method="post" action="{% url nova_keypairs_delete project.projectname %}"> | ||
3845 | 14 | <input name="key_name" type="hidden" value="{{ keypair.name }}" /> | ||
3846 | 15 | <input id="keypair_delete_{{keypair.name}}" class="delete" type="submit" value="Delete" /> | ||
3847 | 16 | {% csrf_token %} | ||
3848 | 17 | </form> | ||
3849 | 18 | </td> | ||
3850 | 19 | </tr> | ||
3851 | 20 | {% endfor %} | ||
3852 | 21 | </table> | ||
3853 | 22 | {% else %} | ||
3854 | 23 | <div class="ui-widget"> | ||
3855 | 24 | <div class="ui-state-highlight ui-corner-all"> | ||
3856 | 25 | <p> | ||
3857 | 26 | <span class="ui-icon ui-icon-info"></span> | ||
3858 | 27 | No key pairs currently exist. | ||
3859 | 28 | </p> | ||
3860 | 29 | </div> | ||
3861 | 30 | </div> | ||
3862 | 31 | {% endif %} | ||
3863 | 32 | 0 | ||
3864 | === removed file 'src/django_nova/templates/django_nova/keypairs/base.html' | |||
3865 | --- src/django_nova/templates/django_nova/keypairs/base.html 2011-01-17 05:55:41 +0000 | |||
3866 | +++ src/django_nova/templates/django_nova/keypairs/base.html 1970-01-01 00:00:00 +0000 | |||
3867 | @@ -1,7 +0,0 @@ | |||
3868 | 1 | {% extends "django_nova/base.html" %} | ||
3869 | 2 | {% load sidebar_tags %} | ||
3870 | 3 | |||
3871 | 4 | {% block nav_projects %} | ||
3872 | 5 | {% sidebar_select keys %} | ||
3873 | 6 | {{ block.super }} | ||
3874 | 7 | {% endblock %} | ||
3875 | 8 | \ No newline at end of file | 0 | \ No newline at end of file |
3876 | 9 | 1 | ||
3877 | === removed file 'src/django_nova/templates/django_nova/keypairs/index.html' | |||
3878 | --- src/django_nova/templates/django_nova/keypairs/index.html 2011-03-01 04:13:08 +0000 | |||
3879 | +++ src/django_nova/templates/django_nova/keypairs/index.html 1970-01-01 00:00:00 +0000 | |||
3880 | @@ -1,77 +0,0 @@ | |||
3881 | 1 | {% extends "django_nova/keypairs/base.html" %} | ||
3882 | 2 | |||
3883 | 3 | {% block title %} - Cloud Computing{% endblock %} | ||
3884 | 4 | |||
3885 | 5 | {% block headerjs %} | ||
3886 | 6 | {{ block.super }} | ||
3887 | 7 | <script type="text/javascript" src="/media/dashboard/js/jquery.form.js"></script> | ||
3888 | 8 | {% endblock %} | ||
3889 | 9 | |||
3890 | 10 | {% block content %} | ||
3891 | 11 | <div id="page_head"> | ||
3892 | 12 | <h2 id="page_heading">Keys</h2> | ||
3893 | 13 | <p id="page_description">Key pairs 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). <em>Protect and use the key as a normal private key.</em></p> | ||
3894 | 14 | </div> | ||
3895 | 15 | |||
3896 | 16 | {% include "django_nova/_messages.html" %} | ||
3897 | 17 | |||
3898 | 18 | <div id="instances"> | ||
3899 | 19 | {% include "django_nova/keypairs/_list.html" %} | ||
3900 | 20 | </div> | ||
3901 | 21 | |||
3902 | 22 | <div class="dash_block first"> | ||
3903 | 23 | <form id="frm_key_create" action="{% url nova_keypairs_add project.projectname %}" method="post"> | ||
3904 | 24 | {% csrf_token %} | ||
3905 | 25 | <input id="js" name="js" type="hidden" value="0" /> | ||
3906 | 26 | <fieldset> | ||
3907 | 27 | <h3>Create New Keypair</h3> | ||
3908 | 28 | {% include "django_nova/keypairs/_create_form.html" %} | ||
3909 | 29 | <input id="keypair_create" class="create" type="submit" value="Create" /> | ||
3910 | 30 | </fieldset> | ||
3911 | 31 | </form> | ||
3912 | 32 | </div> | ||
3913 | 33 | |||
3914 | 34 | <div id="dlg_confirm" title="Confirm Termination"> | ||
3915 | 35 | <p>Are you sure you wish to delete key <span id="spn_delete_key_name"></span>?</p> | ||
3916 | 36 | </div> | ||
3917 | 37 | {% endblock %} | ||
3918 | 38 | |||
3919 | 39 | {% block footerjs %} | ||
3920 | 40 | {{ block.super }} | ||
3921 | 41 | <script type="text/javascript"> | ||
3922 | 42 | $(function() { $('#js').val('1'); }); | ||
3923 | 43 | |||
3924 | 44 | {% if download_key %} | ||
3925 | 45 | $(function() { window.location = '{% url nova_keypairs_download project.projectname download_key %}'; }); | ||
3926 | 46 | {% endif %} | ||
3927 | 47 | |||
3928 | 48 | $(function() { | ||
3929 | 49 | $('.form-key-delete').submit(function() { | ||
3930 | 50 | _key_name = $(this).children(':first').val() | ||
3931 | 51 | $('#spn_delete_key_name').text(_key_name); | ||
3932 | 52 | $('#dlg_confirm').dialog('open'); | ||
3933 | 53 | return false; | ||
3934 | 54 | }); | ||
3935 | 55 | |||
3936 | 56 | $('#dlg_confirm').dialog({ | ||
3937 | 57 | buttons: { | ||
3938 | 58 | 'Ok': onConfirmOK, | ||
3939 | 59 | 'Cancel': function() { $(this).dialog('close'); } | ||
3940 | 60 | }, | ||
3941 | 61 | autoOpen: false, | ||
3942 | 62 | resizable: false, | ||
3943 | 63 | width: 500, | ||
3944 | 64 | height: 200 | ||
3945 | 65 | }); | ||
3946 | 66 | |||
3947 | 67 | }); | ||
3948 | 68 | |||
3949 | 69 | var _terminateID = null; | ||
3950 | 70 | |||
3951 | 71 | function onConfirmOK() { | ||
3952 | 72 | $(this).dialog('close'); | ||
3953 | 73 | form = document.getElementById('form_key_delete_' + _key_name); | ||
3954 | 74 | if(form) form.submit(); | ||
3955 | 75 | } | ||
3956 | 76 | </script> | ||
3957 | 77 | {% endblock %} | ||
3958 | 78 | 0 | ||
3959 | === removed directory 'src/django_nova/templates/django_nova/projects' | |||
3960 | === removed file 'src/django_nova/templates/django_nova/projects/edit_user.html' | |||
3961 | --- src/django_nova/templates/django_nova/projects/edit_user.html 2011-01-16 03:46:33 +0000 | |||
3962 | +++ src/django_nova/templates/django_nova/projects/edit_user.html 1970-01-01 00:00:00 +0000 | |||
3963 | @@ -1,72 +0,0 @@ | |||
3964 | 1 | {% extends "django_nova/base.html" %} | ||
3965 | 2 | {% block title %} - {{ project.projectname|capfirst }} Overview{% endblock %} | ||
3966 | 3 | {% block pageclass %}overview{% endblock %} | ||
3967 | 4 | |||
3968 | 5 | {% block headerjs %} | ||
3969 | 6 | {{ block.super }} | ||
3970 | 7 | <script type="text/javascript" src="/media/dashboard/js/django-admin.multiselect.js"></script> | ||
3971 | 8 | <link rel="stylesheet" type="text/css" href="/media/dashboard/css/django-admin-widgets.css" /> | ||
3972 | 9 | |||
3973 | 10 | <script type="text/javascript" charset="utf-8"> | ||
3974 | 11 | $(function(){ | ||
3975 | 12 | $.each($("#user_edit form select"), function () { | ||
3976 | 13 | // "Locations" can be any label you want | ||
3977 | 14 | SelectFilter.init(this.id, "Roles", 0, "/media/admin/"); | ||
3978 | 15 | }); | ||
3979 | 16 | }) | ||
3980 | 17 | </script> | ||
3981 | 18 | {% endblock %} | ||
3982 | 19 | |||
3983 | 20 | |||
3984 | 21 | {% block content %} | ||
3985 | 22 | <div id="page_head"> | ||
3986 | 23 | <h2 id="page_heading">Edit User Roles</h2> | ||
3987 | 24 | <p id="page_description">From here you can edit multiple user roles.</p> | ||
3988 | 25 | </div> | ||
3989 | 26 | |||
3990 | 27 | {% include "django_nova/_messages.html" %} | ||
3991 | 28 | <div id="user_edit" class="dash_block first"> | ||
3992 | 29 | {% if user %} | ||
3993 | 30 | |||
3994 | 31 | <form action="." method="post" enctype="multipart/form-data"> | ||
3995 | 32 | {% csrf_token %} | ||
3996 | 33 | <fieldset class="module aligned {{ fieldset.classes }}"> | ||
3997 | 34 | <h3 id="edit_{{ user.username }}">Edit Roles for User: {{ user.username }}</h3> | ||
3998 | 35 | <div class="form-row"> | ||
3999 | 36 | <label>User</label> | ||
4000 | 37 | <span id="user_name">{{ user.username }}</span> | ||
4001 | 38 | </div> | ||
4002 | 39 | <input type="hidden" name="username" value="{{ user.id }}" id="username" /> | ||
4003 | 40 | |||
4004 | 41 | {% for field in form.visible_fields %} | ||
4005 | 42 | <div class="form-row"> | ||
4006 | 43 | {{ field.errors }} | ||
4007 | 44 | {{ field.label_tag }}{{ field }} | ||
4008 | 45 | {% if field.field.help_text %}<p class="help">{{ field.field.help_text|safe }}</p>{% endif %} | ||
4009 | 46 | </div> | ||
4010 | 47 | {% endfor %} | ||
4011 | 48 | {% for field in form.hidden_fields %} | ||
4012 | 49 | {{ field }} | ||
4013 | 50 | {% endfor %} | ||
4014 | 51 | </fieldset> | ||
4015 | 52 | <div class="cancel"> | ||
4016 | 53 | <a href="{% url nova_project_manage project.projectname %}">Cancel</a> | ||
4017 | 54 | </div> | ||
4018 | 55 | <div class="submit-row"> | ||
4019 | 56 | <input type="submit" value="Save" class="default" /> | ||
4020 | 57 | {# <a href="#" class="deletelink">Remove User</a> #} | ||
4021 | 58 | </div> | ||
4022 | 59 | </form> | ||
4023 | 60 | {% else %} | ||
4024 | 61 | <div class="ui-widget"> | ||
4025 | 62 | <div class="ui-state-highlight ui-corner-all"> | ||
4026 | 63 | <p> | ||
4027 | 64 | <span class="ui-icon ui-icon-info"></span> | ||
4028 | 65 | No users are currently associated with this project. | ||
4029 | 66 | </p> | ||
4030 | 67 | </div> | ||
4031 | 68 | </div> | ||
4032 | 69 | {% endif %} | ||
4033 | 70 | </div> | ||
4034 | 71 | {% endblock %} | ||
4035 | 72 | |||
4036 | 73 | 0 | ||
4037 | === removed file 'src/django_nova/templates/django_nova/projects/index.html' | |||
4038 | --- src/django_nova/templates/django_nova/projects/index.html 2011-01-12 20:02:06 +0000 | |||
4039 | +++ src/django_nova/templates/django_nova/projects/index.html 1970-01-01 00:00:00 +0000 | |||
4040 | @@ -1,26 +0,0 @@ | |||
4041 | 1 | {% extends "django_nova/base.html" %} | ||
4042 | 2 | {% block title %} - {{ project.projectname|capfirst }} Overview{% endblock %} | ||
4043 | 3 | {% block pageclass %}overview{% endblock %} | ||
4044 | 4 | |||
4045 | 5 | {% block content %} | ||
4046 | 6 | <div id="page_head"> | ||
4047 | 7 | <h2><span>{{ project.projectname|capfirst }}</span> Overview</h2> | ||
4048 | 8 | </div> | ||
4049 | 9 | |||
4050 | 10 | {% include "django_nova/_messages.html" %} | ||
4051 | 11 | |||
4052 | 12 | <div id="welcome"> | ||
4053 | 13 | <p>Welcome to the <span>{{ project.projectname|capfirst }}</span> Overview. From here you can manage your instances, images, keys, and security groups.</p> | ||
4054 | 14 | <p>To get started using the command line management tools, you can <a target="_blank" href="http://open.eucalyptus.com/wiki/Euca2oolsGuide_v1.1">download euca2ools</a> and use them with your x509 credentials.</p> | ||
4055 | 15 | </div> | ||
4056 | 16 | |||
4057 | 17 | <div id="resources" class="dash_block"> | ||
4058 | 18 | <h3>Project Resources</h3> | ||
4059 | 19 | <ul> | ||
4060 | 20 | <li><a href="{% url nova_download_credentials project.projectname %}">Generate X509 credentials.</a></li> | ||
4061 | 21 | <li><a href="{% url nova_instances project.projectname %}">View Instances (<strong>{{ instance_count }}</strong> running).</a></li> | ||
4062 | 22 | <li><a href="{% url nova_images project.projectname %}">View Images.</a></li> | ||
4063 | 23 | </ul> | ||
4064 | 24 | </div> | ||
4065 | 25 | {% endblock %} | ||
4066 | 26 | |||
4067 | 27 | 0 | ||
4068 | === removed file 'src/django_nova/templates/django_nova/projects/manage.html' | |||
4069 | --- src/django_nova/templates/django_nova/projects/manage.html 2011-01-12 20:02:06 +0000 | |||
4070 | +++ src/django_nova/templates/django_nova/projects/manage.html 1970-01-01 00:00:00 +0000 | |||
4071 | @@ -1,45 +0,0 @@ | |||
4072 | 1 | {% extends "django_nova/base.html" %} | ||
4073 | 2 | {% block title %} - {{ project.projectname|capfirst }} Overview{% endblock %} | ||
4074 | 3 | {% block pageclass %}overview{% endblock %} | ||
4075 | 4 | |||
4076 | 5 | {% block content %} | ||
4077 | 6 | <div id="page_head"> | ||
4078 | 7 | <h2 id="page_heading">Manage Users and Roles</h2> | ||
4079 | 8 | <p id="page_description">From here you can manage users and roles.</p> | ||
4080 | 9 | </div> | ||
4081 | 10 | |||
4082 | 11 | {% include "django_nova/_messages.html" %} | ||
4083 | 12 | |||
4084 | 13 | <div id="users"> | ||
4085 | 14 | {% if members %} | ||
4086 | 15 | <table style="width: 100%"> | ||
4087 | 16 | <tr> | ||
4088 | 17 | <th>Username</th> | ||
4089 | 18 | <th>Project Roles</th> | ||
4090 | 19 | <th>Global Roles</th> | ||
4091 | 20 | <th> </th> | ||
4092 | 21 | </tr> | ||
4093 | 22 | {% for member in members %} | ||
4094 | 23 | <tr class="{% cycle 'odd' 'even' %}"> | ||
4095 | 24 | <td>{{ member.memberId }} {% if project.projectManagerId == member.memberId %}(<em>project manager</em>){% endif %}</td> | ||
4096 | 25 | <td>{{ member.project_roles }}</td> | ||
4097 | 26 | <td>{{ member.global_roles }}</td> | ||
4098 | 27 | <td class="odd"> | ||
4099 | 28 | <a href="{% url nova_project_edit_user project.projectname member.memberId%}">Edit</a> | ||
4100 | 29 | </td> | ||
4101 | 30 | </tr> | ||
4102 | 31 | {% endfor %} | ||
4103 | 32 | </table> | ||
4104 | 33 | {% else %} | ||
4105 | 34 | <div class="ui-widget"> | ||
4106 | 35 | <div class="ui-state-highlight ui-corner-all"> | ||
4107 | 36 | <p> | ||
4108 | 37 | <span class="ui-icon ui-icon-info"></span> | ||
4109 | 38 | No users are currently associated with this project. | ||
4110 | 39 | </p> | ||
4111 | 40 | </div> | ||
4112 | 41 | </div> | ||
4113 | 42 | {% endif %} | ||
4114 | 43 | </div> | ||
4115 | 44 | {% endblock %} | ||
4116 | 45 | |||
4117 | 46 | 0 | ||
4118 | === removed directory 'src/django_nova/templates/django_nova/securitygroups' | |||
4119 | === removed file 'src/django_nova/templates/django_nova/securitygroups/_authorize_form.html' | |||
4120 | --- src/django_nova/templates/django_nova/securitygroups/_authorize_form.html 2011-01-12 20:02:06 +0000 | |||
4121 | +++ src/django_nova/templates/django_nova/securitygroups/_authorize_form.html 1970-01-01 00:00:00 +0000 | |||
4122 | @@ -1,5 +0,0 @@ | |||
4123 | 1 | {% for field in authorize_form %} | ||
4124 | 2 | {{ field.label_tag }} | ||
4125 | 3 | {% if field.errors %}{{ field.errors }}{% endif %} | ||
4126 | 4 | {{ field }} | ||
4127 | 5 | {% endfor %} | ||
4128 | 6 | \ No newline at end of file | 0 | \ No newline at end of file |
4129 | 7 | 1 | ||
4130 | === removed file 'src/django_nova/templates/django_nova/securitygroups/_create_form.html' | |||
4131 | --- src/django_nova/templates/django_nova/securitygroups/_create_form.html 2011-01-12 20:02:06 +0000 | |||
4132 | +++ src/django_nova/templates/django_nova/securitygroups/_create_form.html 1970-01-01 00:00:00 +0000 | |||
4133 | @@ -1,5 +0,0 @@ | |||
4134 | 1 | {% for field in create_form %} | ||
4135 | 2 | {{ field.label_tag }} | ||
4136 | 3 | {% if field.errors %}{{ field.errors }}{% endif %} | ||
4137 | 4 | {{ field }} | ||
4138 | 5 | {% endfor %} | ||
4139 | 6 | 0 | ||
4140 | === removed file 'src/django_nova/templates/django_nova/securitygroups/_revoke_form.html' | |||
4141 | --- src/django_nova/templates/django_nova/securitygroups/_revoke_form.html 2011-01-12 20:02:06 +0000 | |||
4142 | +++ src/django_nova/templates/django_nova/securitygroups/_revoke_form.html 1970-01-01 00:00:00 +0000 | |||
4143 | @@ -1,3 +0,0 @@ | |||
4144 | 1 | <input type="hidden" name="protocol" value="{{ rule.ip_protocol }}" /> | ||
4145 | 2 | <input type="hidden" name="from_port" value="{{ rule.from_port}}" /> | ||
4146 | 3 | <input type="hidden" name="to_port" value="{{ rule.to_port }}" /> | ||
4147 | 4 | 0 | ||
4148 | === removed file 'src/django_nova/templates/django_nova/securitygroups/base.html' | |||
4149 | --- src/django_nova/templates/django_nova/securitygroups/base.html 2011-01-17 05:55:41 +0000 | |||
4150 | +++ src/django_nova/templates/django_nova/securitygroups/base.html 1970-01-01 00:00:00 +0000 | |||
4151 | @@ -1,7 +0,0 @@ | |||
4152 | 1 | {% extends "django_nova/base.html" %} | ||
4153 | 2 | {% load sidebar_tags %} | ||
4154 | 3 | |||
4155 | 4 | {% block nav_projects %} | ||
4156 | 5 | {% sidebar_select securitygroups %} | ||
4157 | 6 | {{ block.super }} | ||
4158 | 7 | {% endblock %} | ||
4159 | 8 | \ No newline at end of file | 0 | \ No newline at end of file |
4160 | 9 | 1 | ||
4161 | === removed file 'src/django_nova/templates/django_nova/securitygroups/detail.html' | |||
4162 | --- src/django_nova/templates/django_nova/securitygroups/detail.html 2011-01-17 05:55:41 +0000 | |||
4163 | +++ src/django_nova/templates/django_nova/securitygroups/detail.html 1970-01-01 00:00:00 +0000 | |||
4164 | @@ -1,62 +0,0 @@ | |||
4165 | 1 | {% extends "django_nova/securitygroups/base.html" %} | ||
4166 | 2 | |||
4167 | 3 | {% block title %} - Cloud Computing{% endblock %} | ||
4168 | 4 | |||
4169 | 5 | {% block content %} | ||
4170 | 6 | <div id="dashboard_tabs"> | ||
4171 | 7 | <div id="tabs-1" class="ui-tabs-panel ui-widget-content ui-corner-bottom dash-wrap" style="margin-left:0;min-height:300px;"> | ||
4172 | 8 | <ul id="dashboard_nav"> | ||
4173 | 9 | <li><a id="lnk_overview" href="{% url dashboard_project project.projectname %}">Overview</a></li> | ||
4174 | 10 | <li><a id="lnk_instances" href="{% url dashboard_instances project.projectname %}">Instances</a></li> | ||
4175 | 11 | <li><a id="lnk_images" href="{% url dashboard_images project.projectname %}">Images</a></li> | ||
4176 | 12 | <li><a id="lnk_keypairs" href="{% url dashboard_keypairs project.projectname %}">Keys</a></li> | ||
4177 | 13 | <li class="active"><a id="lnk_securitygroups" href="{% url dashboard_securitygroups project.projectname %}">Security Groups</a></li> | ||
4178 | 14 | <li><a id="lnk_volumes" href="{% url dashboard_volumes project.projectname %}">Volumes</a></li> | ||
4179 | 15 | </ul> | ||
4180 | 16 | <div id="right_content"> | ||
4181 | 17 | <div id="page_head"> | ||
4182 | 18 | <h2>Security Group: {{ securitygroup.name }}</h2> | ||
4183 | 19 | <p>Add and remove protocols to the security group by authorizing and revoking port forwarding. For instance<br /> [tcp, 80, 80] will allow access to HTTP from devices outside this security group.</p> | ||
4184 | 20 | </div> | ||
4185 | 21 | |||
4186 | 22 | {% include "django_nova/_messages.html" %} | ||
4187 | 23 | |||
4188 | 24 | <table> | ||
4189 | 25 | <tr> | ||
4190 | 26 | <th>Protocol</th> | ||
4191 | 27 | <th>From Port</th> | ||
4192 | 28 | <th>To Port</th> | ||
4193 | 29 | <th></th> | ||
4194 | 30 | </tr> | ||
4195 | 31 | {% for rule in securitygroup.rules %} | ||
4196 | 32 | <tr class="{% cycle 'odd' 'even' %}"> | ||
4197 | 33 | <td>{{ rule.ip_protocol }}</td> | ||
4198 | 34 | <td class="odd">{{ rule.from_port }}</td> | ||
4199 | 35 | <td>{{ rule.to_port }}</td> | ||
4200 | 36 | <td class="odd"> | ||
4201 | 37 | <form id="security_groups" method="post" action="{% url dashboard_securitygroups_revoke project.projectname securitygroup.name %}"> | ||
4202 | 38 | {% csrf_token %} | ||
4203 | 39 | {% include "django_nova/securitygroups/_revoke_form.html" %} | ||
4204 | 40 | <input class="ui-state-default ui-corner-all" type="submit" value="Revoke" /> | ||
4205 | 41 | </form> | ||
4206 | 42 | </td> | ||
4207 | 43 | </tr> | ||
4208 | 44 | {% endfor %} | ||
4209 | 45 | </table> | ||
4210 | 46 | |||
4211 | 47 | <div class="block"> | ||
4212 | 48 | <h3>Authorize</h3> | ||
4213 | 49 | <form id="authorize" method="post" action="{% url dashboard_securitygroups_authorize project.projectname securitygroup.name %}"> | ||
4214 | 50 | {% csrf_token %} | ||
4215 | 51 | <fieldset> | ||
4216 | 52 | <input type="hidden" name="group" value="{{ securitygroup.name }}" /> | ||
4217 | 53 | {% include "django_nova/securitygroups/_authorize_form.html" %} | ||
4218 | 54 | <input class="ui-state-default ui-corner-all" type="submit" value="Authorize"> | ||
4219 | 55 | </fieldset> | ||
4220 | 56 | </form> | ||
4221 | 57 | </div> | ||
4222 | 58 | </div> | ||
4223 | 59 | <div class="clr"></div> | ||
4224 | 60 | </div> | ||
4225 | 61 | </div> | ||
4226 | 62 | {% endblock %} | ||
4227 | 63 | 0 | ||
4228 | === removed file 'src/django_nova/templates/django_nova/securitygroups/index.html' | |||
4229 | --- src/django_nova/templates/django_nova/securitygroups/index.html 2011-01-17 05:55:41 +0000 | |||
4230 | +++ src/django_nova/templates/django_nova/securitygroups/index.html 1970-01-01 00:00:00 +0000 | |||
4231 | @@ -1,59 +0,0 @@ | |||
4232 | 1 | {% extends "django_nova/securitygroups/base.html" %} | ||
4233 | 2 | |||
4234 | 3 | {% block title %} - Cloud Computing{% endblock %} | ||
4235 | 4 | |||
4236 | 5 | {% block content %} | ||
4237 | 6 | <div id="dashboard_tabs"> | ||
4238 | 7 | <div id="tabs-1" class="ui-tabs-panel ui-widget-content ui-corner-bottom dash-wrap" style="margin-left:0px;min-height:300px;"> | ||
4239 | 8 | <ul id="dashboard_nav"> | ||
4240 | 9 | <li><a id="lnk_overview" href="{% url dashboard_project project.projectname %}">Overview</a></li> | ||
4241 | 10 | <li><a id="lnk_instances" href="{% url dashboard_instances project.projectname %}">Instances</a></li> | ||
4242 | 11 | <li><a id="lnk_images" href="{% url dashboard_images project.projectname %}">Images</a></li> | ||
4243 | 12 | <li><a id="lnk_keypairs" href="{% url dashboard_keypairs project.projectname %}">Keys</a></li> | ||
4244 | 13 | <li class="active"><a id="lnk_securitygroups" href="{% url dashboard_securitygroups project.projectname %}">Security Groups</a></li> | ||
4245 | 14 | <li><a id="lnk_volumes" href="{% url dashboard_volumes project.projectname %}">Volumes</a></li> | ||
4246 | 15 | </ul> | ||
4247 | 16 | <div id="right_content"> | ||
4248 | 17 | <div id="page_head"> | ||
4249 | 18 | <h2 id="page_heading">Security Groups</h2> | ||
4250 | 19 | <p id="page_description">Security groups are firewall rules which allow access to your instances from other groups as well as the internet. All ports/protocols are denied by default.</p> | ||
4251 | 20 | </div> | ||
4252 | 21 | |||
4253 | 22 | {% include "django_nova/_messages.html" %} | ||
4254 | 23 | |||
4255 | 24 | <table style="width:100%;"> | ||
4256 | 25 | <tr> | ||
4257 | 26 | <th>Name</th> | ||
4258 | 27 | <th style="min-width:60%;">Description</th> | ||
4259 | 28 | <th>Rules</th> | ||
4260 | 29 | <th> </th> | ||
4261 | 30 | </tr> | ||
4262 | 31 | {% for securitygroup in securitygroups %} | ||
4263 | 32 | <tr class="{% cycle 'odd' 'even' %}"> | ||
4264 | 33 | <td id="group_{{ securitygroup.id }}"><a href="{% url dashboard_securitygroups_detail project.projectname securitygroup.name %}">{{ securitygroup.name }}</a></td> | ||
4265 | 34 | <td id="group_{{ securitygroup.id }}_description" class="odd">{{ securitygroup.description }}</td> | ||
4266 | 35 | <td id="group_{{ securitygroup.id }}_rules">{{ securitygroup.rules|length }}</td> | ||
4267 | 36 | <td class="odd"> | ||
4268 | 37 | <form id="delete_group_{{ securitygroup.id }}" method="post" action="{% url dashboard_securitygroups_delete project.projectname securitygroup.name %}"> | ||
4269 | 38 | {% csrf_token %} | ||
4270 | 39 | <input class="ui-state-default ui-corner-all" type="submit" value="Delete"> | ||
4271 | 40 | </form> | ||
4272 | 41 | </td> | ||
4273 | 42 | </tr> | ||
4274 | 43 | {% endfor %} | ||
4275 | 44 | </table> | ||
4276 | 45 | <div class="block"> | ||
4277 | 46 | <form id="add_group_form" method="post" action="{% url dashboard_securitygroups_add project.projectname %}"> | ||
4278 | 47 | {% csrf_token %} | ||
4279 | 48 | <fieldset> | ||
4280 | 49 | <h3>New Group</h3> | ||
4281 | 50 | {% include "django_nova/securitygroups/_create_form.html" %} | ||
4282 | 51 | <label> </label><input class="ui-state-default ui-corner-all" type="submit" value="Create" /> | ||
4283 | 52 | </fieldset> | ||
4284 | 53 | </form> | ||
4285 | 54 | </div> | ||
4286 | 55 | </div> | ||
4287 | 56 | <div class="clr"></div> | ||
4288 | 57 | </div> | ||
4289 | 58 | </div> | ||
4290 | 59 | {% endblock %} | ||
4291 | 60 | 0 | ||
4292 | === removed directory 'src/django_nova/templates/django_nova/volumes' | |||
4293 | === removed file 'src/django_nova/templates/django_nova/volumes/_attach_form.html' | |||
4294 | --- src/django_nova/templates/django_nova/volumes/_attach_form.html 2011-01-12 20:02:06 +0000 | |||
4295 | +++ src/django_nova/templates/django_nova/volumes/_attach_form.html 1970-01-01 00:00:00 +0000 | |||
4296 | @@ -1,5 +0,0 @@ | |||
4297 | 1 | {% for field in attach_form %} | ||
4298 | 2 | {{ field.label_tag }} | ||
4299 | 3 | {% if field.errors %}{{ field.errors }}{% endif %} | ||
4300 | 4 | {{ field }} | ||
4301 | 5 | {% endfor %} | ||
4302 | 6 | 0 | ||
4303 | === removed file 'src/django_nova/templates/django_nova/volumes/_create_form.html' | |||
4304 | --- src/django_nova/templates/django_nova/volumes/_create_form.html 2011-01-12 20:02:06 +0000 | |||
4305 | +++ src/django_nova/templates/django_nova/volumes/_create_form.html 1970-01-01 00:00:00 +0000 | |||
4306 | @@ -1,5 +0,0 @@ | |||
4307 | 1 | {% for field in create_form %} | ||
4308 | 2 | {{ field.label_tag }} | ||
4309 | 3 | {% if field.errors %}{{ field.errors }}{% endif %} | ||
4310 | 4 | {{ field }} | ||
4311 | 5 | {% endfor %} | ||
4312 | 6 | 0 | ||
4313 | === removed file 'src/django_nova/templates/django_nova/volumes/base.html' | |||
4314 | --- src/django_nova/templates/django_nova/volumes/base.html 2011-01-17 05:55:41 +0000 | |||
4315 | +++ src/django_nova/templates/django_nova/volumes/base.html 1970-01-01 00:00:00 +0000 | |||
4316 | @@ -1,7 +0,0 @@ | |||
4317 | 1 | {% extends "django_nova/base.html" %} | ||
4318 | 2 | {% load sidebar_tags %} | ||
4319 | 3 | |||
4320 | 4 | {% block nav_projects %} | ||
4321 | 5 | {% sidebar_select volumes %} | ||
4322 | 6 | {{ block.super }} | ||
4323 | 7 | {% endblock %} | ||
4324 | 8 | \ No newline at end of file | 0 | \ No newline at end of file |
4325 | 9 | 1 | ||
4326 | === removed file 'src/django_nova/templates/django_nova/volumes/index.html' | |||
4327 | --- src/django_nova/templates/django_nova/volumes/index.html 2011-01-17 05:55:41 +0000 | |||
4328 | +++ src/django_nova/templates/django_nova/volumes/index.html 1970-01-01 00:00:00 +0000 | |||
4329 | @@ -1,84 +0,0 @@ | |||
4330 | 1 | {% extends "django_nova/volumes/base.html" %} | ||
4331 | 2 | |||
4332 | 3 | {% block title %} - Cloud Computing{% endblock %} | ||
4333 | 4 | |||
4334 | 5 | {% block content %} | ||
4335 | 6 | <div id="page_head"> | ||
4336 | 7 | <h2 id="page_heading">Volumes</h2> | ||
4337 | 8 | <p id="page_description">Volumes provide persistent block storage. Creating a new volume gives you a raw block device which you may format with your choice of filesystems (ext3 is recommended). A volume may only be attached to a single instance at a time.</p> | ||
4338 | 9 | </div> | ||
4339 | 10 | |||
4340 | 11 | {% include "django_nova/_messages.html" %} | ||
4341 | 12 | |||
4342 | 13 | {% if volumes %} | ||
4343 | 14 | <table style="width: 100%"> | ||
4344 | 15 | <tr> | ||
4345 | 16 | <th>ID</th> | ||
4346 | 17 | <th>Size</th> | ||
4347 | 18 | <th colspan="2">Status</th> | ||
4348 | 19 | </tr> | ||
4349 | 20 | {% for volume in volumes %} | ||
4350 | 21 | <tr class="{% cycle 'odd' 'even' %}"> | ||
4351 | 22 | <td id="volume_{{ volume.id }}">{{ volume.id }} {{ volume.displayName }}</td> | ||
4352 | 23 | <td id="volume_{{ volume.id }}_size" class="odd">{{ volume.size }}GB</td> | ||
4353 | 24 | <td id="volume_{{ volume.id }})_status"> | ||
4354 | 25 | {% if volume.status == "in-use" %} | ||
4355 | 26 | {% if volume.attachment_state == "attached" %} | ||
4356 | 27 | attached: {{ volume.attach_data.instance_id }} | ||
4357 | 28 | {% else %} | ||
4358 | 29 | {{ volume.attachment_state }} | ||
4359 | 30 | {% endif %} | ||
4360 | 31 | {% else %} | ||
4361 | 32 | {{ volume.status }} | ||
4362 | 33 | {% endif %} | ||
4363 | 34 | </td> | ||
4364 | 35 | {% if volume.attachment_state == "attached" %} | ||
4365 | 36 | <td class="odd"> | ||
4366 | 37 | <form class="volume" action="{% url nova_volumes_detach project.projectname volume.id %}" method="post"> | ||
4367 | 38 | {% csrf_token %} | ||
4368 | 39 | <input id="detach_{{ volume.id }}" class="detach" type="submit" value="Detach"> | ||
4369 | 40 | </form> | ||
4370 | 41 | </td> | ||
4371 | 42 | {% else %} | ||
4372 | 43 | <td class="odd"> | ||
4373 | 44 | <form class="volume" action="{% url nova_volumes_delete project.projectname volume.id %}" method="post"> | ||
4374 | 45 | {% csrf_token %} | ||
4375 | 46 | <input id="delete_{{ volume.id }}" class="delete" type="submit" value="Delete"> | ||
4376 | 47 | </form> | ||
4377 | 48 | </td> | ||
4378 | 49 | {% endif %} | ||
4379 | 50 | </tr> | ||
4380 | 51 | {% endfor %} | ||
4381 | 52 | </table> | ||
4382 | 53 | {% else %} | ||
4383 | 54 | <div class="ui-widget"> | ||
4384 | 55 | <div class="ui-state-highlight ui-corner-all"> | ||
4385 | 56 | <p> | ||
4386 | 57 | <span class="ui-icon ui-icon-info"></span> | ||
4387 | 58 | No volumes currently exist. | ||
4388 | 59 | </p> | ||
4389 | 60 | </div> | ||
4390 | 61 | </div> | ||
4391 | 62 | {% endif %} | ||
4392 | 63 | <div class="dash_block first"> | ||
4393 | 64 | <form id="new_volume_form" method="post" action="{% url nova_volumes_add project.projectname %}"> | ||
4394 | 65 | {% csrf_token %} | ||
4395 | 66 | <fieldset> | ||
4396 | 67 | <h3>Create New Volume</h3> | ||
4397 | 68 | {% include "django_nova/volumes/_create_form.html" %} | ||
4398 | 69 | <input id="create_volume" class="create" type="submit" value="Create" /> | ||
4399 | 70 | </fieldset> | ||
4400 | 71 | </form> | ||
4401 | 72 | </div> | ||
4402 | 73 | |||
4403 | 74 | <div class="dash_block"> | ||
4404 | 75 | <form id="new_volume_form" method="post" action="{% url nova_volumes_attach project.projectname %}"> | ||
4405 | 76 | {% csrf_token %} | ||
4406 | 77 | <fieldset> | ||
4407 | 78 | <h3>Attach Volume</h3> | ||
4408 | 79 | {% include "django_nova/volumes/_attach_form.html" %} | ||
4409 | 80 | <input id="attach_volume" class="attach" type="submit" value="Attach" /> | ||
4410 | 81 | </fieldset> | ||
4411 | 82 | </form> | ||
4412 | 83 | </div> | ||
4413 | 84 | {% endblock %} | ||
4414 | 85 | 0 | ||
4415 | === removed directory 'src/django_nova/templatetags' | |||
4416 | === removed file 'src/django_nova/templatetags/__init__.py' | |||
4417 | === removed file 'src/django_nova/templatetags/admin_extras.py' | |||
4418 | --- src/django_nova/templatetags/admin_extras.py 2011-01-12 20:02:06 +0000 | |||
4419 | +++ src/django_nova/templatetags/admin_extras.py 1970-01-01 00:00:00 +0000 | |||
4420 | @@ -1,50 +0,0 @@ | |||
4421 | 1 | # vim: tabstop=4 shiftwidth=4 softtabstop=4 | ||
4422 | 2 | |||
4423 | 3 | # Copyright 2010 United States Government as represented by the | ||
4424 | 4 | # Administrator of the National Aeronautics and Space Administration. | ||
4425 | 5 | # All Rights Reserved. | ||
4426 | 6 | # | ||
4427 | 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | ||
4428 | 8 | # not use this file except in compliance with the License. You may obtain | ||
4429 | 9 | # a copy of the License at | ||
4430 | 10 | # | ||
4431 | 11 | # http://www.apache.org/licenses/LICENSE-2.0 | ||
4432 | 12 | # | ||
4433 | 13 | # Unless required by applicable law or agreed to in writing, software | ||
4434 | 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
4435 | 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
4436 | 16 | # License for the specific language governing permissions and limitations | ||
4437 | 17 | # under the License. | ||
4438 | 18 | """ | ||
4439 | 19 | Template tags for extending the Django admin interface. | ||
4440 | 20 | """ | ||
4441 | 21 | |||
4442 | 22 | from django.contrib.admin.templatetags.admin_list import items_for_result, result_headers | ||
4443 | 23 | from django.core.urlresolvers import reverse | ||
4444 | 24 | from django.template import Library | ||
4445 | 25 | from django.utils.safestring import mark_safe | ||
4446 | 26 | |||
4447 | 27 | |||
4448 | 28 | register = Library() | ||
4449 | 29 | |||
4450 | 30 | def project_result_list(cl): | ||
4451 | 31 | headers = list(result_headers(cl)) | ||
4452 | 32 | headers.append({'text': mark_safe(' ')}) | ||
4453 | 33 | |||
4454 | 34 | results = list() | ||
4455 | 35 | |||
4456 | 36 | for project in cl.result_list: | ||
4457 | 37 | rl = list(items_for_result(cl,project,None)) | ||
4458 | 38 | |||
4459 | 39 | url = reverse('admin_project_sendcredentials', args=[project.projectname]) | ||
4460 | 40 | content = mark_safe('<td><a href="%s">Send Credentials</a></td>' % url) | ||
4461 | 41 | |||
4462 | 42 | rl.append(content) | ||
4463 | 43 | results.append(rl) | ||
4464 | 44 | |||
4465 | 45 | return { | ||
4466 | 46 | 'cl': cl, | ||
4467 | 47 | 'result_headers': headers, | ||
4468 | 48 | 'results': results | ||
4469 | 49 | } | ||
4470 | 50 | project_result_list = register.inclusion_tag("admin/change_list_results.html")(project_result_list) | ||
4471 | 51 | 0 | ||
4472 | === removed file 'src/django_nova/templatetags/django_nova_tags.py' | |||
4473 | --- src/django_nova/templatetags/django_nova_tags.py 2011-02-01 19:18:59 +0000 | |||
4474 | +++ src/django_nova/templatetags/django_nova_tags.py 1970-01-01 00:00:00 +0000 | |||
4475 | @@ -1,37 +0,0 @@ | |||
4476 | 1 | # vim: tabstop=4 shiftwidth=4 softtabstop=4 | ||
4477 | 2 | |||
4478 | 3 | # Copyright 2010 United States Government as represented by the | ||
4479 | 4 | # Administrator of the National Aeronautics and Space Administration. | ||
4480 | 5 | # All Rights Reserved. | ||
4481 | 6 | # | ||
4482 | 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | ||
4483 | 8 | # not use this file except in compliance with the License. You may obtain | ||
4484 | 9 | # a copy of the License at | ||
4485 | 10 | # | ||
4486 | 11 | # http://www.apache.org/licenses/LICENSE-2.0 | ||
4487 | 12 | # | ||
4488 | 13 | # Unless required by applicable law or agreed to in writing, software | ||
4489 | 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
4490 | 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
4491 | 16 | # License for the specific language governing permissions and limitations | ||
4492 | 17 | # under the License. | ||
4493 | 18 | |||
4494 | 19 | """ | ||
4495 | 20 | Template tags for working with django_nova. | ||
4496 | 21 | """ | ||
4497 | 22 | |||
4498 | 23 | from django import template | ||
4499 | 24 | from django.conf import settings | ||
4500 | 25 | |||
4501 | 26 | |||
4502 | 27 | register = template.Library() | ||
4503 | 28 | |||
4504 | 29 | |||
4505 | 30 | class SiteBrandingNode(template.Node): | ||
4506 | 31 | def render(self, context): | ||
4507 | 32 | return settings.SITE_BRANDING | ||
4508 | 33 | |||
4509 | 34 | @register.tag | ||
4510 | 35 | def site_branding(parser, token): | ||
4511 | 36 | return SiteBrandingNode() | ||
4512 | 37 | |||
4513 | 38 | 0 | ||
4514 | === removed file 'src/django_nova/templatetags/project_tags.py' | |||
4515 | --- src/django_nova/templatetags/project_tags.py 2011-01-17 06:58:19 +0000 | |||
4516 | +++ src/django_nova/templatetags/project_tags.py 1970-01-01 00:00:00 +0000 | |||
4517 | @@ -1,39 +0,0 @@ | |||
4518 | 1 | # vim: tabstop=4 shiftwidth=4 softtabstop=4 | ||
4519 | 2 | |||
4520 | 3 | # Copyright 2010 United States Government as represented by the | ||
4521 | 4 | # Administrator of the National Aeronautics and Space Administration. | ||
4522 | 5 | # All Rights Reserved. | ||
4523 | 6 | # | ||
4524 | 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | ||
4525 | 8 | # not use this file except in compliance with the License. You may obtain | ||
4526 | 9 | # a copy of the License at | ||
4527 | 10 | # | ||
4528 | 11 | # http://www.apache.org/licenses/LICENSE-2.0 | ||
4529 | 12 | # | ||
4530 | 13 | # Unless required by applicable law or agreed to in writing, software | ||
4531 | 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
4532 | 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
4533 | 16 | # License for the specific language governing permissions and limitations | ||
4534 | 17 | # under the License. | ||
4535 | 18 | |||
4536 | 19 | """ | ||
4537 | 20 | Template tags for gathering contextual region data. | ||
4538 | 21 | """ | ||
4539 | 22 | |||
4540 | 23 | from django import template | ||
4541 | 24 | from django_nova.shortcuts import get_projects | ||
4542 | 25 | |||
4543 | 26 | |||
4544 | 27 | register = template.Library() | ||
4545 | 28 | |||
4546 | 29 | |||
4547 | 30 | class ProjectsNode(template.Node): | ||
4548 | 31 | def render(self, context): | ||
4549 | 32 | # Store project list in template context. | ||
4550 | 33 | context['projects'] = get_projects(context['request'].user) | ||
4551 | 34 | return '' | ||
4552 | 35 | |||
4553 | 36 | |||
4554 | 37 | @register.tag | ||
4555 | 38 | def load_projects(parser, token): | ||
4556 | 39 | return ProjectsNode() | ||
4557 | 40 | 0 | ||
4558 | === removed file 'src/django_nova/templatetags/region_tags.py' | |||
4559 | --- src/django_nova/templatetags/region_tags.py 2011-01-17 06:58:19 +0000 | |||
4560 | +++ src/django_nova/templatetags/region_tags.py 1970-01-01 00:00:00 +0000 | |||
4561 | @@ -1,40 +0,0 @@ | |||
4562 | 1 | # vim: tabstop=4 shiftwidth=4 softtabstop=4 | ||
4563 | 2 | |||
4564 | 3 | # Copyright 2010 United States Government as represented by the | ||
4565 | 4 | # Administrator of the National Aeronautics and Space Administration. | ||
4566 | 5 | # All Rights Reserved. | ||
4567 | 6 | # | ||
4568 | 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | ||
4569 | 8 | # not use this file except in compliance with the License. You may obtain | ||
4570 | 9 | # a copy of the License at | ||
4571 | 10 | # | ||
4572 | 11 | # http://www.apache.org/licenses/LICENSE-2.0 | ||
4573 | 12 | # | ||
4574 | 13 | # Unless required by applicable law or agreed to in writing, software | ||
4575 | 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
4576 | 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
4577 | 16 | # License for the specific language governing permissions and limitations | ||
4578 | 17 | # under the License. | ||
4579 | 18 | """ | ||
4580 | 19 | Template tags for gathering contextual region data. | ||
4581 | 20 | """ | ||
4582 | 21 | |||
4583 | 22 | from django import template | ||
4584 | 23 | from django_nova.shortcuts import get_current_region, get_all_regions | ||
4585 | 24 | |||
4586 | 25 | |||
4587 | 26 | register = template.Library() | ||
4588 | 27 | |||
4589 | 28 | |||
4590 | 29 | class RegionsNode(template.Node): | ||
4591 | 30 | def render(self, context): | ||
4592 | 31 | # Store region info in template context. | ||
4593 | 32 | context['current_region'] = get_current_region(context['request']) | ||
4594 | 33 | context['regions'] = get_all_regions() | ||
4595 | 34 | return '' | ||
4596 | 35 | |||
4597 | 36 | |||
4598 | 37 | @register.tag | ||
4599 | 38 | def load_regions(parser, token): | ||
4600 | 39 | return RegionsNode() | ||
4601 | 40 | |||
4602 | 41 | 0 | ||
4603 | === removed file 'src/django_nova/templatetags/sidebar_tags.py' | |||
4604 | --- src/django_nova/templatetags/sidebar_tags.py 2011-01-17 05:55:41 +0000 | |||
4605 | +++ src/django_nova/templatetags/sidebar_tags.py 1970-01-01 00:00:00 +0000 | |||
4606 | @@ -1,46 +0,0 @@ | |||
4607 | 1 | # vim: tabstop=4 shiftwidth=4 softtabstop=4 | ||
4608 | 2 | |||
4609 | 3 | # Copyright 2010 United States Government as represented by the | ||
4610 | 4 | # Administrator of the National Aeronautics and Space Administration. | ||
4611 | 5 | # All Rights Reserved. | ||
4612 | 6 | # | ||
4613 | 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | ||
4614 | 8 | # not use this file except in compliance with the License. You may obtain | ||
4615 | 9 | # a copy of the License at | ||
4616 | 10 | # | ||
4617 | 11 | # http://www.apache.org/licenses/LICENSE-2.0 | ||
4618 | 12 | # | ||
4619 | 13 | # Unless required by applicable law or agreed to in writing, software | ||
4620 | 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
4621 | 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
4622 | 16 | # License for the specific language governing permissions and limitations | ||
4623 | 17 | # under the License. | ||
4624 | 18 | |||
4625 | 19 | """ | ||
4626 | 20 | Template tags for rendering the sidebar. | ||
4627 | 21 | """ | ||
4628 | 22 | |||
4629 | 23 | from django import template | ||
4630 | 24 | |||
4631 | 25 | |||
4632 | 26 | register = template.Library() | ||
4633 | 27 | |||
4634 | 28 | |||
4635 | 29 | class SidebarSelectNode(template.Node): | ||
4636 | 30 | def __init__(self, selected): | ||
4637 | 31 | self.selected = selected | ||
4638 | 32 | |||
4639 | 33 | def render(self, context): | ||
4640 | 34 | # Store page type in template context. | ||
4641 | 35 | context['sidebar_selected'] = self.selected | ||
4642 | 36 | return '' | ||
4643 | 37 | |||
4644 | 38 | |||
4645 | 39 | @register.tag | ||
4646 | 40 | def sidebar_select(parser, token): | ||
4647 | 41 | try: | ||
4648 | 42 | tag_name, selected = token.split_contents() | ||
4649 | 43 | except ValueError: | ||
4650 | 44 | raise template.TemplateSyntaxError, "%r tag requires exactly one argument" % token.contents.split()[0] | ||
4651 | 45 | return SidebarSelectNode(str(selected)) | ||
4652 | 46 | |||
4653 | 47 | 0 | ||
4654 | === removed file 'src/django_nova/templatetags/truncate_filter.py' | |||
4655 | --- src/django_nova/templatetags/truncate_filter.py 2011-01-12 20:02:06 +0000 | |||
4656 | +++ src/django_nova/templatetags/truncate_filter.py 1970-01-01 00:00:00 +0000 | |||
4657 | @@ -1,31 +0,0 @@ | |||
4658 | 1 | # vim: tabstop=4 shiftwidth=4 softtabstop=4 | ||
4659 | 2 | |||
4660 | 3 | # Copyright 2010 United States Government as represented by the | ||
4661 | 4 | # Administrator of the National Aeronautics and Space Administration. | ||
4662 | 5 | # All Rights Reserved. | ||
4663 | 6 | # | ||
4664 | 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | ||
4665 | 8 | # not use this file except in compliance with the License. You may obtain | ||
4666 | 9 | # a copy of the License at | ||
4667 | 10 | # | ||
4668 | 11 | # http://www.apache.org/licenses/LICENSE-2.0 | ||
4669 | 12 | # | ||
4670 | 13 | # Unless required by applicable law or agreed to in writing, software | ||
4671 | 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
4672 | 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
4673 | 16 | # License for the specific language governing permissions and limitations | ||
4674 | 17 | # under the License. | ||
4675 | 18 | """ | ||
4676 | 19 | Template tags for truncating strings. | ||
4677 | 20 | """ | ||
4678 | 21 | |||
4679 | 22 | from django import template | ||
4680 | 23 | |||
4681 | 24 | register = template.Library() | ||
4682 | 25 | |||
4683 | 26 | @register.filter("truncate") | ||
4684 | 27 | def truncate(value, size): | ||
4685 | 28 | if len(value) > size and size > 3: | ||
4686 | 29 | return value[0:(size-3)] + '...' | ||
4687 | 30 | else: | ||
4688 | 31 | return value[0:size] | ||
4689 | 32 | 0 | ||
4690 | === removed directory 'src/django_nova/tests' | |||
4691 | === removed file 'src/django_nova/tests/__init__.py' | |||
4692 | --- src/django_nova/tests/__init__.py 2011-01-18 02:09:01 +0000 | |||
4693 | +++ src/django_nova/tests/__init__.py 1970-01-01 00:00:00 +0000 | |||
4694 | @@ -1,1 +0,0 @@ | |||
4695 | 1 | from view_tests import * | ||
4696 | 2 | \ No newline at end of file | 0 | \ No newline at end of file |
4697 | 3 | 1 | ||
4698 | === removed directory 'src/django_nova/tests/templates' | |||
4699 | === removed file 'src/django_nova/tests/templates/base-sidebar.html' | |||
4700 | === removed file 'src/django_nova/tests/urls.py' | |||
4701 | --- src/django_nova/tests/urls.py 2011-02-11 03:07:22 +0000 | |||
4702 | +++ src/django_nova/tests/urls.py 1970-01-01 00:00:00 +0000 | |||
4703 | @@ -1,36 +0,0 @@ | |||
4704 | 1 | # vim: tabstop=4 shiftwidth=4 softtabstop=4 | ||
4705 | 2 | |||
4706 | 3 | # Copyright 2010 United States Government as represented by the | ||
4707 | 4 | # Administrator of the National Aeronautics and Space Administration. | ||
4708 | 5 | # All Rights Reserved. | ||
4709 | 6 | # | ||
4710 | 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | ||
4711 | 8 | # not use this file except in compliance with the License. You may obtain | ||
4712 | 9 | # a copy of the License at | ||
4713 | 10 | # | ||
4714 | 11 | # http://www.apache.org/licenses/LICENSE-2.0 | ||
4715 | 12 | # | ||
4716 | 13 | # Unless required by applicable law or agreed to in writing, software | ||
4717 | 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
4718 | 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
4719 | 16 | # License for the specific language governing permissions and limitations | ||
4720 | 17 | # under the License. | ||
4721 | 18 | |||
4722 | 19 | """ | ||
4723 | 20 | URL patterns for testing django-nova views. | ||
4724 | 21 | """ | ||
4725 | 22 | |||
4726 | 23 | from django.conf.urls.defaults import * | ||
4727 | 24 | from django.conf.urls.defaults import * | ||
4728 | 25 | |||
4729 | 26 | |||
4730 | 27 | urlpatterns = patterns('', | ||
4731 | 28 | url(r'^projects/', include('django_nova.urls.project')), | ||
4732 | 29 | url(r'^region/', include('django_nova.urls.region')), | ||
4733 | 30 | url(r'^admin/projects/', include('django_nova.urls.admin_project')), | ||
4734 | 31 | url(r'^admin/roles/', include('django_nova.urls.admin_roles')), | ||
4735 | 32 | url(r'^credentials/download/(?P<auth_token>\w+)/$', | ||
4736 | 33 | 'django_nova.views.credentials.authorize_credentials', | ||
4737 | 34 | name='nova_credentials_authorize'), | ||
4738 | 35 | ) | ||
4739 | 36 | |||
4740 | 37 | 0 | ||
4741 | === removed directory 'src/django_nova/tests/view_tests' | |||
4742 | === removed file 'src/django_nova/tests/view_tests/__init__.py' | |||
4743 | --- src/django_nova/tests/view_tests/__init__.py 2011-02-11 03:07:22 +0000 | |||
4744 | +++ src/django_nova/tests/view_tests/__init__.py 1970-01-01 00:00:00 +0000 | |||
4745 | @@ -1,7 +0,0 @@ | |||
4746 | 1 | from credential_tests import * | ||
4747 | 2 | from image_tests import * | ||
4748 | 3 | from instance_tests import * | ||
4749 | 4 | from keypair_tests import * | ||
4750 | 5 | from region_tests import * | ||
4751 | 6 | from volume_tests import * | ||
4752 | 7 | |||
4753 | 8 | 0 | ||
4754 | === removed file 'src/django_nova/tests/view_tests/base.py' | |||
4755 | --- src/django_nova/tests/view_tests/base.py 2011-02-11 02:44:45 +0000 | |||
4756 | +++ src/django_nova/tests/view_tests/base.py 1970-01-01 00:00:00 +0000 | |||
4757 | @@ -1,90 +0,0 @@ | |||
4758 | 1 | # vim: tabstop=4 shiftwidth=4 softtabstop=4 | ||
4759 | 2 | |||
4760 | 3 | # Copyright 2010 United States Government as represented by the | ||
4761 | 4 | # Administrator of the National Aeronautics and Space Administration. | ||
4762 | 5 | # All Rights Reserved. | ||
4763 | 6 | # | ||
4764 | 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | ||
4765 | 8 | # not use this file except in compliance with the License. You may obtain | ||
4766 | 9 | # a copy of the License at | ||
4767 | 10 | # | ||
4768 | 11 | # http://www.apache.org/licenses/LICENSE-2.0 | ||
4769 | 12 | # | ||
4770 | 13 | # Unless required by applicable law or agreed to in writing, software | ||
4771 | 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
4772 | 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
4773 | 16 | # License for the specific language governing permissions and limitations | ||
4774 | 17 | # under the License. | ||
4775 | 18 | |||
4776 | 19 | """ | ||
4777 | 20 | Base classes for view based unit tests. | ||
4778 | 21 | """ | ||
4779 | 22 | |||
4780 | 23 | import mox | ||
4781 | 24 | |||
4782 | 25 | from django import test | ||
4783 | 26 | from django.conf import settings | ||
4784 | 27 | from django.contrib.auth import models as auth_models | ||
4785 | 28 | from django_nova import adminclient | ||
4786 | 29 | from django_nova import manager | ||
4787 | 30 | from django_nova import shortcuts | ||
4788 | 31 | |||
4789 | 32 | |||
4790 | 33 | TEST_PROJECT = 'test' | ||
4791 | 34 | TEST_USER = 'test' | ||
4792 | 35 | TEST_REGION = 'test' | ||
4793 | 36 | |||
4794 | 37 | |||
4795 | 38 | class BaseViewTests(test.TestCase): | ||
4796 | 39 | def setUp(self): | ||
4797 | 40 | self.mox = mox.Mox() | ||
4798 | 41 | |||
4799 | 42 | def tearDown(self): | ||
4800 | 43 | self.mox.UnsetStubs() | ||
4801 | 44 | |||
4802 | 45 | def assertRedirectsNoFollow(self, response, expected_url): | ||
4803 | 46 | self.assertEqual(response._headers['location'], | ||
4804 | 47 | ('Location', settings.TESTSERVER + expected_url)) | ||
4805 | 48 | self.assertEqual(response.status_code, 302) | ||
4806 | 49 | |||
4807 | 50 | def authenticateTestUser(self): | ||
4808 | 51 | user = auth_models.User.objects.create_user(TEST_USER, | ||
4809 | 52 | 'test@test.com', | ||
4810 | 53 | password='test') | ||
4811 | 54 | login = self.client.login(username=TEST_USER, password='test') | ||
4812 | 55 | self.failUnless(login, 'Unable to login') | ||
4813 | 56 | return user | ||
4814 | 57 | |||
4815 | 58 | |||
4816 | 59 | class BaseProjectViewTests(BaseViewTests): | ||
4817 | 60 | def setUp(self): | ||
4818 | 61 | super(BaseProjectViewTests, self).setUp() | ||
4819 | 62 | |||
4820 | 63 | project = adminclient.ProjectInfo() | ||
4821 | 64 | project.projectname = TEST_PROJECT | ||
4822 | 65 | project.projectManagerId = TEST_USER | ||
4823 | 66 | |||
4824 | 67 | self.user = self.authenticateTestUser() | ||
4825 | 68 | self.region = adminclient.RegionInfo(name=TEST_REGION, | ||
4826 | 69 | endpoint='http://test:8773/') | ||
4827 | 70 | self.project = manager.ProjectManager(self.user.username, | ||
4828 | 71 | project, | ||
4829 | 72 | self.region) | ||
4830 | 73 | self.mox.StubOutWithMock(shortcuts, 'get_project_or_404') | ||
4831 | 74 | shortcuts.get_project_or_404(mox.IgnoreArg(), | ||
4832 | 75 | 'test').AndReturn(self.project) | ||
4833 | 76 | |||
4834 | 77 | def create_key_pair_choices(self, key_names): | ||
4835 | 78 | return [(k, k) for k in key_names] | ||
4836 | 79 | |||
4837 | 80 | def create_instance_type_choices(self): | ||
4838 | 81 | return [('m1.medium', 'm1.medium'), | ||
4839 | 82 | ('m1.large', 'm1.large')] | ||
4840 | 83 | |||
4841 | 84 | def create_instance_choices(self, instance_ids): | ||
4842 | 85 | return [(id, id) for id in instance_ids] | ||
4843 | 86 | |||
4844 | 87 | def create_available_volume_choices(self, volumes): | ||
4845 | 88 | return [(v.id, '%s %s - %dGB' % (v.id, v.displayName, v.size)) \ | ||
4846 | 89 | for v in volumes] | ||
4847 | 90 | |||
4848 | 91 | 0 | ||
4849 | === removed file 'src/django_nova/tests/view_tests/credential_tests.py' | |||
4850 | --- src/django_nova/tests/view_tests/credential_tests.py 2011-02-11 03:07:22 +0000 | |||
4851 | +++ src/django_nova/tests/view_tests/credential_tests.py 1970-01-01 00:00:00 +0000 | |||
4852 | @@ -1,70 +0,0 @@ | |||
4853 | 1 | # vim: tabstop=4 shiftwidth=4 softtabstop=4 | ||
4854 | 2 | |||
4855 | 3 | # Copyright 2010 United States Government as represented by the | ||
4856 | 4 | # Administrator of the National Aeronautics and Space Administration. | ||
4857 | 5 | # All Rights Reserved. | ||
4858 | 6 | # | ||
4859 | 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | ||
4860 | 8 | # not use this file except in compliance with the License. You may obtain | ||
4861 | 9 | # a copy of the License at | ||
4862 | 10 | # | ||
4863 | 11 | # http://www.apache.org/licenses/LICENSE-2.0 | ||
4864 | 12 | # | ||
4865 | 13 | # Unless required by applicable law or agreed to in writing, software | ||
4866 | 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
4867 | 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
4868 | 16 | # License for the specific language governing permissions and limitations | ||
4869 | 17 | # under the License. | ||
4870 | 18 | |||
4871 | 19 | """ | ||
4872 | 20 | Unit tests for credential views. | ||
4873 | 21 | """ | ||
4874 | 22 | |||
4875 | 23 | import mox | ||
4876 | 24 | from django.conf import settings | ||
4877 | 25 | from django.core.urlresolvers import reverse | ||
4878 | 26 | from django_nova import models | ||
4879 | 27 | from django_nova.tests.view_tests.base import BaseViewTests | ||
4880 | 28 | |||
4881 | 29 | |||
4882 | 30 | class CredentialViewTests(BaseViewTests): | ||
4883 | 31 | def test_download_expired_credentials(self): | ||
4884 | 32 | auth_token = 'expired' | ||
4885 | 33 | self.mox.StubOutWithMock(models.CredentialsAuthorization, | ||
4886 | 34 | 'get_by_token') | ||
4887 | 35 | models.CredentialsAuthorization.get_by_token(auth_token) \ | ||
4888 | 36 | .AndReturn(None) | ||
4889 | 37 | self.mox.ReplayAll() | ||
4890 | 38 | |||
4891 | 39 | res = self.client.get(reverse('nova_credentials_authorize', | ||
4892 | 40 | args=[auth_token])) | ||
4893 | 41 | self.assertTemplateUsed(res, 'django_nova/credentials/expired.html') | ||
4894 | 42 | |||
4895 | 43 | self.mox.VerifyAll() | ||
4896 | 44 | |||
4897 | 45 | def test_download_good_credentials(self): | ||
4898 | 46 | auth_token = 'good' | ||
4899 | 47 | |||
4900 | 48 | creds = models.CredentialsAuthorization() | ||
4901 | 49 | creds.username = 'test' | ||
4902 | 50 | creds.project = 'test' | ||
4903 | 51 | creds.auth_token = auth_token | ||
4904 | 52 | |||
4905 | 53 | self.mox.StubOutWithMock(models.CredentialsAuthorization, | ||
4906 | 54 | 'get_by_token') | ||
4907 | 55 | self.mox.StubOutWithMock(creds, 'get_zip') | ||
4908 | 56 | models.CredentialsAuthorization.get_by_token(auth_token) \ | ||
4909 | 57 | .AndReturn(creds) | ||
4910 | 58 | creds.get_zip().AndReturn('zip') | ||
4911 | 59 | |||
4912 | 60 | self.mox.ReplayAll() | ||
4913 | 61 | |||
4914 | 62 | res = self.client.get(reverse('nova_credentials_authorize', | ||
4915 | 63 | args=[auth_token])) | ||
4916 | 64 | self.assertEqual(res.status_code, 200) | ||
4917 | 65 | self.assertEqual(res['Content-Disposition'], | ||
4918 | 66 | 'attachment; filename=%s-test-test-x509.zip' % | ||
4919 | 67 | settings.SITE_NAME) | ||
4920 | 68 | self.assertContains(res, 'zip') | ||
4921 | 69 | |||
4922 | 70 | self.mox.VerifyAll() | ||
4923 | 71 | 0 | ||
4924 | === removed file 'src/django_nova/tests/view_tests/image_tests.py' | |||
4925 | --- src/django_nova/tests/view_tests/image_tests.py 2011-02-08 01:20:39 +0000 | |||
4926 | +++ src/django_nova/tests/view_tests/image_tests.py 1970-01-01 00:00:00 +0000 | |||
4927 | @@ -1,232 +0,0 @@ | |||
4928 | 1 | # vim: tabstop=4 shiftwidth=4 softtabstop=4 | ||
4929 | 2 | |||
4930 | 3 | # Copyright 2010 United States Government as represented by the | ||
4931 | 4 | # Administrator of the National Aeronautics and Space Administration. | ||
4932 | 5 | # All Rights Reserved. | ||
4933 | 6 | # | ||
4934 | 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | ||
4935 | 8 | # not use this file except in compliance with the License. You may obtain | ||
4936 | 9 | # a copy of the License at | ||
4937 | 10 | # | ||
4938 | 11 | # http://www.apache.org/licenses/LICENSE-2.0 | ||
4939 | 12 | # | ||
4940 | 13 | # Unless required by applicable law or agreed to in writing, software | ||
4941 | 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
4942 | 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
4943 | 16 | # License for the specific language governing permissions and limitations | ||
4944 | 17 | # under the License. | ||
4945 | 18 | |||
4946 | 19 | """ | ||
4947 | 20 | Unit tests for image views. | ||
4948 | 21 | """ | ||
4949 | 22 | |||
4950 | 23 | import boto.ec2.image | ||
4951 | 24 | import boto.ec2.instance | ||
4952 | 25 | import mox | ||
4953 | 26 | |||
4954 | 27 | from django.core.urlresolvers import reverse | ||
4955 | 28 | from django_nova import forms | ||
4956 | 29 | from django_nova import shortcuts | ||
4957 | 30 | from django_nova.tests.view_tests.base import BaseProjectViewTests, TEST_PROJECT | ||
4958 | 31 | |||
4959 | 32 | |||
4960 | 33 | TEST_IMAGE_ID = 'ami_test' | ||
4961 | 34 | TEST_INSTANCE_ID = 'i-abcdefg' | ||
4962 | 35 | TEST_KEY = 'foo' | ||
4963 | 36 | |||
4964 | 37 | |||
4965 | 38 | class ImageViewTests(BaseProjectViewTests): | ||
4966 | 39 | def setUp(self): | ||
4967 | 40 | self.ami = boto.ec2.image.Image() | ||
4968 | 41 | self.ami.id = TEST_IMAGE_ID | ||
4969 | 42 | setattr(self.ami, 'displayName', TEST_IMAGE_ID) | ||
4970 | 43 | setattr(self.ami, 'description', TEST_IMAGE_ID) | ||
4971 | 44 | super(ImageViewTests, self).setUp() | ||
4972 | 45 | |||
4973 | 46 | def test_index(self): | ||
4974 | 47 | self.mox.StubOutWithMock(self.project, 'get_images') | ||
4975 | 48 | self.mox.StubOutWithMock(forms, 'get_key_pair_choices') | ||
4976 | 49 | self.mox.StubOutWithMock(forms, 'get_instance_type_choices') | ||
4977 | 50 | |||
4978 | 51 | self.project.get_images().AndReturn([]) | ||
4979 | 52 | forms.get_key_pair_choices(self.project).AndReturn([]) | ||
4980 | 53 | forms.get_instance_type_choices().AndReturn([]) | ||
4981 | 54 | |||
4982 | 55 | self.mox.ReplayAll() | ||
4983 | 56 | |||
4984 | 57 | res = self.client.get(reverse('nova_images', args=[TEST_PROJECT])) | ||
4985 | 58 | self.assertEqual(res.status_code, 200) | ||
4986 | 59 | self.assertTemplateUsed(res, 'django_nova/images/index.html') | ||
4987 | 60 | self.assertEqual(len(res.context['image_lists']), 3) | ||
4988 | 61 | |||
4989 | 62 | self.mox.VerifyAll() | ||
4990 | 63 | |||
4991 | 64 | def test_launch_form(self): | ||
4992 | 65 | self.mox.StubOutWithMock(self.project, 'get_image') | ||
4993 | 66 | self.mox.StubOutWithMock(forms, 'get_key_pair_choices') | ||
4994 | 67 | self.mox.StubOutWithMock(forms, 'get_instance_type_choices') | ||
4995 | 68 | |||
4996 | 69 | self.project.get_image(TEST_IMAGE_ID).AndReturn(self.ami) | ||
4997 | 70 | forms.get_key_pair_choices(self.project).AndReturn([]) | ||
4998 | 71 | forms.get_instance_type_choices().AndReturn([]) | ||
4999 | 72 | |||
5000 | 73 | self.mox.ReplayAll() |
The diff has been truncated for viewing.