Retire repo and note new content in openstack/osops
Change-Id: I44c9ae8142ebfbb720300592d5c4e11c85a275d3 Signed-off-by: Sean McGinnis <sean.mcginnis@gmail.com>
This commit is contained in:
parent
da6cbda514
commit
f63b605d96
41
README
41
README
@ -1,33 +1,12 @@
|
||||
Coda
|
||||
======
|
||||
This project is no longer maintained. Its content has now moved to the
|
||||
https://opendev.org/openstack/osops repo, and further development will
|
||||
continue there.
|
||||
|
||||
Coda is a Horizon dashboard and panel (both share the name) that facilitates resource clean up of a project once that project is no longer needed http://openstack.org
|
||||
The contents of this repository are still available in the Git
|
||||
source code management system. To see the contents of this
|
||||
repository before it reached its end of life, please check out the
|
||||
previous commit with "git checkout HEAD^1".
|
||||
|
||||
Coda Dashboard
|
||||
----------------
|
||||
Coda Dashboard is an extension for OpenStack Dashboard that provides a UI for
|
||||
Coda.
|
||||
|
||||
For developer purposes, please place OpenStack Dashboard extension file, located
|
||||
at *local/_42_coda.py* under horizon/openstack_dashboard/local/enabled
|
||||
directory and run horizon as usual.
|
||||
|
||||
You will need to add the following code to the end of your local_settings.py
|
||||
|
||||
def load_coda():
|
||||
import imp
|
||||
|
||||
#Go up a level, coda should be installed there.
|
||||
local_settings_dir = os.path.split(os.path.dirname(os.path.realpath(__file__)))[0]
|
||||
local_settings_dir+="/dashboards/coda"
|
||||
|
||||
#print local_settings_dir
|
||||
module = imp.load_source("coda", "%s/coda.py" % local_settings_dir)
|
||||
for attr in dir(module):
|
||||
if not attr.startswith('_'):
|
||||
globals()[attr] = getattr(module, attr)
|
||||
|
||||
load_coda()
|
||||
|
||||
This makes sure that the coda.py file containing your settings are imported properly. This is probably a hack
|
||||
but I haven't found a better way to do this yet.
|
||||
For any further questions, please email
|
||||
openstack-discuss@lists.openstack.org or join #openstack-dev on
|
||||
Freenode.
|
||||
|
@ -1,6 +0,0 @@
|
||||
"""The coda dashboard package.
|
||||
|
||||
Coda is a Horizon dashboard and panel (both share the name) that
|
||||
facilitates resource clean up of a project once that project is no longer
|
||||
needed http://openstack.org
|
||||
"""
|
51
coda.py
51
coda.py
@ -1,51 +0,0 @@
|
||||
# Copyright [2015] Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""Settings for the coda panel.
|
||||
|
||||
There may be a better way or place to do this but for now this works
|
||||
so I'm rolling with it.
|
||||
"""
|
||||
|
||||
CODA_USERNAME = "coda_admin"
|
||||
CODA_TENANT_NAME = "coda_admin"
|
||||
CODA_TENANT_ID = "coda_project_id"
|
||||
CODA_PASSWORD = "coda_pw"
|
||||
CODA_AUTH_URL = "http://127.0.0.1:5000/v2.0/"
|
||||
CODA_KEYSTONE_URL = "http://10.23.214.201:35357/v2.0/"
|
||||
|
||||
CODA_AUTH_URL_KEY = "CODA_AUTH_URL"
|
||||
NOVA_ADMIN_URL_KEY = "NOVA_ADMIN_URL"
|
||||
NEUTRON_ADMIN_URL_KEY = "NEUTRON_ADMIN_URL"
|
||||
CINDER_ADMIN_URL_KEY = "CINDER_ADMIN_URL"
|
||||
GLANCE_ADMIN_URL_KEY = "GLANCE_ADMIN_URL"
|
||||
|
||||
CODA_BLACK_LIST = ["00000000001001", "15420898376896"]
|
||||
|
||||
CODA_URL_MAP = {
|
||||
"region-a": {
|
||||
"CODA_AUTH_URL": "http://127.0.0.1:35357/v2.0/",
|
||||
"NOVA_ADMIN_URL": "http://127.0.0.1:8774/v2",
|
||||
"NEUTRON_ADMIN_URL": "http://127.0.0.1:9696/v2.0",
|
||||
"CINDER_ADMIN_URL": "http://127.0.0.1:8776/v2",
|
||||
"GLANCE_ADMIN_URL": "http://127.0.0.1:9292/v2",
|
||||
},
|
||||
# "region-b": {
|
||||
# "CODA_AUTH_URL": "https://127.0.0.1:35357/v2.0/",
|
||||
# "NOVA_ADMIN_URL": "https://127.0.0.1/v2",
|
||||
# "NEUTRON_ADMIN_URL": "https://127.0.0.1/v2.0",
|
||||
# "CINDER_ADMIN_URL": "https://127.0.0.1:8776/v1",
|
||||
# "GLANCE_ADMIN_URL": "https://127.0.0.1:9292/v1.0",
|
||||
# },
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
"""The coda panel package.
|
||||
|
||||
Coda is a Horizon dashboard and panel (both share the name) that
|
||||
facilitates resource clean up of a project once that project is no longer
|
||||
needed http://openstack.org
|
||||
"""
|
194
coda/cinder.py
194
coda/cinder.py
@ -1,194 +0,0 @@
|
||||
# Copyright [2015] Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""
|
||||
All cinder interactions go here.
|
||||
|
||||
Not much else to say.
|
||||
"""
|
||||
|
||||
|
||||
from django.conf import settings
|
||||
import json
|
||||
import requests
|
||||
|
||||
|
||||
def list_volumes(auth_token, region, project_id):
|
||||
"""List volumes."""
|
||||
result = {}
|
||||
|
||||
headers = {
|
||||
"X-Auth-Token": auth_token,
|
||||
"Accept": "application/json",
|
||||
}
|
||||
params = {'all_tenants': '1', 'project_id': project_id}
|
||||
|
||||
if region in settings.CODA_URL_MAP:
|
||||
response = requests.get(
|
||||
"%s/%s/volumes/detail" % (
|
||||
settings.CODA_URL_MAP[region][settings.CINDER_ADMIN_URL_KEY],
|
||||
settings.CODA_TENANT_ID),
|
||||
headers=headers, params=params, verify=False)
|
||||
|
||||
if response.status_code == 200:
|
||||
volumes_dict = json.loads(response.text)
|
||||
|
||||
result = volumes_dict['volumes']
|
||||
else:
|
||||
result['error'] = \
|
||||
repr(response.status_code) + " - " + response.text
|
||||
else:
|
||||
result['error'] = "Invalid region %s specified.", region
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def list_snapshots(auth_token, region, project_id):
|
||||
"""List snapshots."""
|
||||
result = {}
|
||||
|
||||
headers = {
|
||||
"X-Auth-Token": auth_token,
|
||||
"Accept": "application/json",
|
||||
}
|
||||
params = {'all_tenants': '1', 'project_id': project_id}
|
||||
|
||||
if region in settings.CODA_URL_MAP:
|
||||
response = requests.get(
|
||||
"%s/%s/snapshots/detail" % (
|
||||
settings.CODA_URL_MAP[region][settings.CINDER_ADMIN_URL_KEY],
|
||||
settings.CODA_TENANT_ID),
|
||||
headers=headers, params=params, verify=False)
|
||||
|
||||
if response.status_code == 200:
|
||||
snapshots_dict = json.loads(response.text)
|
||||
|
||||
result = snapshots_dict['snapshots']
|
||||
else:
|
||||
result['error'] = \
|
||||
repr(response.status_code) + " - " + response.text
|
||||
else:
|
||||
result['error'] = "Invalid region %s specified.", region
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def list_backups(auth_token, region, project_id):
|
||||
"""List backups."""
|
||||
result = {}
|
||||
|
||||
headers = {
|
||||
"X-Auth-Token": auth_token,
|
||||
"Accept": "application/json"
|
||||
}
|
||||
# todo (nathan) figure out why this changed
|
||||
# params = {'all_tenants': '1', 'project_id': project_id}
|
||||
params = {}
|
||||
|
||||
if region in settings.CODA_URL_MAP:
|
||||
response = requests.get(
|
||||
"%s/%s/backups/detail" % (
|
||||
settings.CODA_URL_MAP[region][settings.CINDER_ADMIN_URL_KEY],
|
||||
settings.CODA_TENANT_ID),
|
||||
headers=headers, params=params, verify=False)
|
||||
|
||||
if response.status_code == 200:
|
||||
backups_dict = json.loads(response.text)
|
||||
|
||||
result = backups_dict['backups']
|
||||
else:
|
||||
result['error'] = \
|
||||
repr(response.status_code) + " - " + response.text
|
||||
else:
|
||||
result['error'] = "Invalid region %s specified.", region
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def delete_volume(auth_token, region, tenant_id, volume_id):
|
||||
"""Delete volumes."""
|
||||
result = 'Volume Deleted'
|
||||
|
||||
if region in settings.CODA_URL_MAP:
|
||||
headers = {
|
||||
"X-Auth-Token": auth_token,
|
||||
"Accept": "application/json",
|
||||
}
|
||||
|
||||
params = {'all_tenants': '1', 'project_id': tenant_id}
|
||||
|
||||
# todo double check why I used codas tenant id here vs user tenant id
|
||||
response = requests.delete("%s/%s/volumes/%s" % (
|
||||
settings.CODA_URL_MAP[region][settings.CINDER_ADMIN_URL_KEY],
|
||||
settings.CODA_TENANT_ID,
|
||||
volume_id), headers=headers, params=params, verify=False)
|
||||
|
||||
if response.status_code != 202:
|
||||
result = repr(response.status_code) + " - " + response.text
|
||||
else:
|
||||
result = "Invalid region %s specified.", region
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def delete_snapshot(auth_token, region, tenant_id, snapshot_id):
|
||||
"""Delete snapshots."""
|
||||
result = 'Snapshot Deleted'
|
||||
|
||||
if region in settings.CODA_URL_MAP:
|
||||
headers = {
|
||||
"X-Auth-Token": auth_token,
|
||||
"Accept": "application/json",
|
||||
}
|
||||
|
||||
params = {'all_tenants': '1', 'project_id': tenant_id}
|
||||
|
||||
# todo double check why I used codas tenant id here vs user tenant id
|
||||
response = requests.delete("%s/%s/snapshots/%s" % (
|
||||
settings.CODA_URL_MAP[region][settings.CINDER_ADMIN_URL_KEY],
|
||||
settings.CODA_TENANT_ID,
|
||||
snapshot_id), headers=headers, params=params, verify=False)
|
||||
|
||||
if response.status_code != 202:
|
||||
result = repr(response.status_code) + " - " + response.text
|
||||
else:
|
||||
result = "Invalid region %s specified.", region
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def delete_backup(auth_token, region, tenant_id, backup_id):
|
||||
"""Delete backups."""
|
||||
result = 'Backup Deleted'
|
||||
|
||||
if region in settings.CODA_URL_MAP:
|
||||
headers = {
|
||||
"X-Auth-Token": auth_token,
|
||||
"Accept": "application/json",
|
||||
}
|
||||
|
||||
params = {'all_tenants': '1', 'project_id': tenant_id}
|
||||
|
||||
# todo double check why I used codas tenant id here vs user tenant id
|
||||
response = requests.delete("%s/%s/backups/%s" % (
|
||||
settings.CODA_URL_MAP[region][settings.CINDER_ADMIN_URL_KEY],
|
||||
settings.CODA_TENANT_ID,
|
||||
backup_id), headers=headers, params=params, verify=False)
|
||||
|
||||
if response.status_code != 202:
|
||||
result = repr(response.status_code) + " - " + response.text
|
||||
else:
|
||||
result = "Invalid region %s specified.", region
|
||||
|
||||
return result
|
90
coda/coda.py
90
coda/coda.py
@ -1,90 +0,0 @@
|
||||
# Copyright [2015] Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""Code that is specific to Coda.
|
||||
|
||||
Methods that aren't specific to an OpenStack API go here.
|
||||
"""
|
||||
|
||||
|
||||
from django.conf import settings
|
||||
from django.core.cache import cache
|
||||
from openstack_dashboard.dashboards.coda.coda import keystone
|
||||
|
||||
CODA_CACHE = 'coda_cache'
|
||||
|
||||
|
||||
def get_coda_regions():
|
||||
"""Return a list of regions for the Coda installation."""
|
||||
return settings.CODA_URL_MAP.keys()
|
||||
|
||||
|
||||
def get_auth_token():
|
||||
"""Abstract getting the Coda auth token from cache or API as needed."""
|
||||
coda_cache = {}
|
||||
|
||||
if cache.get(CODA_CACHE) is not None:
|
||||
coda_cache = cache.get(CODA_CACHE)
|
||||
|
||||
if 'coda_token' not in coda_cache:
|
||||
coda_token = keystone.get_coda_token()
|
||||
coda_cache['coda_token'] = coda_token
|
||||
# keep for an hour
|
||||
cache.set('coda_cache', coda_cache, 3600)
|
||||
else:
|
||||
coda_token = coda_cache['coda_token']
|
||||
|
||||
return coda_token
|
||||
|
||||
|
||||
def fill_image_info(instances, images):
|
||||
"""Use image dict to fill in image name for instances."""
|
||||
for user_id in instances:
|
||||
for instance in instances[user_id]:
|
||||
if images is None:
|
||||
instance['image']['name'] = "Image Info Unavailable"
|
||||
else:
|
||||
for image in images:
|
||||
if image['id'] == instance['image']['id']:
|
||||
instance['image']['name'] = image['name']
|
||||
break
|
||||
|
||||
if 'name' not in instance['image']:
|
||||
instance['image']['name'] = "Error Getting Image Info"
|
||||
|
||||
return instances
|
||||
|
||||
|
||||
def fill_volume_info(volumes, snapshots, backups):
|
||||
"""Unify volume, snapshot, and backup in a single dict."""
|
||||
|
||||
print backups
|
||||
for volume in volumes:
|
||||
volume['snapshots'] = []
|
||||
volume['backups'] = []
|
||||
|
||||
for snapshot in snapshots:
|
||||
if snapshot['volume_id'] == volume['id']:
|
||||
volume['snapshots'].append(snapshot)
|
||||
|
||||
for backup in backups:
|
||||
if backup['volume_id'] == volume['id']:
|
||||
volume['backups'].append(backup)
|
||||
|
||||
return volumes
|
||||
|
||||
|
||||
def is_project_black_listed(project_id):
|
||||
"""Check if a project ID is blacklisted (i.e. shouldn't be cleaned)."""
|
||||
return project_id in settings.CODA_BLACK_LIST
|
163
coda/glance.py
163
coda/glance.py
@ -1,163 +0,0 @@
|
||||
# Copyright [2015] Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""
|
||||
All glance interactions go here.
|
||||
|
||||
Not much else to say.
|
||||
"""
|
||||
|
||||
from django.conf import settings
|
||||
import json
|
||||
import requests
|
||||
|
||||
|
||||
def list_images(auth_token, region, tenant_id):
|
||||
"""List all images for a project."""
|
||||
result = {}
|
||||
limit = 1000
|
||||
|
||||
headers = {
|
||||
"X-Auth-Token": auth_token,
|
||||
"Accept": "application/json",
|
||||
}
|
||||
|
||||
params = {
|
||||
'limit': limit,
|
||||
'is_public': 'None',
|
||||
'property-owner_id': tenant_id,
|
||||
}
|
||||
|
||||
if region in settings.CODA_URL_MAP:
|
||||
response = requests.get(
|
||||
"%s/images/detail" %
|
||||
settings.CODA_URL_MAP[region][settings.GLANCE_ADMIN_URL_KEY],
|
||||
headers=headers,
|
||||
params=params,
|
||||
verify=False)
|
||||
|
||||
if response.status_code == 200:
|
||||
images_dict = json.loads(response.text)
|
||||
|
||||
result = images_dict['images']
|
||||
else:
|
||||
result['error'] = \
|
||||
repr(response.status_code) + " - " + response.text
|
||||
else:
|
||||
result['error'] = "Invalid region %s specified.", region
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def list_all_images(auth_token, region):
|
||||
"""List all images for a region."""
|
||||
result = {'public': []}
|
||||
images = []
|
||||
limit = 1000
|
||||
|
||||
headers = {
|
||||
"X-Auth-Token": auth_token,
|
||||
"Accept": "application/json",
|
||||
}
|
||||
params = {'limit': limit}
|
||||
|
||||
if region in settings.CODA_URL_MAP:
|
||||
response = requests.get(
|
||||
"%s/images" %
|
||||
settings.CODA_URL_MAP[region][settings.GLANCE_ADMIN_URL_KEY],
|
||||
headers=headers, params=params, verify=False)
|
||||
|
||||
if response.status_code == 200:
|
||||
images_dict = json.loads(response.text)
|
||||
count = len(images_dict['images'])
|
||||
|
||||
if count < limit:
|
||||
images.extend(images_dict['images'])
|
||||
else:
|
||||
marker = images_dict['images'][count - 1]['id']
|
||||
images = get_next_images(auth_token, region, limit,
|
||||
images_dict['images'], marker)
|
||||
else:
|
||||
result['error'] = \
|
||||
repr(response.status_code) + " - " + response.text
|
||||
else:
|
||||
result['error'] = "Invalid region %s specified." % region
|
||||
|
||||
for image in images:
|
||||
if image['owner'] is None and image['is_public'] is True:
|
||||
result['public'].append(image)
|
||||
else:
|
||||
if image['owner'] not in result:
|
||||
result[image['owner']] = []
|
||||
|
||||
result[image['owner']].append(image)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def get_next_images(auth_token, region, limit, images, marker):
|
||||
"""Recursive method used to list all images for a region."""
|
||||
headers = {
|
||||
"X-Auth-Token": auth_token,
|
||||
"Accept": "application/json",
|
||||
}
|
||||
params = {'limit': limit, 'is_public': 'None', 'marker': marker}
|
||||
|
||||
response = requests.get(
|
||||
"%s/images/detail" %
|
||||
settings.CODA_URL_MAP[region][settings.GLANCE_ADMIN_URL_KEY],
|
||||
headers=headers,
|
||||
params=params,
|
||||
verify=False)
|
||||
|
||||
if response.status_code == 200:
|
||||
images_dict = json.loads(response.text)
|
||||
count = len(images_dict['images'])
|
||||
|
||||
if len(images_dict['images']) < limit:
|
||||
images.extend(images_dict['images'])
|
||||
else:
|
||||
images.extend(images_dict['images'])
|
||||
marker = images_dict['images'][count - 1]['id']
|
||||
images = get_next_images(auth_token, region, limit, images, marker)
|
||||
else:
|
||||
# todo (nathan) throw exception here
|
||||
print("todo throw exception")
|
||||
|
||||
return images
|
||||
|
||||
|
||||
def delete_image(auth_token, region, image_id):
|
||||
"""Delete the image."""
|
||||
result = 'Image Deleted'
|
||||
|
||||
if region in settings.CODA_URL_MAP:
|
||||
headers = {
|
||||
"X-Auth-Token": auth_token,
|
||||
"Accept": "application/json",
|
||||
}
|
||||
|
||||
response = requests.delete(
|
||||
"%s/images/%s" % (
|
||||
settings.CODA_URL_MAP[region][settings.GLANCE_ADMIN_URL_KEY],
|
||||
image_id),
|
||||
headers=headers,
|
||||
verify=False)
|
||||
|
||||
if response.status_code != 204:
|
||||
result = repr(response.status_code) + " - " + response.text
|
||||
else:
|
||||
result = "Invalid region %s specified.", region
|
||||
|
||||
return result
|
117
coda/keystone.py
117
coda/keystone.py
@ -1,117 +0,0 @@
|
||||
# Copyright [2015] Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""
|
||||
All keystone interactions go here.
|
||||
|
||||
Not much else to say.
|
||||
"""
|
||||
|
||||
|
||||
from django.conf import settings
|
||||
import json
|
||||
import requests
|
||||
|
||||
JSON_HEADERS = {
|
||||
"Content-Type": "application/json",
|
||||
"Accept": "application/json",
|
||||
}
|
||||
|
||||
|
||||
def get_coda_token():
|
||||
"""Return the auth token for the coda user."""
|
||||
payload = {
|
||||
"auth": {
|
||||
"tenantId": settings.CODA_TENANT_ID,
|
||||
"passwordCredentials": {
|
||||
"username": settings.CODA_USERNAME,
|
||||
"password": settings.CODA_PASSWORD
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result = 'error'
|
||||
|
||||
try:
|
||||
response = requests.post(
|
||||
"%s/tokens" % settings.CODA_AUTH_URL,
|
||||
data=json.dumps(payload),
|
||||
headers=JSON_HEADERS,
|
||||
verify=False)
|
||||
|
||||
result = json.loads(response.text)['access']['token']['id']
|
||||
except Exception as ex:
|
||||
print("error in get_coda_token", ex)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def get_project_users(auth_token, project_id):
|
||||
"""Return a map of user info for a given project."""
|
||||
headers = {
|
||||
"X-Auth-Token": auth_token,
|
||||
"Accept": "application/json",
|
||||
}
|
||||
response = requests.get(
|
||||
"%s/tenants/%s/users" % (settings.CODA_KEYSTONE_URL, project_id),
|
||||
headers=headers,
|
||||
verify=False)
|
||||
|
||||
return json.loads(response.text)['users']
|
||||
|
||||
|
||||
def user_authenticate(tenant_id, username, password):
|
||||
"""Get the auth token for a user of Coda."""
|
||||
payload = {
|
||||
"auth": {
|
||||
"tenantId": tenant_id,
|
||||
"passwordCredentials": {
|
||||
"username": username,
|
||||
"password": password
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result = 'error'
|
||||
|
||||
try:
|
||||
response = requests.post("%s/tokens" % settings.CODA_AUTH_URL,
|
||||
data=json.dumps(payload),
|
||||
headers=JSON_HEADERS,
|
||||
verify=False)
|
||||
result = json.loads(response.text)['access']['token']['id']
|
||||
except Exception as ex:
|
||||
print("error in user_authenticate", ex)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def project_exists(auth_token, project_id):
|
||||
"""Check if the project id is valid / exists.
|
||||
|
||||
Returns true with info if it does and false and empty if not.
|
||||
"""
|
||||
headers = {
|
||||
"X-Auth-Token": auth_token,
|
||||
"Accept": "application/json",
|
||||
}
|
||||
response = requests.get(
|
||||
"%s/tenants/%s" % (settings.CODA_KEYSTONE_URL, project_id),
|
||||
headers=headers,
|
||||
verify=False)
|
||||
|
||||
if response.status_code == 200:
|
||||
return True, json.loads(response.text)
|
||||
else:
|
||||
return False, ''
|
359
coda/neutron.py
359
coda/neutron.py
@ -1,359 +0,0 @@
|
||||
# Copyright [2015] Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""
|
||||
All keystone interactions go here.
|
||||
|
||||
Not much else to say.
|
||||
"""
|
||||
|
||||
|
||||
# import logging
|
||||
# from django.core.cache import cache
|
||||
from django.conf import settings
|
||||
import json
|
||||
import requests
|
||||
|
||||
|
||||
def list_floating_ips(auth_token, region, project_id):
|
||||
"""Return a list of maps with floating ip info."""
|
||||
result = {}
|
||||
|
||||
if region in settings.CODA_URL_MAP:
|
||||
headers = {
|
||||
"X-Auth-Token": auth_token,
|
||||
"Accept": "application/json",
|
||||
}
|
||||
params = {'all_tenants': '1', 'tenant_id': project_id}
|
||||
col_filter = "fields=id&fields=floating_ip_address"
|
||||
col_filter += "&fields=fixed_ip_address&fields=port_id"
|
||||
|
||||
response = requests.get(
|
||||
"%s/floatingips?%s" % (
|
||||
settings.CODA_URL_MAP[region][settings.NEUTRON_ADMIN_URL_KEY],
|
||||
col_filter),
|
||||
headers=headers, params=params, verify=False)
|
||||
|
||||
if response.status_code == 200:
|
||||
floating_ip_dict = json.loads(response.text)
|
||||
|
||||
result = floating_ip_dict['floatingips']
|
||||
else:
|
||||
result['error'] = \
|
||||
repr(response.status_code) + " - " + response.text
|
||||
else:
|
||||
result['error'] = "Invalid region %s specified.", region
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def list_security_groups(auth_token, region, project_id):
|
||||
"""Return a list of maps with security group info."""
|
||||
result = {}
|
||||
|
||||
headers = {
|
||||
"X-Auth-Token": auth_token,
|
||||
"Accept": "application/json",
|
||||
}
|
||||
params = {'all_tenants': '1', 'tenant_id': project_id}
|
||||
|
||||
if region in settings.CODA_URL_MAP:
|
||||
response = requests.get(
|
||||
"%s/security-groups" %
|
||||
settings.CODA_URL_MAP[region][settings.NEUTRON_ADMIN_URL_KEY],
|
||||
headers=headers,
|
||||
params=params, verify=False)
|
||||
|
||||
if response.status_code == 200:
|
||||
sec_group_dict = json.loads(response.text)
|
||||
|
||||
result = sec_group_dict['security_groups']
|
||||
result = remove_default_security_group(result)
|
||||
else:
|
||||
result['error'] = \
|
||||
repr(response.status_code) + " - " + response.text
|
||||
else:
|
||||
result['error'] = "Invalid region %s specified.", region
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def list_networks(auth_token, region, project_id):
|
||||
"""List networks."""
|
||||
result = {}
|
||||
|
||||
headers = {
|
||||
"X-Auth-Token": auth_token,
|
||||
"Accept": "application/json",
|
||||
}
|
||||
params = {'all_tenants': '1', 'tenant_id': project_id}
|
||||
|
||||
if region in settings.CODA_URL_MAP:
|
||||
result[region] = {}
|
||||
|
||||
response = requests.get(
|
||||
"%s/networks" %
|
||||
settings.CODA_URL_MAP[region][settings.NEUTRON_ADMIN_URL_KEY],
|
||||
headers=headers,
|
||||
params=params,
|
||||
verify=False)
|
||||
|
||||
if response.status_code == 200:
|
||||
network_dict = json.loads(response.text)
|
||||
|
||||
result = network_dict['networks']
|
||||
else:
|
||||
result['error'] = \
|
||||
repr(response.status_code) + " - " + response.text
|
||||
else:
|
||||
result['error'] = "Invalid region %s specified.", region
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def list_subnets(auth_token, region, project_id):
|
||||
"""List subnets."""
|
||||
result = {}
|
||||
|
||||
headers = {
|
||||
"X-Auth-Token": auth_token,
|
||||
"Accept": "application/json",
|
||||
}
|
||||
params = {'all_tenants': '1', 'tenant_id': project_id}
|
||||
|
||||
if region in settings.CODA_URL_MAP:
|
||||
response = requests.get(
|
||||
"%s/subnets" %
|
||||
settings.CODA_URL_MAP[region][settings.NEUTRON_ADMIN_URL_KEY],
|
||||
headers=headers,
|
||||
params=params,
|
||||
verify=False)
|
||||
|
||||
if response.status_code == 200:
|
||||
subnet_dict = json.loads(response.text)
|
||||
|
||||
result = subnet_dict['subnets']
|
||||
else:
|
||||
result['error'] = \
|
||||
repr(response.status_code) + " - " + response.text
|
||||
else:
|
||||
result['error'] = "Invalid region %s specified.", region
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def list_routers(auth_token, region, project_id):
|
||||
"""List routers."""
|
||||
result = {}
|
||||
|
||||
headers = {
|
||||
"X-Auth-Token": auth_token,
|
||||
"Accept": "application/json",
|
||||
}
|
||||
params = {'tenant_id': project_id}
|
||||
|
||||
if region in settings.CODA_URL_MAP:
|
||||
response = requests.get(
|
||||
"%s/routers" %
|
||||
settings.CODA_URL_MAP[region][settings.NEUTRON_ADMIN_URL_KEY],
|
||||
headers=headers,
|
||||
params=params,
|
||||
verify=False)
|
||||
|
||||
if response.status_code == 200:
|
||||
router_dict = json.loads(response.text)
|
||||
|
||||
result = router_dict['routers']
|
||||
else:
|
||||
result['error'] = \
|
||||
repr(response.status_code) + " - " + response.text
|
||||
else:
|
||||
result['error'] = "Invalid region %s specified.", region
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def delete_floating_ip(auth_token, region, tenant_id, floating_ip_id):
|
||||
"""Delete floating ips."""
|
||||
result = 'Floating IP Deleted'
|
||||
|
||||
if region in settings.CODA_URL_MAP:
|
||||
headers = {
|
||||
"X-Auth-Token": auth_token,
|
||||
"Accept": "application/json",
|
||||
}
|
||||
|
||||
params = {'all_tenants': '1', 'tenant_id': tenant_id, 'fields': 'id'}
|
||||
|
||||
response = requests.delete(
|
||||
"%s/floatingips/%s" % (
|
||||
settings.CODA_URL_MAP[region][settings.NEUTRON_ADMIN_URL_KEY],
|
||||
floating_ip_id),
|
||||
headers=headers,
|
||||
params=params,
|
||||
verify=False)
|
||||
|
||||
if response.status_code != 204:
|
||||
result = repr(response.status_code) + " - " + response.text
|
||||
else:
|
||||
result = "Invalid region %s specified.", region
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def delete_security_group(auth_token, region, tenant_id, security_group_id):
|
||||
"""Delete security groups."""
|
||||
result = 'Security Group Deleted'
|
||||
|
||||
if region in settings.CODA_URL_MAP:
|
||||
headers = {
|
||||
"X-Auth-Token": auth_token,
|
||||
"Accept": "application/json",
|
||||
}
|
||||
|
||||
params = {'all_tenants': '1', 'tenant_id': tenant_id}
|
||||
|
||||
response = requests.delete(
|
||||
"%s/security-groups/%s" % (
|
||||
settings.CODA_URL_MAP[region][settings.NEUTRON_ADMIN_URL_KEY],
|
||||
security_group_id),
|
||||
headers=headers,
|
||||
params=params,
|
||||
verify=False)
|
||||
|
||||
if response.status_code != 204:
|
||||
result = repr(response.status_code) + " - " + response.text
|
||||
else:
|
||||
result = "Invalid region %s specified.", region
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def delete_network(auth_token, region, tenant_id, network_id):
|
||||
"""Delete networks."""
|
||||
result = 'Network Deleted'
|
||||
|
||||
if region in settings.CODA_URL_MAP:
|
||||
headers = {
|
||||
"X-Auth-Token": auth_token,
|
||||
"Accept": "application/json",
|
||||
}
|
||||
|
||||
params = {'all_tenants': '1', 'tenant_id': tenant_id}
|
||||
|
||||
response = requests.delete(
|
||||
"%s/networks/%s" % (
|
||||
settings.CODA_URL_MAP[region][settings.NEUTRON_ADMIN_URL_KEY],
|
||||
network_id),
|
||||
headers=headers,
|
||||
params=params,
|
||||
verify=False)
|
||||
|
||||
if response.status_code != 204:
|
||||
result = repr(response.status_code) + " - " + response.text
|
||||
else:
|
||||
result = "Invalid region %s specified.", region
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def delete_router(auth_token, region, tenant_id, router_id):
|
||||
"""Delete routers."""
|
||||
result = 'Router Deleted'
|
||||
|
||||
if region in settings.CODA_URL_MAP:
|
||||
headers = {
|
||||
"X-Auth-Token": auth_token,
|
||||
"Accept": "application/json",
|
||||
}
|
||||
|
||||
ports = list_ports_for_device(
|
||||
auth_token,
|
||||
settings.CODA_URL_MAP[region][settings.NEUTRON_ADMIN_URL_KEY],
|
||||
tenant_id,
|
||||
router_id)
|
||||
port_error = False
|
||||
|
||||
for port in ports:
|
||||
data = {'port_id': port['id']}
|
||||
|
||||
response = requests.put(
|
||||
"%s/routers/%s/remove_router_interface" %
|
||||
(settings.CODA_URL_MAP[region][settings.NEUTRON_ADMIN_URL_KEY],
|
||||
router_id),
|
||||
headers=headers,
|
||||
data=json.dumps(data),
|
||||
verify=False)
|
||||
|
||||
if response.status_code != 200:
|
||||
result = "Couldn't remove port id [%s]. Delete aborted." \
|
||||
% port['id']
|
||||
port_error = True
|
||||
break
|
||||
|
||||
# Remove the router if the interfaces were cleared ok.
|
||||
if not port_error:
|
||||
params = {'all_tenants': '1', 'tenant_id': tenant_id}
|
||||
response = requests.delete(
|
||||
"%s/routers/%s" %
|
||||
(settings.CODA_URL_MAP[region][settings.NEUTRON_ADMIN_URL_KEY],
|
||||
router_id),
|
||||
headers=headers,
|
||||
params=params,
|
||||
verify=False)
|
||||
|
||||
if response.status_code != 204:
|
||||
result = repr(response.status_code) + " - " + response.text
|
||||
else:
|
||||
result = "Invalid region %s specified.", region
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def list_ports_for_device(auth_token, url_base, tenant_id, device_id):
|
||||
"""Utility method used by delete."""
|
||||
result = {}
|
||||
|
||||
headers = {
|
||||
"X-Auth-Token": auth_token,
|
||||
"Accept": "application/json",
|
||||
}
|
||||
params = {
|
||||
'all_tenants': '1',
|
||||
'tenant_id': tenant_id,
|
||||
'device_id': device_id,
|
||||
}
|
||||
response = requests.get(
|
||||
"%s/ports" % url_base,
|
||||
headers=headers,
|
||||
params=params,
|
||||
verify=False)
|
||||
|
||||
if response.status_code == 200:
|
||||
ports_dict = json.loads(response.text)
|
||||
|
||||
result = ports_dict['ports']
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def remove_default_security_group(security_groups):
|
||||
"""Utility method to prevent default sec group from displaying."""
|
||||
# todo (nathan) awful, use a list comprehension for this
|
||||
result = []
|
||||
for group in security_groups:
|
||||
if group['name'] != 'default':
|
||||
result.append(group)
|
||||
|
||||
return result
|
95
coda/nova.py
95
coda/nova.py
@ -1,95 +0,0 @@
|
||||
# Copyright [2015] Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""
|
||||
All Nova interactions go here.
|
||||
|
||||
Not much else to say.
|
||||
"""
|
||||
|
||||
|
||||
# import logging
|
||||
# from django.core.cache import cache
|
||||
from django.conf import settings
|
||||
import json
|
||||
import requests
|
||||
|
||||
|
||||
def list_instances(auth_token, region, tenant_id):
|
||||
"""Return a map keyed with user ids to a map with instance info."""
|
||||
result = {}
|
||||
|
||||
headers = {
|
||||
"X-Auth-Token": auth_token,
|
||||
"Accept": "application/json",
|
||||
}
|
||||
payload = {'all_tenants': '1', 'tenant_id': tenant_id}
|
||||
|
||||
if region in settings.CODA_URL_MAP:
|
||||
response = requests.get(
|
||||
"%s/%s/servers/detail" % (
|
||||
settings.CODA_URL_MAP[region][settings.NOVA_ADMIN_URL_KEY],
|
||||
settings.CODA_TENANT_ID),
|
||||
headers=headers,
|
||||
params=payload,
|
||||
verify=False)
|
||||
|
||||
if response.status_code == 200:
|
||||
server_dict = json.loads(response.text)
|
||||
|
||||
if "servers" in server_dict:
|
||||
sorted_instances = \
|
||||
sorted(server_dict['servers'], key=lambda k: k['user_id'])
|
||||
|
||||
for instance in sorted_instances:
|
||||
if instance['user_id'] not in result.keys():
|
||||
result[instance['user_id']] = []
|
||||
|
||||
result[instance['user_id']].append(instance)
|
||||
else:
|
||||
result['error'] = \
|
||||
repr(response.status_code) + " - " + response.text
|
||||
else:
|
||||
result['error'] = "Invalid region %s specified.", region
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def delete_instance(auth_token, region, tenant_id, instance_id):
|
||||
"""Delete the instance."""
|
||||
result = 'Instance Deleted'
|
||||
|
||||
if region in settings.CODA_URL_MAP:
|
||||
headers = {
|
||||
"X-Auth-Token": auth_token,
|
||||
"Accept": "application/json",
|
||||
}
|
||||
|
||||
payload = {'all_tenants': '1', 'tenant_id': tenant_id}
|
||||
|
||||
response = requests.delete(
|
||||
"%s/%s/servers/%s" % (
|
||||
settings.CODA_URL_MAP[region][settings.NOVA_ADMIN_URL_KEY],
|
||||
settings.CODA_TENANT_ID,
|
||||
instance_id),
|
||||
headers=headers,
|
||||
params=payload,
|
||||
verify=False)
|
||||
|
||||
if response.status_code != 204:
|
||||
result = repr(response.status_code) + " - " + response.text
|
||||
else:
|
||||
result = "Invalid region %s specified.", region
|
||||
|
||||
return result
|
@ -1,35 +0,0 @@
|
||||
# Copyright [2015] Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""
|
||||
The Coda panel definition.
|
||||
|
||||
Not much else to say.
|
||||
"""
|
||||
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
import horizon
|
||||
from openstack_dashboard.dashboards.coda import dashboard
|
||||
|
||||
|
||||
class Coda(horizon.Panel):
|
||||
"""The Coda panel class."""
|
||||
|
||||
name = _("Coda")
|
||||
slug = "coda"
|
||||
|
||||
|
||||
dashboard.Coda.register(Coda)
|
@ -1,27 +0,0 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Coda - Resource Cleanup" %}{% endblock %}
|
||||
|
||||
{% block page_header %}
|
||||
{% include "horizon/common/_page_header.html" with title=_("Coda - Resource Cleanup") %}
|
||||
{% endblock page_header %}
|
||||
|
||||
{% block main %}
|
||||
<div>
|
||||
<form id="coda_form" action="{% url 'horizon:coda:coda:results' %}" method="post" style="width: 655px">
|
||||
{% csrf_token %}
|
||||
<label for="project_id">Project ID:</label>
|
||||
<input id="project_id" type="text" name="project_id" style="width: 400px" value="{% if project_id %}{{ project_id }}{%endif%}" autofocus="true" tabindex="10"/>
|
||||
<input class="btn btn-primary" type="submit" value="Search" tabindex="20"/>
|
||||
<input id="update_cache" type="checkbox" name="update_cache" value="True" tabindex="20" {% ifequal update_cache 'True' %}checked{%endifequal%}/> Update Cache
|
||||
</form>
|
||||
</div>
|
||||
{% block results %}{% endblock %}
|
||||
{% endblock %}
|
||||
|
||||
{% block js %}
|
||||
{{ block.super }}
|
||||
|
||||
<script type="text/javascript" src="{{ STATIC_URL }}/coda/js/js.cookie.js"></script>
|
||||
{% block custom_js %}{% endblock %}
|
||||
{% endblock %}
|
@ -1,97 +0,0 @@
|
||||
{% extends "coda/coda/coda_base.html" %}
|
||||
{% load staticfiles %}
|
||||
|
||||
{% block title %}Confirm Delete?{% endblock %}
|
||||
|
||||
{% block custom_js %}
|
||||
<script type="text/javascript">
|
||||
function confirmDelete() {
|
||||
if (confirm("Are you sure you want to delete all resources?")) {
|
||||
document.scrubber_form.submit();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
{% block results %}
|
||||
|
||||
<div id="splash">
|
||||
<div class="sidebar">
|
||||
<h2>Project Info</h2>
|
||||
<p>Project Name: {{ project_info.tenant.name }}</p>
|
||||
<p>Project ID: {{ project_info.tenant.id}}</p>
|
||||
<p>Enabled: {{ project_info.tenant.enabled }}</p>
|
||||
<p>Description: {{ project_info.tenant.description}}</p>
|
||||
<input type="hidden" name="project_id" value="{{ project_id }}">
|
||||
{% if users %}
|
||||
<h4>Users:</h4>
|
||||
{% for user in users %}
|
||||
<p>Name: {{ user.name }}</p>
|
||||
<p>Username: {{ user.username }}</p>
|
||||
<p>ID: {{ user.id }}</p>
|
||||
<p>Enabled: {{ user.enabled }}</p>
|
||||
<p>E-Mail: {{ user.email }}</p>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<h4>No Users in this Project</h4>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div id='content_body'>
|
||||
<div class="warning">
|
||||
<h2 class="warning-text">WARNING!</h2>
|
||||
<h3 class="warning-text"> You are about to delete all resources this project. This action cannot be undone.</h3>
|
||||
</div>
|
||||
<div class="row large-rounded">
|
||||
<div id="login" class="confirm">
|
||||
<div class="modal-header">
|
||||
<h3>Enter Admin Credentials to Continue</h3>
|
||||
</div>
|
||||
|
||||
<form id="delete_form" action="{% url 'horizon:coda:coda:delete_resources' %}" method="post">
|
||||
{% csrf_token %}
|
||||
<div class="modal-body clearfix">
|
||||
<div class="messages"></div>
|
||||
|
||||
<fieldset>
|
||||
<input type="hidden" name="domainId" value="{{ domain_id }}">
|
||||
<div class="control-group form-field clearfix ">
|
||||
<label for="os_username">OS_USERNAME</label>
|
||||
<div class="input">
|
||||
<input autofocus="true" id="os_username" name="os_username" tabindex="10" type="text">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group form-field clearfix ">
|
||||
<label for="os_password">OS_PASSWORD</label>
|
||||
|
||||
<div class="input">
|
||||
<input id="os_password" name="os_password" tabindex="20" type="password">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group form-field clearfix ">
|
||||
<label for="os_tenant_id">OS_TENANT_ID</label>
|
||||
<div class="input">
|
||||
<input id="os_tenant_id" name="os_tenant_id" tabindex="30" type="text">
|
||||
</div>
|
||||
</div>
|
||||
<input type="hidden" name="project_id" value="{{ project_id }}">
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button type="submit" class="btn btn-primary pull-right" tabindex="40">Delete Resources</button>
|
||||
<a href="{% url 'horizon:coda:coda:index' %}">
|
||||
<input class="btn pull-right" type="button" value="Cancel" />
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
@ -1,78 +0,0 @@
|
||||
{% load template_utils %}
|
||||
<script type="text/javascript">
|
||||
var backups_{{ region|jsfunc }}_{{ project_id }}_done = false;
|
||||
$(document).ready(function(){
|
||||
var csrftoken = Cookies.get('csrftoken');
|
||||
var project_id = "{{ project_id }}";
|
||||
var region = "{{ region }}";
|
||||
var user_token = "{{ user_token }}";
|
||||
|
||||
$.post('/coda/delete/backups/',
|
||||
{csrfmiddlewaretoken: csrftoken, project_id: project_id, region: region, user_token: user_token},
|
||||
function(data, status) {
|
||||
var resultsDiv = $('#backups_{{ region }}_{{ project_id }}').find('#results');
|
||||
data = JSON.parse(data);
|
||||
|
||||
if(Object.keys(data).length > 0) {
|
||||
var tableWrapper = $("<div>").addClass("table_wrapper");
|
||||
tableWrapper.append("<h3 class=\"table_title\">Backups</h3>");
|
||||
var table = $("<table>");
|
||||
table.addClass("table")
|
||||
table.addClass("table-bordered")
|
||||
table.addClass("datatable")
|
||||
|
||||
var thead = $("<thead>");
|
||||
var tr = $("<tr>");
|
||||
|
||||
tr.append($("<th>UUID</th>").addClass("normal_column"));
|
||||
tr.append($("<th>Outcome</th>").addClass("normal_column"));
|
||||
thead.append(tr);
|
||||
table.append(thead);
|
||||
|
||||
var tbody = $("<tbody>");
|
||||
|
||||
$.map(data, function (outcome, instanceId) {
|
||||
var tr = $("<tr>");
|
||||
tr.append("<td>" + instanceId + "</td>");
|
||||
tr.append("<td>" + outcome + "</td>");
|
||||
tbody.append(tr);
|
||||
});
|
||||
|
||||
table.append(tbody);
|
||||
|
||||
var tfoot = $("<tfoot>");
|
||||
var tr = $("<tr>");
|
||||
var td = $("<td colspan='2'>");
|
||||
var span = $("<span colspan='2'>");
|
||||
var footerMessage = "Displaying " + Object.keys(data).length + " item";
|
||||
if (Object.keys(data).length > 1)
|
||||
footerMessage += "s";
|
||||
|
||||
span.append(footerMessage);
|
||||
td.append(span);
|
||||
tr.append(td);
|
||||
tfoot.append(tr);
|
||||
table.append(tfoot);
|
||||
|
||||
tableWrapper.append(table);
|
||||
resultsDiv.append(tableWrapper);
|
||||
} else {
|
||||
var resultsDiv = $('#backups_{{ region }}_{{ project_id }}').find('#results');
|
||||
resultsDiv.html("<h4>No Backups in region.</h4>")
|
||||
}
|
||||
$('#backups_{{ region }}_{{ project_id }}').find('#deleting').hide();
|
||||
$('#backups_{{ region }}_{{ project_id }}').find('#results').show();
|
||||
backups_{{ region|jsfunc }}_{{ project_id }}_done = true;
|
||||
scrub_volumes_{{ region|jsfunc }}_{{ project_id }}();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="backups_{{ region }}_{{ project_id }}" class="table_wrapper">
|
||||
<div id="deleting">
|
||||
<h3>Deleting Backups...</h3>
|
||||
</div>
|
||||
<div id="results" style="display: none">
|
||||
|
||||
</div>
|
||||
</div>
|
@ -1,78 +0,0 @@
|
||||
{% load template_utils %}
|
||||
<script type="text/javascript">
|
||||
function scrub_floating_ips_{{ region|jsfunc }}_{{ project_id }}(){
|
||||
var csrftoken = Cookies.get('csrftoken');
|
||||
var project_id = "{{ project_id }}";
|
||||
var region = "{{ region }}";
|
||||
var user_token = "{{ user_token }}";
|
||||
|
||||
$('#floating_ips_{{ region }}_{{ project_id }}').find('#deleting').find('h3').html("Deleting floating IPs...")
|
||||
|
||||
$.post('/coda/delete/floating_ips/',
|
||||
{csrfmiddlewaretoken: csrftoken, project_id: project_id, region: region, user_token: user_token},
|
||||
function(data, status) {
|
||||
var resultsDiv = $('#floating_ips_{{ region }}_{{ project_id }}').find('#results');
|
||||
data = JSON.parse(data);
|
||||
|
||||
if(Object.keys(data).length > 0) {
|
||||
var tableWrapper = $("<div>").addClass("table_wrapper");
|
||||
tableWrapper.append("<h3 class=\"table_title\">Floating IPs</h3>");
|
||||
var table = $("<table>");
|
||||
table.addClass("table")
|
||||
table.addClass("table-bordered")
|
||||
table.addClass("datatable")
|
||||
|
||||
var thead = $("<thead>");
|
||||
var tr = $("<tr>");
|
||||
|
||||
tr.append($("<th>UUID</th>").addClass("normal_column"));
|
||||
tr.append($("<th>Outcome</th>").addClass("normal_column"));
|
||||
thead.append(tr);
|
||||
table.append(thead);
|
||||
|
||||
var tbody = $("<tbody>");
|
||||
|
||||
$.map(data, function (outcome, instanceId) {
|
||||
var tr = $("<tr>");
|
||||
tr.append("<td>" + instanceId + "</td>");
|
||||
tr.append("<td>" + outcome + "</td>");
|
||||
tbody.append(tr);
|
||||
});
|
||||
|
||||
table.append(tbody);
|
||||
|
||||
var tfoot = $("<tfoot>");
|
||||
var tr = $("<tr>");
|
||||
var td = $("<td colspan='2'>");
|
||||
var span = $("<span colspan='2'>");
|
||||
var footerMessage = "Displaying " + Object.keys(data).length + " item";
|
||||
if (Object.keys(data).length > 1)
|
||||
footerMessage += "s";
|
||||
|
||||
span.append(footerMessage);
|
||||
td.append(span);
|
||||
tr.append(td);
|
||||
tfoot.append(tr);
|
||||
table.append(tfoot);
|
||||
|
||||
tableWrapper.append(table);
|
||||
resultsDiv.append(tableWrapper);
|
||||
} else {
|
||||
var resultsDiv = $('#floating_ips_{{ region }}_{{ project_id }}').find('#results');
|
||||
resultsDiv.html("<h4>No Floating IPs in region.</h4>")
|
||||
}
|
||||
$('#floating_ips_{{ region }}_{{ project_id }}').find('#deleting').hide();
|
||||
$('#floating_ips_{{ region }}_{{ project_id }}').find('#results').show();
|
||||
wait_security_groups_{{ region|jsfunc }}_{{ project_id }}();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<div id="floating_ips_{{ region }}_{{ project_id }}" class="table_wrapper">
|
||||
<div id="deleting">
|
||||
<h3>Waiting for instances to delete...</h3>
|
||||
</div>
|
||||
<div id="results" style="display: none">
|
||||
|
||||
</div>
|
||||
</div>
|
@ -1,74 +0,0 @@
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function(){
|
||||
var csrftoken = Cookies.get('csrftoken');
|
||||
var project_id = "{{ project_id }}";
|
||||
var region = "{{ region }}";
|
||||
var user_token = "{{ user_token }}";
|
||||
|
||||
$.post('/coda/delete/images/',
|
||||
{csrfmiddlewaretoken: csrftoken, project_id: project_id, region: region, user_token: user_token},
|
||||
function(data, status) {
|
||||
var resultsDiv = $('#images_{{ region }}_{{ project_id }}').find('#results');
|
||||
data = JSON.parse(data);
|
||||
|
||||
if(Object.keys(data).length > 0) {
|
||||
var tableWrapper = $("<div>").addClass("table_wrapper");
|
||||
tableWrapper.append("<h3 class=\"table_title\">Images</h3>");
|
||||
var table = $("<table>");
|
||||
table.addClass("table")
|
||||
table.addClass("table-bordered")
|
||||
table.addClass("datatable")
|
||||
|
||||
var thead = $("<thead>");
|
||||
var tr = $("<tr>");
|
||||
|
||||
tr.append($("<th>UUID</th>").addClass("normal_column"));
|
||||
tr.append($("<th>Outcome</th>").addClass("normal_column"));
|
||||
thead.append(tr);
|
||||
table.append(thead);
|
||||
|
||||
var tbody = $("<tbody>");
|
||||
|
||||
$.map(data, function (outcome, instanceId) {
|
||||
var tr = $("<tr>");
|
||||
tr.append("<td>" + instanceId + "</td>");
|
||||
tr.append("<td>" + outcome + "</td>");
|
||||
tbody.append(tr);
|
||||
});
|
||||
|
||||
table.append(tbody);
|
||||
|
||||
var tfoot = $("<tfoot>");
|
||||
var tr = $("<tr>");
|
||||
var td = $("<td colspan='2'>");
|
||||
var span = $("<span colspan='2'>");
|
||||
var footerMessage = "Displaying " + Object.keys(data).length + " item";
|
||||
if (Object.keys(data).length > 1)
|
||||
footerMessage += "s";
|
||||
|
||||
span.append(footerMessage);
|
||||
td.append(span);
|
||||
tr.append(td);
|
||||
tfoot.append(tr);
|
||||
table.append(tfoot);
|
||||
|
||||
tableWrapper.append(table);
|
||||
resultsDiv.append(tableWrapper);
|
||||
} else {
|
||||
var resultsDiv = $('#images_{{ region }}_{{ project_id }}').find('#results');
|
||||
resultsDiv.html("<h4>No Images in region.</h4>")
|
||||
}
|
||||
$('#images_{{ region }}_{{ project_id }}').find('#deleting').hide();
|
||||
$('#images_{{ region }}_{{ project_id }}').find('#results').show();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="images_{{ region }}_{{ project_id }}" class="table_wrapper">
|
||||
<div id="deleting">
|
||||
<h3>Deleting Images...</h3>
|
||||
</div>
|
||||
<div id="results" style="display: none">
|
||||
|
||||
</div>
|
||||
</div>
|
@ -1,76 +0,0 @@
|
||||
{% load template_utils %}
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function(){
|
||||
var csrftoken = Cookies.get('csrftoken');
|
||||
var project_id = "{{ project_id }}";
|
||||
var region = "{{ region }}";
|
||||
var user_token = "{{ user_token }}";
|
||||
|
||||
$.post('/coda/delete/instances/',
|
||||
{csrfmiddlewaretoken: csrftoken, project_id: project_id, region: region, user_token: user_token},
|
||||
function(data, status) {
|
||||
var resultsDiv = $('#instances_{{ region }}_{{ project_id }}').find('#results');
|
||||
data = JSON.parse(data);
|
||||
|
||||
if(Object.keys(data).length > 0) {
|
||||
var tableWrapper = $("<div>").addClass("table_wrapper");
|
||||
tableWrapper.append("<h3 class=\"table_title\">Instances</h3>");
|
||||
var table = $("<table>");
|
||||
table.addClass("table")
|
||||
table.addClass("table-bordered")
|
||||
table.addClass("datatable")
|
||||
|
||||
var thead = $("<thead>");
|
||||
var tr = $("<tr>");
|
||||
|
||||
tr.append($("<th>UUID</th>").addClass("normal_column"));
|
||||
tr.append($("<th>Outcome</th>").addClass("normal_column"));
|
||||
thead.append(tr);
|
||||
table.append(thead);
|
||||
|
||||
var tbody = $("<tbody>");
|
||||
|
||||
$.map(data, function (outcome, instanceId) {
|
||||
var tr = $("<tr>");
|
||||
tr.append("<td>" + instanceId + "</td>");
|
||||
tr.append("<td>" + outcome + "</td>");
|
||||
tbody.append(tr);
|
||||
});
|
||||
|
||||
table.append(tbody);
|
||||
|
||||
var tfoot = $("<tfoot>");
|
||||
var tr = $("<tr>");
|
||||
var td = $("<td colspan='2'>");
|
||||
var span = $("<span colspan='2'>");
|
||||
var footerMessage = "Displaying " + Object.keys(data).length + " item";
|
||||
if (Object.keys(data).length > 1)
|
||||
footerMessage += "s";
|
||||
|
||||
span.append(footerMessage);
|
||||
td.append(span);
|
||||
tr.append(td);
|
||||
tfoot.append(tr);
|
||||
table.append(tfoot);
|
||||
|
||||
tableWrapper.append(table);
|
||||
resultsDiv.append(tableWrapper);
|
||||
} else {
|
||||
var resultsDiv = $('#instances_{{ region }}_{{ project_id }}').find('#results');
|
||||
resultsDiv.html("<h4>No Instances in region.</h4>")
|
||||
}
|
||||
$('#instances_{{ region }}_{{ project_id }}').find('#deleting').hide();
|
||||
$('#instances_{{ region }}_{{ project_id }}').find('#results').show();
|
||||
scrub_floating_ips_{{ region|jsfunc }}_{{ project_id }}();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="instances_{{ region }}_{{ project_id }}" class="table_wrapper">
|
||||
<div id="deleting">
|
||||
<h3>Deleting instances...</h3>
|
||||
</div>
|
||||
<div id="results" style="display: none">
|
||||
|
||||
</div>
|
||||
</div>
|
@ -1,77 +0,0 @@
|
||||
{% load template_utils %}
|
||||
<script type="text/javascript">
|
||||
function scrub_networks_{{ region|jsfunc }}_{{ project_id }}(){
|
||||
var csrftoken = Cookies.get('csrftoken');
|
||||
var project_id = "{{ project_id }}";
|
||||
var region = "{{ region }}";
|
||||
var user_token = "{{ user_token }}";
|
||||
|
||||
$('#networks_{{ region }}_{{ project_id }}').find('#deleting').find('h3').html("Deleting Networks...")
|
||||
|
||||
$.post('/coda/delete/networks/',
|
||||
{csrfmiddlewaretoken: csrftoken, project_id: project_id, region: region, user_token: user_token},
|
||||
function(data, status) {
|
||||
var resultsDiv = $('#networks_{{ region }}_{{ project_id }}').find('#results');
|
||||
data = JSON.parse(data);
|
||||
|
||||
if(Object.keys(data).length > 0) {
|
||||
var tableWrapper = $("<div>").addClass("table_wrapper");
|
||||
tableWrapper.append("<h3 class=\"table_title\">Networks</h3>");
|
||||
var table = $("<table>");
|
||||
table.addClass("table")
|
||||
table.addClass("table-bordered")
|
||||
table.addClass("datatable")
|
||||
|
||||
var thead = $("<thead>");
|
||||
var tr = $("<tr>");
|
||||
|
||||
tr.append($("<th>UUID</th>").addClass("normal_column"));
|
||||
tr.append($("<th>Outcome</th>").addClass("normal_column"));
|
||||
thead.append(tr);
|
||||
table.append(thead);
|
||||
|
||||
var tbody = $("<tbody>");
|
||||
|
||||
$.map(data, function (outcome, instanceId) {
|
||||
var tr = $("<tr>");
|
||||
tr.append("<td>" + instanceId + "</td>");
|
||||
tr.append("<td>" + outcome + "</td>");
|
||||
tbody.append(tr);
|
||||
});
|
||||
|
||||
table.append(tbody);
|
||||
|
||||
var tfoot = $("<tfoot>");
|
||||
var tr = $("<tr>");
|
||||
var td = $("<td colspan='2'>");
|
||||
var span = $("<span colspan='2'>");
|
||||
var footerMessage = "Displaying " + Object.keys(data).length + " item";
|
||||
if (Object.keys(data).length > 1)
|
||||
footerMessage += "s";
|
||||
|
||||
span.append(footerMessage);
|
||||
td.append(span);
|
||||
tr.append(td);
|
||||
tfoot.append(tr);
|
||||
table.append(tfoot);
|
||||
|
||||
tableWrapper.append(table);
|
||||
resultsDiv.append(tableWrapper);
|
||||
} else {
|
||||
var resultsDiv = $('#networks_{{ region }}_{{ project_id }}').find('#results');
|
||||
resultsDiv.html("<h4>No Networks in region.</h4>")
|
||||
}
|
||||
$('#networks_{{ region }}_{{ project_id }}').find('#deleting').hide();
|
||||
$('#networks_{{ region }}_{{ project_id }}').find('#results').show();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<div id="networks_{{ region }}_{{ project_id }}" class="table_wrapper">
|
||||
<div id="deleting">
|
||||
<h3>Waiting for Routers to delete...</h3>
|
||||
</div>
|
||||
<div id="results" style="display: none">
|
||||
|
||||
</div>
|
||||
</div>
|
@ -1,51 +0,0 @@
|
||||
{% extends "coda/coda/coda_base.html" %}
|
||||
{% load staticfiles %}
|
||||
|
||||
{% block title %}Delete Results{% endblock %}
|
||||
|
||||
{% block results %}
|
||||
|
||||
<div id="main_content">
|
||||
<div class="sidebar">
|
||||
<h2>Project Info</h2>
|
||||
<div style="margin-left: 14px">
|
||||
<p>Project Name: {{ project_info.tenant.name }}</p>
|
||||
<p>Project ID: {{ project_info.tenant.id}}</p>
|
||||
<p>Enabled: {{ project_info.tenant.enabled }}</p>
|
||||
<p>Description: {{ project_info.tenant.description}}</p>
|
||||
<input type="hidden" name="project_id" value="{{ project_id }}">
|
||||
{% if users %}
|
||||
<h4>Users:</h4>
|
||||
{% for user in users %}
|
||||
<p>Name: {{ user.name }}</p>
|
||||
<p>Username: {{ user.username }}</p>
|
||||
<p>ID: {{ user.id }}</p>
|
||||
<p>Enabled: {{ user.enabled }}</p>
|
||||
<p>E-Mail: {{ user.email }}</p>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<h4>No Users in this Project</h4>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id='content_body'>
|
||||
<h1>Coda Results for Project ID: {{ project_id }}</h1>
|
||||
{% for region in regions %}
|
||||
<h2>Region: {{ region }}</h2>
|
||||
{% include "coda/coda/delete/instances.html" %}
|
||||
{% include "coda/coda/delete/floating_ips.html" %}
|
||||
{% include "coda/coda/delete/security_groups.html" %}
|
||||
{% include "coda/coda/delete/routers.html" %}
|
||||
{% include "coda/coda/delete/networks.html" %}
|
||||
{% include "coda/coda/delete/snapshots.html" %}
|
||||
{% include "coda/coda/delete/backups.html" %}
|
||||
{% include "coda/coda/delete/volumes.html" %}
|
||||
{% include "coda/coda/delete/images.html" %}
|
||||
{% endfor %} <!-- END region for loop -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
|
@ -1,78 +0,0 @@
|
||||
{% load template_utils %}
|
||||
<script type="text/javascript">
|
||||
function scrub_routers_{{ region|jsfunc }}_{{ project_id }}(){
|
||||
var csrftoken = Cookies.get('csrftoken');
|
||||
var project_id = "{{ project_id }}";
|
||||
var region = "{{ region }}";
|
||||
var user_token = "{{ user_token }}";
|
||||
|
||||
$('#routers_{{ region }}_{{ project_id }}').find('#deleting').find('h3').html("Deleting Routers...")
|
||||
|
||||
$.post('/coda/delete/routers/',
|
||||
{csrfmiddlewaretoken: csrftoken, project_id: project_id, region: region, user_token: user_token},
|
||||
function(data, status) {
|
||||
var resultsDiv = $('#routers_{{ region }}_{{ project_id }}').find('#results');
|
||||
data = JSON.parse(data);
|
||||
|
||||
if(Object.keys(data).length > 0) {
|
||||
var tableWrapper = $("<div>").addClass("table_wrapper");
|
||||
tableWrapper.append("<h3 class=\"table_title\">Routers</h3>");
|
||||
var table = $("<table>");
|
||||
table.addClass("table")
|
||||
table.addClass("table-bordered")
|
||||
table.addClass("datatable")
|
||||
|
||||
var thead = $("<thead>");
|
||||
var tr = $("<tr>");
|
||||
|
||||
tr.append($("<th>UUID</th>").addClass("normal_column"));
|
||||
tr.append($("<th>Outcome</th>").addClass("normal_column"));
|
||||
thead.append(tr);
|
||||
table.append(thead);
|
||||
|
||||
var tbody = $("<tbody>");
|
||||
|
||||
$.map(data, function (outcome, instanceId) {
|
||||
var tr = $("<tr>");
|
||||
tr.append("<td>" + instanceId + "</td>");
|
||||
tr.append("<td>" + outcome + "</td>");
|
||||
tbody.append(tr);
|
||||
});
|
||||
|
||||
table.append(tbody);
|
||||
|
||||
var tfoot = $("<tfoot>");
|
||||
var tr = $("<tr>");
|
||||
var td = $("<td colspan='2'>");
|
||||
var span = $("<span colspan='2'>");
|
||||
var footerMessage = "Displaying " + Object.keys(data).length + " item";
|
||||
if (Object.keys(data).length > 1)
|
||||
footerMessage += "s";
|
||||
|
||||
span.append(footerMessage);
|
||||
td.append(span);
|
||||
tr.append(td);
|
||||
tfoot.append(tr);
|
||||
table.append(tfoot);
|
||||
|
||||
tableWrapper.append(table);
|
||||
resultsDiv.append(tableWrapper);
|
||||
} else {
|
||||
var resultsDiv = $('#routers_{{ region }}_{{ project_id }}').find('#results');
|
||||
resultsDiv.html("<h4>No Routers in region.</h4>")
|
||||
}
|
||||
$('#routers_{{ region }}_{{ project_id }}').find('#deleting').hide();
|
||||
$('#routers_{{ region }}_{{ project_id }}').find('#results').show();
|
||||
scrub_networks_{{ region|jsfunc }}_{{ project_id }}();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<div id="routers_{{ region }}_{{ project_id }}" class="table_wrapper">
|
||||
<div id="deleting">
|
||||
<h3>Waiting for Security Groups to delete...</h3>
|
||||
</div>
|
||||
<div id="results" style="display: none">
|
||||
|
||||
</div>
|
||||
</div>
|
@ -1,83 +0,0 @@
|
||||
{% load template_utils %}
|
||||
<script type="text/javascript">
|
||||
function wait_security_groups_{{ region|jsfunc }}_{{ project_id }}(){
|
||||
$('#security_groups_{{ region }}_{{ project_id }}').find('#deleting').find('h3').html("Floating IP's deleted. Waiting a few seconds for ports to clear...")
|
||||
setTimeout(function() { scrub_security_groups_{{ region|jsfunc }}_{{ project_id }}() }, 5000);
|
||||
}
|
||||
|
||||
function scrub_security_groups_{{ region|jsfunc }}_{{ project_id }}(){
|
||||
var csrftoken = Cookies.get('csrftoken');
|
||||
var project_id = "{{ project_id }}";
|
||||
var region = "{{ region }}";
|
||||
var user_token = "{{ user_token }}";
|
||||
|
||||
$('#security_groups_{{ region }}_{{ project_id }}').find('#deleting').find('h3').html("Deleting security groups...")
|
||||
|
||||
$.post('/coda/delete/security_groups/',
|
||||
{csrfmiddlewaretoken: csrftoken, project_id: project_id, region: region, user_token: user_token},
|
||||
function(data, status) {
|
||||
var resultsDiv = $('#security_groups_{{ region }}_{{ project_id }}').find('#results');
|
||||
data = JSON.parse(data);
|
||||
|
||||
if(Object.keys(data).length > 0) {
|
||||
var tableWrapper = $("<div>").addClass("table_wrapper");
|
||||
tableWrapper.append("<h3 class=\"table_title\">Security Groups</h3>");
|
||||
var table = $("<table>");
|
||||
table.addClass("table")
|
||||
table.addClass("table-bordered")
|
||||
table.addClass("datatable")
|
||||
|
||||
var thead = $("<thead>");
|
||||
var tr = $("<tr>");
|
||||
|
||||
tr.append($("<th>UUID</th>").addClass("normal_column"));
|
||||
tr.append($("<th>Outcome</th>").addClass("normal_column"));
|
||||
thead.append(tr);
|
||||
table.append(thead);
|
||||
|
||||
var tbody = $("<tbody>");
|
||||
|
||||
$.map(data, function (outcome, instanceId) {
|
||||
var tr = $("<tr>");
|
||||
tr.append("<td>" + instanceId + "</td>");
|
||||
tr.append("<td>" + outcome + "</td>");
|
||||
tbody.append(tr);
|
||||
});
|
||||
|
||||
table.append(tbody);
|
||||
|
||||
var tfoot = $("<tfoot>");
|
||||
var tr = $("<tr>");
|
||||
var td = $("<td colspan='2'>");
|
||||
var span = $("<span colspan='2'>");
|
||||
var footerMessage = "Displaying " + Object.keys(data).length + " item";
|
||||
if (Object.keys(data).length > 1)
|
||||
footerMessage += "s";
|
||||
|
||||
span.append(footerMessage);
|
||||
td.append(span);
|
||||
tr.append(td);
|
||||
tfoot.append(tr);
|
||||
table.append(tfoot);
|
||||
|
||||
tableWrapper.append(table);
|
||||
resultsDiv.append(tableWrapper);
|
||||
} else {
|
||||
var resultsDiv = $('#security_groups_{{ region }}_{{ project_id }}').find('#results');
|
||||
resultsDiv.html("<h4>No Security Groups in region.</h4>")
|
||||
}
|
||||
$('#security_groups_{{ region }}_{{ project_id }}').find('#deleting').hide();
|
||||
$('#security_groups_{{ region }}_{{ project_id }}').find('#results').show();
|
||||
scrub_routers_{{ region|jsfunc }}_{{ project_id }}();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<div id="security_groups_{{ region }}_{{ project_id }}" class="table_wrapper">
|
||||
<div id="deleting">
|
||||
<h3>Waiting for Floating IPs to delete...</h3>
|
||||
</div>
|
||||
<div id="results" style="display: none">
|
||||
|
||||
</div>
|
||||
</div>
|
@ -1,79 +0,0 @@
|
||||
{% load template_utils %}
|
||||
<script type="text/javascript">
|
||||
var snapshots_{{ region|jsfunc }}_{{ project_id }}_done = false;
|
||||
|
||||
$(document).ready(function(){
|
||||
var csrftoken = Cookies.get('csrftoken');
|
||||
var project_id = "{{ project_id }}";
|
||||
var region = "{{ region }}";
|
||||
var user_token = "{{ user_token }}";
|
||||
|
||||
$.post('/coda/delete/snapshots/',
|
||||
{csrfmiddlewaretoken: csrftoken, project_id: project_id, region: region, user_token: user_token},
|
||||
function(data, status) {
|
||||
var resultsDiv = $('#snapshots_{{ region }}_{{ project_id }}').find('#results');
|
||||
data = JSON.parse(data);
|
||||
|
||||
if(Object.keys(data).length > 0) {
|
||||
var tableWrapper = $("<div>").addClass("table_wrapper");
|
||||
tableWrapper.append("<h3 class=\"table_title\">Snapshots</h3>");
|
||||
var table = $("<table>");
|
||||
table.addClass("table")
|
||||
table.addClass("table-bordered")
|
||||
table.addClass("datatable")
|
||||
|
||||
var thead = $("<thead>");
|
||||
var tr = $("<tr>");
|
||||
|
||||
tr.append($("<th>UUID</th>").addClass("normal_column"));
|
||||
tr.append($("<th>Outcome</th>").addClass("normal_column"));
|
||||
thead.append(tr);
|
||||
table.append(thead);
|
||||
|
||||
var tbody = $("<tbody>");
|
||||
|
||||
$.map(data, function (outcome, instanceId) {
|
||||
var tr = $("<tr>");
|
||||
tr.append("<td>" + instanceId + "</td>");
|
||||
tr.append("<td>" + outcome + "</td>");
|
||||
tbody.append(tr);
|
||||
});
|
||||
|
||||
table.append(tbody);
|
||||
|
||||
var tfoot = $("<tfoot>");
|
||||
var tr = $("<tr>");
|
||||
var td = $("<td colspan='2'>");
|
||||
var span = $("<span colspan='2'>");
|
||||
var footerMessage = "Displaying " + Object.keys(data).length + " item";
|
||||
if (Object.keys(data).length > 1)
|
||||
footerMessage += "s";
|
||||
|
||||
span.append(footerMessage);
|
||||
td.append(span);
|
||||
tr.append(td);
|
||||
tfoot.append(tr);
|
||||
table.append(tfoot);
|
||||
|
||||
tableWrapper.append(table);
|
||||
resultsDiv.append(tableWrapper);
|
||||
} else {
|
||||
var resultsDiv = $('#snapshots_{{ region }}_{{ project_id }}').find('#results');
|
||||
resultsDiv.html("<h4>No Snapshots in region.</h4>")
|
||||
}
|
||||
$('#snapshots_{{ region }}_{{ project_id }}').find('#deleting').hide();
|
||||
$('#snapshots_{{ region }}_{{ project_id }}').find('#results').show();
|
||||
snapshots_{{ region|jsfunc }}_{{ project_id }}_done = true;
|
||||
scrub_volumes_{{ region|jsfunc }}_{{ project_id }}();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="snapshots_{{ region }}_{{ project_id }}" class="table_wrapper">
|
||||
<div id="deleting">
|
||||
<h3>Deleting Snapshots...</h3>
|
||||
</div>
|
||||
<div id="results" style="display: none">
|
||||
|
||||
</div>
|
||||
</div>
|
@ -1,87 +0,0 @@
|
||||
{% load template_utils %}
|
||||
<script type="text/javascript">
|
||||
function scrub_volumes_{{ region|jsfunc }}_{{ project_id }}(){
|
||||
var csrftoken = Cookies.get('csrftoken');
|
||||
var project_id = "{{ project_id }}";
|
||||
var region = "{{ region }}";
|
||||
var user_token = "{{ user_token }}";
|
||||
|
||||
if (!backups_{{ region|jsfunc }}_{{ project_id }}_done) {
|
||||
$('#volumes_{{ region }}_{{ project_id }}').find('#deleting').find('h3').html("Waiting for Backups to delete...")
|
||||
return;
|
||||
}
|
||||
|
||||
if (!snapshots_{{ region|jsfunc }}_{{ project_id }}_done) {
|
||||
$('#volumes_{{ region }}_{{ project_id }}').find('#deleting').find('h3').html("Waiting for Snapshots to delete...")
|
||||
return;
|
||||
}
|
||||
|
||||
$('#volumes_{{ region }}_{{ project_id }}').find('#deleting').find('h3').html("Deleting Volumes...")
|
||||
|
||||
$.post('/coda/delete/volumes/',
|
||||
{csrfmiddlewaretoken: csrftoken, project_id: project_id, region: region, user_token: user_token},
|
||||
function(data, status) {
|
||||
var resultsDiv = $('#volumes_{{ region }}_{{ project_id }}').find('#results');
|
||||
data = JSON.parse(data);
|
||||
|
||||
if(Object.keys(data).length > 0) {
|
||||
var tableWrapper = $("<div>").addClass("table_wrapper");
|
||||
tableWrapper.append("<h3 class=\"table_title\">Volumes</h3>");
|
||||
var table = $("<table>");
|
||||
table.addClass("table")
|
||||
table.addClass("table-bordered")
|
||||
table.addClass("datatable")
|
||||
|
||||
var thead = $("<thead>");
|
||||
var tr = $("<tr>");
|
||||
|
||||
tr.append($("<th>UUID</th>").addClass("normal_column"));
|
||||
tr.append($("<th>Outcome</th>").addClass("normal_column"));
|
||||
thead.append(tr);
|
||||
table.append(thead);
|
||||
|
||||
var tbody = $("<tbody>");
|
||||
|
||||
$.map(data, function (outcome, instanceId) {
|
||||
var tr = $("<tr>");
|
||||
tr.append("<td>" + instanceId + "</td>");
|
||||
tr.append("<td>" + outcome + "</td>");
|
||||
tbody.append(tr);
|
||||
});
|
||||
|
||||
table.append(tbody);
|
||||
|
||||
var tfoot = $("<tfoot>");
|
||||
var tr = $("<tr>");
|
||||
var td = $("<td colspan='2'>");
|
||||
var span = $("<span colspan='2'>");
|
||||
var footerMessage = "Displaying " + Object.keys(data).length + " item";
|
||||
if (Object.keys(data).length > 1)
|
||||
footerMessage += "s";
|
||||
|
||||
span.append(footerMessage);
|
||||
td.append(span);
|
||||
tr.append(td);
|
||||
tfoot.append(tr);
|
||||
table.append(tfoot);
|
||||
|
||||
tableWrapper.append(table);
|
||||
resultsDiv.append(tableWrapper);
|
||||
} else {
|
||||
var resultsDiv = $('#volumes_{{ region }}_{{ project_id }}').find('#results');
|
||||
resultsDiv.html("<h4>No Volumes in region.</h4>")
|
||||
}
|
||||
$('#volumes_{{ region }}_{{ project_id }}').find('#deleting').hide();
|
||||
$('#volumes_{{ region }}_{{ project_id }}').find('#results').show();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<div id="volumes_{{ region }}_{{ project_id }}" class="table_wrapper">
|
||||
<div id="deleting">
|
||||
<h3>Waiting for Backups and Snapshots to delete...</h3>
|
||||
</div>
|
||||
<div id="results" style="display: none">
|
||||
|
||||
</div>
|
||||
</div>
|
@ -1,11 +0,0 @@
|
||||
{% extends "coda/coda/coda_base.html" %}
|
||||
{% load staticfiles %}
|
||||
|
||||
{% block title %}Error{% endblock %}
|
||||
|
||||
{% block results %}
|
||||
<div>
|
||||
<h1 style="color: red; text-align: center">Error!</h1>
|
||||
<h2 style="color: red; text-align: center">{{ error_message }}</h2>
|
||||
</div>
|
||||
{% endblock %}
|
@ -1,65 +0,0 @@
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function(){
|
||||
var csrftoken = Cookies.get('csrftoken');
|
||||
var project_id = "{{ project_id }}";
|
||||
var region = "{{ region }}";
|
||||
var update_cache = "{{ update_cache }}";
|
||||
|
||||
$.post('/coda/floating_ips/', {csrfmiddlewaretoken: csrftoken, project_id: project_id, region: region, update_cache: update_cache}, function(data, status){
|
||||
var tbody = $('#floatingips_{{ region }}_{{ project_id }}').find('tbody');
|
||||
data = JSON.parse(data);
|
||||
|
||||
if(data.length > 0) {
|
||||
$.each(data, function (i, floatingip) {
|
||||
var tr = $("<tr>");
|
||||
tr.append("<td>" + floatingip.id + "</td>");
|
||||
tr.append("<td>" + floatingip.floating_ip_address + "</td>");
|
||||
tr.append("<td>" + floatingip.fixed_ip_address + "</td>");
|
||||
tr.append("<td>" + floatingip.port_id + "</td>");
|
||||
tbody.append(tr);
|
||||
});
|
||||
|
||||
|
||||
var footerMessage = "Displaying " + data.length + " item";
|
||||
if(data.length > 1)
|
||||
footerMessage+="s";
|
||||
|
||||
$('#floatingips_{{ region }}_{{ project_id }}').find('span').text(footerMessage);
|
||||
} else {
|
||||
var resultsDiv = $('#floatingips_{{ region }}_{{ project_id }}').find('#results');
|
||||
resultsDiv.html("<h4>No Floating IPs in region.</h4>")
|
||||
}
|
||||
$('#floatingips_{{ region }}_{{ project_id }}').find('#querying').hide();
|
||||
$('#floatingips_{{ region }}_{{ project_id }}').find('#results').show();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<div id="floatingips_{{ region }}_{{ project_id }}" class="table_wrapper">
|
||||
<div id="querying">
|
||||
<h3>Querying floating IPs for region: {{ region }}...</h3>
|
||||
</div>
|
||||
<div id="results" style="display: none">
|
||||
<h3 class="table_title">Floating IPs</h3>
|
||||
<table class="table table-bordered datatable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="normal_column">UUID</th>
|
||||
<th class="normal_column">Floating Address</th>
|
||||
<th class="normal_column">Fixed Address</th>
|
||||
<th class="normal_column">Port ID</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="4">
|
||||
<span class="table_count"></span>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
@ -1,64 +0,0 @@
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function(){
|
||||
var csrftoken = Cookies.get('csrftoken');
|
||||
var project_id = "{{ project_id }}";
|
||||
var region = "{{ region }}";
|
||||
var update_cache = "{{ update_cache }}";
|
||||
|
||||
$.post('/coda/images/', {csrfmiddlewaretoken: csrftoken, project_id: project_id, region: region, update_cache: update_cache}, function(data, status){
|
||||
var tbody = $('#images_{{ region }}_{{ project_id }}').find('tbody');
|
||||
data = JSON.parse(data);
|
||||
|
||||
if(data.length > 0) {
|
||||
$.each(data, function (i, image) {
|
||||
var tr = $("<tr>");
|
||||
tr.append("<td>" + image.id + "</td>");
|
||||
tr.append("<td>" + image.name + "</td>");
|
||||
tr.append("<td>" + image.status + "</td>");
|
||||
tr.append("<td>" + image.created_at + "</td>");
|
||||
tbody.append(tr);
|
||||
});
|
||||
|
||||
var footerMessage = "Displaying " + data.length + " item";
|
||||
if (data.length > 1)
|
||||
footerMessage += "s";
|
||||
|
||||
$('#images_{{ region }}_{{ project_id }}').find('span').text(footerMessage);
|
||||
} else {
|
||||
var resultsDiv = $('#images_{{ region }}_{{ project_id }}').find('#results');
|
||||
resultsDiv.html("<h4>No Images in region.</h4>")
|
||||
}
|
||||
$('#images_{{ region }}_{{ project_id }}').find('#querying').hide();
|
||||
$('#images_{{ region }}_{{ project_id }}').find('#results').show();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<div id="images_{{ region }}_{{ project_id }}" class="table_wrapper">
|
||||
<div id="querying">
|
||||
<h3>Querying Images for region: {{ region }}...</h3>
|
||||
</div>
|
||||
<div id="results" style="display: none">
|
||||
<h3 class="table_title">Images</h3>
|
||||
<table class="table table-bordered datatable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="normal_column">UUID</th>
|
||||
<th class="normal_column">Name</th>
|
||||
<th class="normal_column">Status</th>
|
||||
<th class="normal_column">Created</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="4">
|
||||
<span class="table_count"></span>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
@ -1,4 +0,0 @@
|
||||
{% extends "coda/coda/coda_base.html" %}
|
||||
{% load staticfiles %}
|
||||
|
||||
|
@ -1,87 +0,0 @@
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function(){
|
||||
var csrftoken = Cookies.get('csrftoken');
|
||||
var project_id = "{{ project_id }}";
|
||||
var region = "{{ region }}";
|
||||
var update_cache = "{{ update_cache }}";
|
||||
|
||||
$.post('/coda/instances/', {csrfmiddlewaretoken: csrftoken, project_id: project_id, region: region, update_cache: update_cache}, function(data, status) {
|
||||
var resultsDiv = $('#instances_{{ region }}_{{ project_id }}').find('#results');
|
||||
data = JSON.parse(data);
|
||||
|
||||
if(Object.keys(data).length > 0) {
|
||||
$.map(data, function (instancesList, userID) {
|
||||
var tableWrapper = $("<div>").addClass("table_wrapper");
|
||||
tableWrapper.append("<h3 class=\"table_title\">Instances for User ID: " + userID + "</h3>");
|
||||
var table = $("<table>");
|
||||
table.addClass("table")
|
||||
table.addClass("table-bordered")
|
||||
table.addClass("datatable")
|
||||
|
||||
var thead = $("<thead>");
|
||||
var tr = $("<tr>");
|
||||
|
||||
tr.append($("<th>UUID</th>").addClass("normal_column"));
|
||||
tr.append($("<th>Name</th>").addClass("normal_column"));
|
||||
tr.append($("<th>Flavor</th>").addClass("normal_column"));
|
||||
tr.append($("<th>Status</th>").addClass("normal_column"));
|
||||
tr.append($("<th>Task</th>").addClass("normal_column"));
|
||||
tr.append($("<th>Power</th>").addClass("normal_column"));
|
||||
tr.append($("<th>Hypervisor</th>").addClass("normal_column"));
|
||||
tr.append($("<th>Image Id</th>").addClass("normal_column"));
|
||||
tr.append($("<th>Image Name</th>").addClass("normal_column"));
|
||||
thead.append(tr);
|
||||
table.append(thead);
|
||||
|
||||
var tbody = $("<tbody>");
|
||||
|
||||
$.each(instancesList, function (i, instance) {
|
||||
var tr = $("<tr>");
|
||||
tr.append("<td>" + instance.id + "</td>");
|
||||
tr.append("<td>" + instance.name + "</td>");
|
||||
tr.append("<td>" + instance.flavor.id + "</td>");
|
||||
tr.append("<td>" + instance.status + "</td>");
|
||||
tr.append("<td>" + instance["OS-EXT-STS:task_state"] + "</td>");
|
||||
tr.append("<td>" + instance["OS-EXT-STS:power_state"] + "</td>");
|
||||
tr.append("<td>" + instance["OS-EXT-SRV-ATTR:hypervisor_hostname"] + "</td>");
|
||||
tr.append("<td>" + instance.image.id + "</td>");
|
||||
tr.append("<td>" + instance.image.name + "</td>");
|
||||
tbody.append(tr);
|
||||
});
|
||||
table.append(tbody);
|
||||
|
||||
var tfoot = $("<tfoot>");
|
||||
var tr = $("<tr>");
|
||||
var td = $("<td colspan='9'>");
|
||||
var span = $("<span colspan='9'>");
|
||||
var footerMessage = "Displaying " + instancesList.length + " item";
|
||||
if (instancesList.length > 1)
|
||||
footerMessage += "s";
|
||||
|
||||
span.append(footerMessage);
|
||||
td.append(span);
|
||||
tr.append(td);
|
||||
tfoot.append(tr);
|
||||
table.append(tfoot);
|
||||
|
||||
tableWrapper.append(table);
|
||||
resultsDiv.append(tableWrapper);
|
||||
});
|
||||
} else {
|
||||
var resultsDiv = $('#instances_{{ region }}_{{ project_id }}').find('#results');
|
||||
resultsDiv.html("<h4>No Instances in region.</h4>")
|
||||
}
|
||||
$('#instances_{{ region }}_{{ project_id }}').find('#querying').hide();
|
||||
$('#instances_{{ region }}_{{ project_id }}').find('#results').show();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="instances_{{ region }}_{{ project_id }}" class="table_wrapper">
|
||||
<div id="querying">
|
||||
<h3>Querying instances for region: {{ region }}...</h3>
|
||||
</div>
|
||||
<div id="results" style="display: none">
|
||||
|
||||
</div>
|
||||
</div>
|
@ -1,62 +0,0 @@
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function(){
|
||||
var csrftoken = Cookies.get('csrftoken');
|
||||
var project_id = "{{ project_id }}";
|
||||
var region = "{{ region }}";
|
||||
var update_cache = "{{ update_cache }}";
|
||||
|
||||
$.post('/coda/networks/', {csrfmiddlewaretoken: csrftoken, project_id: project_id, region: region, update_cache: update_cache}, function(data, status){
|
||||
var tbody = $('#networks_{{ region }}_{{ project_id }}').find('tbody');
|
||||
data = JSON.parse(data);
|
||||
|
||||
if(data.length > 0) {
|
||||
$.each(data, function (i, network) {
|
||||
var tr = $("<tr>");
|
||||
tr.append("<td>" + network.id + "</td>");
|
||||
tr.append("<td>" + network.name + "</td>");
|
||||
tr.append("<td>" + network.status + "</td>");
|
||||
tbody.append(tr);
|
||||
});
|
||||
|
||||
var footerMessage = "Displaying " + data.length + " item";
|
||||
if (data.length > 1)
|
||||
footerMessage += "s";
|
||||
|
||||
$('#networks_{{ region }}_{{ project_id }}').find('span').text(footerMessage);
|
||||
} else {
|
||||
var resultsDiv = $('#networks_{{ region }}_{{ project_id }}').find('#results');
|
||||
resultsDiv.html("<h4>No Networks in region.</h4>")
|
||||
}
|
||||
$('#networks_{{ region }}_{{ project_id }}').find('#querying').hide();
|
||||
$('#networks_{{ region }}_{{ project_id }}').find('#results').show();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<div id="networks_{{ region }}_{{ project_id }}" class="table_wrapper">
|
||||
<div id="querying">
|
||||
<h3>Querying networks for region: {{ region }}...</h3>
|
||||
</div>
|
||||
<div id="results" style="display: none">
|
||||
<h3 class="table_title">Networks</h3>
|
||||
<table class="table table-bordered datatable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="normal_column">UUID</th>
|
||||
<th class="normal_column">Name</th>
|
||||
<th class="normal_column">Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="3">
|
||||
<span class="table_count"></span>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
@ -1,11 +0,0 @@
|
||||
{% extends "coda/coda/coda_base.html" %}
|
||||
{% load staticfiles %}
|
||||
|
||||
{% block title %}No Project Found{% endblock %}
|
||||
|
||||
|
||||
{% block results %}
|
||||
<div>
|
||||
<h2 style="text-align: center">No records found that match Project ID {{ project_id }}.</h2>
|
||||
</div>
|
||||
{% endblock %}
|
@ -1,54 +0,0 @@
|
||||
{% extends "coda/coda/coda_base.html" %}
|
||||
{% load staticfiles %}
|
||||
|
||||
{% block results %}
|
||||
<div id="main_content">
|
||||
<div class="sidebar">
|
||||
<h2>Project Info</h2>
|
||||
<form id="coda_form" action="{% url 'horizon:coda:coda:confirm_delete' %}" method="post">
|
||||
{% csrf_token %}
|
||||
<p>Project Name: {{ project_info.tenant.name }}</p>
|
||||
<p>Project ID: {{ project_info.tenant.id}}</p>
|
||||
<p>Enabled: {{ project_info.tenant.enabled }}</p>
|
||||
<p>Description: {{ project_info.tenant.description}}</p>
|
||||
<input type="hidden" name="project_id" value="{{ project_id }}">
|
||||
{% if users %}
|
||||
<h4>Users:</h4>
|
||||
{% for user in users %}
|
||||
<p>Name: {{ user.name }}</p>
|
||||
<p>Username: {{ user.username }}</p>
|
||||
<p>ID: {{ user.id }}</p>
|
||||
<p>Enabled: {{ user.enabled }}</p>
|
||||
<p>E-Mail: {{ user.email }}</p>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<h4>No Users in this Project</h4>
|
||||
{% endif %}
|
||||
|
||||
<div style="text-align: right; margin-right: 14px; margin-bottom: 10px;">
|
||||
<a href="{% url 'horizon:coda:coda:index' %}">
|
||||
<input class="btn" type="button" value="Cancel" />
|
||||
</a>
|
||||
<input class="btn btn-primary" type="submit" value="Delete Resources">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id='content_body'>
|
||||
<div class="tenant-header">
|
||||
<h1>Resources for {{ project_id }}</h1>
|
||||
</div>
|
||||
{% for region in regions %}
|
||||
<h2>Region: {{ region }}</h2>
|
||||
{% include "coda/coda/instances.html" %}
|
||||
{% include "coda/coda/floating_ips.html" %}
|
||||
{% include "coda/coda/security_groups.html" %}
|
||||
{% include "coda/coda/networks.html" %}
|
||||
{% include "coda/coda/subnets.html" %}
|
||||
{% include "coda/coda/routers.html" %}
|
||||
{% include "coda/coda/volumes.html" %}
|
||||
{% include "coda/coda/images.html" %}
|
||||
{% endfor %} <!-- END region for loop -->
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
@ -1,68 +0,0 @@
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function(){
|
||||
var csrftoken = Cookies.get('csrftoken');
|
||||
var project_id = "{{ project_id }}";
|
||||
var region = "{{ region }}";
|
||||
var update_cache = "{{ update_cache }}";
|
||||
|
||||
$.post('/coda/routers/', {csrfmiddlewaretoken: csrftoken, project_id: project_id, region: region, update_cache: update_cache}, function(data, status){
|
||||
var tbody = $('#routers_{{ region }}_{{ project_id }}').find('tbody');
|
||||
data = JSON.parse(data);
|
||||
|
||||
if(data.length > 0) {
|
||||
$.each(data, function (i, router) {
|
||||
var tr = $("<tr>");
|
||||
tr.append("<td>" + router.id + "</td>");
|
||||
tr.append("<td>" + router.name + "</td>");
|
||||
tr.append("<td>" + router.status + "</td>");
|
||||
if (router.external_gateway_info != null)
|
||||
tr.append("<td>" + router.external_gateway_info.network_id + "</td>");
|
||||
else
|
||||
tr.append("<td>null</td>");
|
||||
|
||||
tbody.append(tr);
|
||||
});
|
||||
|
||||
var footerMessage = "Displaying " + data.length + " item";
|
||||
if (data.length > 1)
|
||||
footerMessage += "s";
|
||||
|
||||
$('#routers_{{ region }}_{{ project_id }}').find('span').text(footerMessage);
|
||||
} else {
|
||||
var resultsDiv = $('#routers_{{ region }}_{{ project_id }}').find('#results');
|
||||
resultsDiv.html("<h4>No Routers in region.</h4>")
|
||||
}
|
||||
$('#routers_{{ region }}_{{ project_id }}').find('#querying').hide();
|
||||
$('#routers_{{ region }}_{{ project_id }}').find('#results').show();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<div id="routers_{{ region }}_{{ project_id }}" class="table_wrapper">
|
||||
<div id="querying">
|
||||
<h3>Querying Routers for region: {{ region }}...</h3>
|
||||
</div>
|
||||
<div id="results" style="display: none">
|
||||
<h3 class="table_title">Routers</h3>
|
||||
<table class="table table-bordered datatable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="normal_column">UUID</th>
|
||||
<th class="normal_column">Name</th>
|
||||
<th class="normal_column">Status</th>
|
||||
<th class="normal_column">Gateway</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="4">
|
||||
<span class="table_count"></span>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
@ -1,95 +0,0 @@
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function(){
|
||||
var csrftoken = Cookies.get('csrftoken');
|
||||
var project_id = "{{ project_id }}";
|
||||
var region = "{{ region }}";
|
||||
var update_cache = "{{ update_cache }}";
|
||||
|
||||
$.post('/coda/security_groups/', {csrfmiddlewaretoken: csrftoken, project_id: project_id, region: region, update_cache: update_cache}, function(data, status){
|
||||
var tbody = $('#securitygroups_{{ region }}_{{ project_id }}').find('tbody');
|
||||
data = JSON.parse(data);
|
||||
|
||||
if(data.length > 0) {
|
||||
$.each(data, function (i, secgroup) {
|
||||
var tr = $("<tr>");
|
||||
|
||||
var rulesBody = $("<tbody>");
|
||||
tr.append("<td>" + secgroup.name + "</td>");
|
||||
tr.append("<td>" + secgroup.description + "</td>");
|
||||
tr.append("<td>" + secgroup.id + "</td>");
|
||||
|
||||
$.each(secgroup.security_group_rules, function (i, rule) {
|
||||
var rulesRow = $("<tr>");
|
||||
rulesRow.append("<td>" + rule.id + "</td>");
|
||||
rulesRow.append("<td>" + rule.direction + "</td>");
|
||||
rulesRow.append("<td>" + rule.protocol + "</td>");
|
||||
rulesRow.append("<td>" + rule.port_range_min + "</td>");
|
||||
rulesRow.append("<td>" + rule.port_range_max + "</td>");
|
||||
rulesRow.append("<td>" + rule.remote_ip_prefix + "</td>");
|
||||
rulesBody.append(rulesRow);
|
||||
});
|
||||
|
||||
var ruleTable = $("<table>");
|
||||
var ruleHeaderRow = $("<tr>");
|
||||
ruleTable.addClass("table")
|
||||
ruleTable.addClass("table-bordered")
|
||||
ruleTable.addClass("datatable")
|
||||
|
||||
ruleHeaderRow.append($("<th>UUID</th>").addClass("normal_column"));
|
||||
ruleHeaderRow.append($("<th>Direction</th>").addClass("normal_column"));
|
||||
ruleHeaderRow.append($("<th>Protocol</th>").addClass("normal_column"));
|
||||
ruleHeaderRow.append($("<th>Min Port</th>").addClass("normal_column"));
|
||||
ruleHeaderRow.append($("<th>Max Port</th>").addClass("normal_column"));
|
||||
ruleHeaderRow.append($("<th>CIDR</th>").addClass("normal_column"));
|
||||
|
||||
ruleTable.append($("<thead>").append(ruleHeaderRow));
|
||||
ruleTable.append(rulesBody);
|
||||
ruleTable.append($("<tfoot>").append($("<tr>").append($("<td colspan='6'>"))));
|
||||
|
||||
tr.append($("<td>").append(ruleTable));
|
||||
tbody.append(tr);
|
||||
});
|
||||
|
||||
var footerMessage = "Displaying " + data.length + " item";
|
||||
if (data.length > 1)
|
||||
footerMessage += "s";
|
||||
|
||||
$('#securitygroups_{{ region }}_{{ project_id }}').find('span').text(footerMessage);
|
||||
} else {
|
||||
var resultsDiv = $('#securitygroups_{{ region }}_{{ project_id }}').find('#results');
|
||||
resultsDiv.html("<h4>No Security Groups in region.</h4>")
|
||||
}
|
||||
$('#securitygroups_{{ region }}_{{ project_id }}').find('#querying').hide();
|
||||
$('#securitygroups_{{ region }}_{{ project_id }}').find('#results').show();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<div id="securitygroups_{{ region }}_{{ project_id }}" class="table_wrapper">
|
||||
<div id="querying">
|
||||
<h3>Querying Security Groups for region: {{ region }}...</h3>
|
||||
</div>
|
||||
<div id="results" style="display: none">
|
||||
<h3 class="table_title">Security Groups</h3>
|
||||
<table class="table table-bordered datatable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="normal_column">Name</th>
|
||||
<th class="normal_column">Description</th>
|
||||
<th class="normal_column">UUID</th>
|
||||
<th class="normal_column">Rules</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="4">
|
||||
<span class="table_count"></span>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
@ -1,62 +0,0 @@
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function(){
|
||||
var csrftoken = Cookies.get('csrftoken');
|
||||
var project_id = "{{ project_id }}";
|
||||
var region = "{{ region }}";
|
||||
var update_cache = "{{ update_cache }}";
|
||||
|
||||
$.post('/coda/subnets/', {csrfmiddlewaretoken: csrftoken, project_id: project_id, region: region, update_cache: update_cache}, function(data, status){
|
||||
var tbody = $('#subnets_{{ region }}_{{ project_id }}').find('tbody');
|
||||
data = JSON.parse(data);
|
||||
|
||||
if(data.length > 0) {
|
||||
$.each(data, function (i, subnet) {
|
||||
var tr = $("<tr>");
|
||||
tr.append("<td>" + subnet.id + "</td>");
|
||||
tr.append("<td>" + subnet.name + "</td>");
|
||||
tr.append("<td>" + subnet.cidr + "</td>");
|
||||
tbody.append(tr);
|
||||
});
|
||||
|
||||
var footerMessage = "Displaying " + data.length + " item";
|
||||
if (data.length > 1)
|
||||
footerMessage += "s";
|
||||
|
||||
$('#subnets_{{ region }}_{{ project_id }}').find('span').text(footerMessage);
|
||||
} else {
|
||||
var resultsDiv = $('#subnets_{{ region }}_{{ project_id }}').find('#results');
|
||||
resultsDiv.html("<h4>No Subnets in region.</h4>")
|
||||
}
|
||||
$('#subnets_{{ region }}_{{ project_id }}').find('#querying').hide();
|
||||
$('#subnets_{{ region }}_{{ project_id }}').find('#results').show();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<div id="subnets_{{ region }}_{{ project_id }}" class="table_wrapper">
|
||||
<div id="querying">
|
||||
<h3>Querying Subnets for region: {{ region }}...</h3>
|
||||
</div>
|
||||
<div id="results" style="display: none">
|
||||
<h3 class="table_title">Subnets</h3>
|
||||
<table class="table table-bordered datatable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="normal_column">UUID</th>
|
||||
<th class="normal_column">Name</th>
|
||||
<th class="normal_column">CIDR</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="3">
|
||||
<span class="table_count"></span>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
@ -1,146 +0,0 @@
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function(){
|
||||
var csrftoken = Cookies.get('csrftoken');
|
||||
var project_id = "{{ project_id }}";
|
||||
var region = "{{ region }}";
|
||||
var update_cache = "{{ update_cache }}";
|
||||
|
||||
$.post('/coda/volumes/', {csrfmiddlewaretoken: csrftoken, project_id: project_id, region: region, update_cache: update_cache}, function(data, status){
|
||||
var tbody = $('#volumes_{{ region }}_{{ project_id }}').find('tbody');
|
||||
data = JSON.parse(data);
|
||||
|
||||
if(data.length > 0) {
|
||||
$.each(data, function (i, volume) {
|
||||
var tr = $("<tr>");
|
||||
|
||||
tr.append("<td>" + volume.id + "</td>");
|
||||
tr.append("<td>" + volume.display_name + "</td>");
|
||||
tr.append("<td>" + volume.display_description + "</td>");
|
||||
tr.append("<td>" + volume.created_at + "</td>");
|
||||
tr.append("<td>" + volume.status + "</td>");
|
||||
tr.append("<td>" + volume.size + "</td>");
|
||||
tr.append("<td>" + volume.availability_zone + "</td>");
|
||||
|
||||
if (volume.snapshots.length > 0) {
|
||||
var snapshotsBody = $("<tbody>");
|
||||
|
||||
$.each(volume.snapshots, function (i, snapshot) {
|
||||
var snapshotsRow = $("<tr>");
|
||||
snapshotsRow.append("<td>" + snapshot.id + "</td>");
|
||||
snapshotsRow.append("<td>" + snapshot.display_name + "</td>");
|
||||
snapshotsRow.append("<td>" + snapshot.display_description + "</td>");
|
||||
snapshotsRow.append("<td>" + snapshot.created_at + "</td>");
|
||||
snapshotsRow.append("<td>" + snapshot.status + "</td>");
|
||||
snapshotsRow.append("<td>" + snapshot.size + "</td>");
|
||||
snapshotsBody.append(snapshotsRow);
|
||||
|
||||
});
|
||||
|
||||
var snapshotTable = $("<table>");
|
||||
var snapshotHeaderRow = $("<tr>");
|
||||
snapshotTable.addClass("table");
|
||||
snapshotTable.addClass("table-bordered");
|
||||
snapshotTable.addClass("datatable");
|
||||
|
||||
snapshotHeaderRow.append($("<th>UUID</th>").addClass("normal_column"));
|
||||
snapshotHeaderRow.append($("<th>Name</th>").addClass("normal_column"));
|
||||
snapshotHeaderRow.append($("<th>Description</th>").addClass("normal_column"));
|
||||
snapshotHeaderRow.append($("<th>Created</th>").addClass("normal_column"));
|
||||
snapshotHeaderRow.append($("<th>Status</th>").addClass("normal_column"));
|
||||
snapshotHeaderRow.append($("<th>Size</th>").addClass("normal_column"));
|
||||
|
||||
snapshotTable.append($("<thead>").append(snapshotHeaderRow));
|
||||
snapshotTable.append(snapshotsBody);
|
||||
snapshotTable.append($("<tfoot>").append($("<tr>").append($("<td colspan='6'>"))));
|
||||
|
||||
tr.append($("<td>").append(snapshotTable));
|
||||
} else {
|
||||
tr.append($("<td>").append($("<h4>No Snapshots</h4>")));
|
||||
}
|
||||
|
||||
if (volume.backups.length > 0) {
|
||||
var backupsBody = $("<tbody>");
|
||||
|
||||
$.each(volume.backups, function (i, backup) {
|
||||
var backupRow = $("<tr>");
|
||||
backupRow.append("<td>" + backup.id + "</td>");
|
||||
backupRow.append("<td>" + backup.display_name + "</td>");
|
||||
backupRow.append("<td>" + backup.display_description + "</td>");
|
||||
backupRow.append("<td>" + backup.created_at + "</td>");
|
||||
backupRow.append("<td>" + backup.status + "</td>");
|
||||
backupRow.append("<td>" + backup.size + "</td>");
|
||||
backupsBody.append(backupRow);
|
||||
});
|
||||
|
||||
var backupTable = $("<table>");
|
||||
var backupHeaderRow = $("<tr>");
|
||||
backupTable.addClass("table");
|
||||
backupTable.addClass("table-bordered");
|
||||
backupTable.addClass("datatable");
|
||||
|
||||
backupHeaderRow.append($("<th>UUID</th>").addClass("normal_column"));
|
||||
backupHeaderRow.append($("<th>Name</th>").addClass("normal_column"));
|
||||
backupHeaderRow.append($("<th>Description</th>").addClass("normal_column"));
|
||||
backupHeaderRow.append($("<th>Created</th>").addClass("normal_column"));
|
||||
backupHeaderRow.append($("<th>Status</th>").addClass("normal_column"));
|
||||
backupHeaderRow.append($("<th>Size</th>").addClass("normal_column"));
|
||||
|
||||
backupTable.append($("<thead>").append(backupHeaderRow));
|
||||
backupTable.append(backupsBody);
|
||||
backupTable.append($("<tfoot>").append($("<tr>").append($("<td colspan='6'>"))));
|
||||
|
||||
tr.append($("<td>").append(backupTable));
|
||||
} else {
|
||||
tr.append($("<td>").append($("<h4>No Backups</h4>")));
|
||||
}
|
||||
tbody.append(tr);
|
||||
});
|
||||
|
||||
var footerMessage = "Displaying " + data.length + " item";
|
||||
if (data.length > 1)
|
||||
footerMessage += "s";
|
||||
|
||||
$('#volumes_{{ region }}_{{ project_id }}').find('span').text(footerMessage);
|
||||
} else {
|
||||
var resultsDiv = $('#volumes_{{ region }}_{{ project_id }}').find('#results');
|
||||
resultsDiv.html("<h4>No Volumes in region.</h4>");
|
||||
}
|
||||
$('#volumes_{{ region }}_{{ project_id }}').find('#querying').hide();
|
||||
$('#volumes_{{ region }}_{{ project_id }}').find('#results').show();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<div id="volumes_{{ region }}_{{ project_id }}" class="table_wrapper">
|
||||
<div id="querying">
|
||||
<h3>Querying Volumes for region: {{ region }}...</h3>
|
||||
</div>
|
||||
<div id="results" style="display: none">
|
||||
<h3 class="table_title">Volumes</h3>
|
||||
<table class="table table-bordered datatable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="normal_column">UUID</th>
|
||||
<th class="normal_column">Name</th>
|
||||
<th class="normal_column">Description</th>
|
||||
<th class="normal_column">Created</th>
|
||||
<th class="normal_column">Status</th>
|
||||
<th class="normal_column">Size</th>
|
||||
<th class="normal_column">Zone</th>
|
||||
<th class="normal_column">Snapshots</th>
|
||||
<th class="normal_column">Backups</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="9">
|
||||
<span class="table_count"></span>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
@ -1,30 +0,0 @@
|
||||
# Copyright [2015] Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""
|
||||
Tests go here.
|
||||
|
||||
Not much else to say.
|
||||
"""
|
||||
|
||||
|
||||
from horizon.test import helpers as test
|
||||
|
||||
|
||||
class CodaTests(test.TestCase):
|
||||
"""Moar tests."""
|
||||
|
||||
def test_me(self):
|
||||
"""Test me."""
|
||||
self.assertTrue(1 + 1 == 2)
|
58
coda/urls.py
58
coda/urls.py
@ -1,58 +0,0 @@
|
||||
# Copyright [2015] Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""
|
||||
Url patterns for Coda.
|
||||
|
||||
Not much else to say.
|
||||
"""
|
||||
|
||||
|
||||
from django.conf.urls import patterns
|
||||
from django.conf.urls import url
|
||||
|
||||
from openstack_dashboard.dashboards.coda.coda import views
|
||||
|
||||
|
||||
urlpatterns = patterns(
|
||||
'',
|
||||
url(r'^$', views.IndexView.as_view(), name='index'),
|
||||
url(r'^results/$', views.results, name='results'),
|
||||
url(r'^instances/$', views.instances, name='instances'),
|
||||
url(r'^floating_ips/$', views.floating_ips, name='floating_ips'),
|
||||
url(r'^security_groups/$', views.security_groups, name='security_groups'),
|
||||
url(r'^networks/$', views.networks, name='networks'),
|
||||
url(r'^subnets/$', views.subnets, name='subnets'),
|
||||
url(r'^routers/$', views.routers, name='routers'),
|
||||
url(r'^volumes/$', views.volumes, name='volumes'),
|
||||
url(r'^images/$', views.images, name='images'),
|
||||
url(r'^confirm_delete/$', views.confirm_delete, name='confirm_delete'),
|
||||
url(r'^delete/results/$', views.delete_resources, name='delete_resources'),
|
||||
url(r'^delete/instances/$',
|
||||
views.delete_instances,
|
||||
name='delete_instances'),
|
||||
url(r'^delete/floating_ips/$',
|
||||
views.delete_floating_ips,
|
||||
name='delete_floating_ips'),
|
||||
url(r'^delete/security_groups/$',
|
||||
views.delete_security_groups,
|
||||
name='delete_security_groups'),
|
||||
url(r'^delete/networks/$', views.delete_networks, name='delete_networks'),
|
||||
url(r'^delete/routers/$', views.delete_routers, name='delete_routers'),
|
||||
url(r'^delete/snapshots/$', views.delete_snapshots,
|
||||
name='delete_snapshots'),
|
||||
url(r'^delete/backups/$', views.delete_backups, name='delete_backups'),
|
||||
url(r'^delete/volumes/$', views.delete_volumes, name='delete_volumes'),
|
||||
url(r'^delete/images/$', views.delete_images, name='delete_images'),
|
||||
)
|
574
coda/views.py
574
coda/views.py
@ -1,574 +0,0 @@
|
||||
# Copyright [2015] Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""
|
||||
The Coda views.
|
||||
|
||||
Not much else to say right now.
|
||||
"""
|
||||
|
||||
|
||||
from django.core.cache import cache
|
||||
from django.http import HttpResponse
|
||||
from django.shortcuts import render
|
||||
# from django.conf import settings
|
||||
from horizon import views
|
||||
import json
|
||||
from openstack_dashboard.dashboards.coda.coda import cinder
|
||||
from openstack_dashboard.dashboards.coda.coda import coda
|
||||
from openstack_dashboard.dashboards.coda.coda import glance
|
||||
from openstack_dashboard.dashboards.coda.coda import keystone
|
||||
from openstack_dashboard.dashboards.coda.coda import neutron
|
||||
from openstack_dashboard.dashboards.coda.coda import nova
|
||||
|
||||
DISPATCH_MAP = {
|
||||
'instances': nova.list_instances,
|
||||
'floating_ips': neutron.list_floating_ips,
|
||||
'security_groups': neutron.list_security_groups,
|
||||
'networks': neutron.list_networks,
|
||||
'subnets': neutron.list_subnets,
|
||||
'routers': neutron.list_routers,
|
||||
'volumes': cinder.list_volumes,
|
||||
'snapshots': cinder.list_snapshots,
|
||||
'backups': cinder.list_backups,
|
||||
'images': glance.list_images
|
||||
}
|
||||
|
||||
|
||||
class IndexView(views.APIView):
|
||||
"""Class based definition of the index view."""
|
||||
|
||||
template_name = 'coda/coda/index.html'
|
||||
|
||||
def get_data(self, request, context, *args, **kwargs):
|
||||
"""No context needed."""
|
||||
return context
|
||||
|
||||
|
||||
def results(request):
|
||||
"""The results view."""
|
||||
project_id = request.POST['project_id']
|
||||
update_cache = request.POST.get('update_cache', 'False')
|
||||
|
||||
auth_token = coda.get_auth_token()
|
||||
|
||||
if auth_token == 'error':
|
||||
msg = "Coda User failed to authenticate with the Identity Service."
|
||||
context = {
|
||||
'project_id': project_id,
|
||||
'error_message': msg
|
||||
}
|
||||
return render(request, 'coda/coda/error.html', context)
|
||||
|
||||
project_exists, project_info = keystone.project_exists(
|
||||
auth_token,
|
||||
project_id)
|
||||
|
||||
if project_exists:
|
||||
users = keystone.get_project_users(auth_token, project_id)
|
||||
regions = coda.get_coda_regions()
|
||||
|
||||
context = {
|
||||
'project_id': project_id,
|
||||
'project_info': project_info,
|
||||
'users': users,
|
||||
'regions': regions,
|
||||
'update_cache': update_cache,
|
||||
}
|
||||
|
||||
return render(request, 'coda/coda/results.html', context)
|
||||
else:
|
||||
context = {
|
||||
'project_id': project_id
|
||||
}
|
||||
return render(request, 'coda/coda/no_project.html', context)
|
||||
|
||||
|
||||
def instances(request):
|
||||
"""The instances view."""
|
||||
project_id = request.POST['project_id']
|
||||
region = request.POST['region']
|
||||
update_cache = request.POST.get('update_cache', 'True')
|
||||
|
||||
instances_dict = get_project_resource(
|
||||
region,
|
||||
project_id,
|
||||
'instances',
|
||||
update_cache)
|
||||
|
||||
# todo (nathan) fix this later broken during port from hp pub cloud
|
||||
# images_key = region + '_coda_images'
|
||||
# coda_images = cache.get(images_key)
|
||||
coda_images = None
|
||||
|
||||
if coda_images is not None:
|
||||
image_list = []
|
||||
|
||||
if 'public' in coda_images:
|
||||
image_list.extend(coda_images['public'])
|
||||
|
||||
if project_id in coda_images:
|
||||
image_list.extend(coda_images[project_id])
|
||||
|
||||
coda.fill_image_info(instances_dict, image_list)
|
||||
else:
|
||||
coda.fill_image_info(instances_dict, None)
|
||||
|
||||
return HttpResponse(json.dumps(instances_dict))
|
||||
|
||||
|
||||
def floating_ips(request):
|
||||
"""The floating ips view."""
|
||||
project_id = request.POST['project_id']
|
||||
region = request.POST['region']
|
||||
update_cache = request.POST['update_cache']
|
||||
floating_ips_dict = get_project_resource(
|
||||
region,
|
||||
project_id,
|
||||
'floating_ips',
|
||||
update_cache)
|
||||
|
||||
return HttpResponse(json.dumps(floating_ips_dict))
|
||||
|
||||
|
||||
def security_groups(request):
|
||||
"""The security groups view."""
|
||||
project_id = request.POST['project_id']
|
||||
region = request.POST['region']
|
||||
update_cache = request.POST['update_cache']
|
||||
|
||||
security_groups_dict = get_project_resource(
|
||||
region,
|
||||
project_id,
|
||||
'security_groups',
|
||||
update_cache)
|
||||
|
||||
return HttpResponse(json.dumps(security_groups_dict))
|
||||
|
||||
|
||||
def networks(request):
|
||||
"""The networks view."""
|
||||
project_id = request.POST['project_id']
|
||||
region = request.POST['region']
|
||||
update_cache = request.POST['update_cache']
|
||||
networks_dict = get_project_resource(
|
||||
region,
|
||||
project_id,
|
||||
'networks',
|
||||
update_cache)
|
||||
|
||||
return HttpResponse(json.dumps(networks_dict))
|
||||
|
||||
|
||||
def subnets(request):
|
||||
"""The subnets view."""
|
||||
project_id = request.POST['project_id']
|
||||
region = request.POST['region']
|
||||
update_cache = request.POST['update_cache']
|
||||
subnets_dict = get_project_resource(
|
||||
region,
|
||||
project_id,
|
||||
'subnets',
|
||||
update_cache)
|
||||
|
||||
return HttpResponse(json.dumps(subnets_dict))
|
||||
|
||||
|
||||
def routers(request):
|
||||
"""The routers view."""
|
||||
project_id = request.POST['project_id']
|
||||
region = request.POST['region']
|
||||
update_cache = request.POST['update_cache']
|
||||
routers_dict = get_project_resource(
|
||||
region,
|
||||
project_id,
|
||||
'routers',
|
||||
update_cache)
|
||||
|
||||
return HttpResponse(json.dumps(routers_dict))
|
||||
|
||||
|
||||
def volumes(request):
|
||||
"""The volumes view."""
|
||||
project_id = request.POST['project_id']
|
||||
region = request.POST['region']
|
||||
update_cache = request.POST['update_cache']
|
||||
volumes_dict = get_project_resource(
|
||||
region,
|
||||
project_id,
|
||||
'volumes',
|
||||
update_cache)
|
||||
snapshots_dict = get_project_resource(
|
||||
region,
|
||||
project_id,
|
||||
'snapshots',
|
||||
update_cache)
|
||||
backups_dict = get_project_resource(
|
||||
region,
|
||||
project_id,
|
||||
'backups',
|
||||
update_cache)
|
||||
|
||||
volumes_dict = coda.fill_volume_info(
|
||||
volumes_dict,
|
||||
snapshots_dict,
|
||||
backups_dict)
|
||||
|
||||
return HttpResponse(json.dumps(volumes_dict))
|
||||
|
||||
|
||||
def images(request):
|
||||
"""The images view."""
|
||||
project_id = request.POST['project_id']
|
||||
region = request.POST['region']
|
||||
update_cache = request.POST['update_cache']
|
||||
|
||||
images_dict = None
|
||||
images_key = region + '_' + project_id + '_images'
|
||||
project_images = cache.get(images_key)
|
||||
|
||||
if update_cache == 'True':
|
||||
images_dict = get_all_images(region, True)
|
||||
elif project_images is None:
|
||||
images_dict = get_all_images(region, False)
|
||||
|
||||
if images_dict is not None:
|
||||
if project_id in images_dict:
|
||||
project_images = images_dict[project_id]
|
||||
else:
|
||||
project_images = {}
|
||||
cache.set(images_key, project_images, 600)
|
||||
|
||||
return HttpResponse(json.dumps(project_images))
|
||||
|
||||
|
||||
def get_all_images(region, reload_cache=False):
|
||||
"""Utility method, might belong elsewhere."""
|
||||
images_key = region + '_coda_images'
|
||||
coda_images = cache.get(images_key)
|
||||
|
||||
if reload_cache is True or coda_images is None or len(coda_images) == 0:
|
||||
auth_token = coda.get_auth_token()
|
||||
images_dict = glance.list_all_images(auth_token, region)
|
||||
coda_images = images_dict
|
||||
cache.set(images_key, coda_images, 3600)
|
||||
|
||||
return coda_images
|
||||
|
||||
|
||||
def confirm_delete(request):
|
||||
"""The confirm delete view."""
|
||||
project_id = request.POST['project_id']
|
||||
auth_token = coda.get_auth_token()
|
||||
|
||||
project_exists, project_info = keystone.project_exists(
|
||||
auth_token,
|
||||
project_id)
|
||||
users = keystone.get_project_users(auth_token, project_id)
|
||||
regions = coda.get_coda_regions()
|
||||
|
||||
context = {
|
||||
'project_id': project_id,
|
||||
'project_info': project_info,
|
||||
'users': users,
|
||||
'regions': regions,
|
||||
}
|
||||
|
||||
return render(request, 'coda/coda/confirm_delete.html', context)
|
||||
|
||||
|
||||
def delete_resources(request):
|
||||
"""The deleting resources view."""
|
||||
project_id = request.POST['project_id']
|
||||
os_tenant_id = request.POST['os_tenant_id']
|
||||
os_username = request.POST['os_username']
|
||||
os_password = request.POST['os_password']
|
||||
|
||||
user_token = keystone.user_authenticate(
|
||||
os_tenant_id,
|
||||
os_username,
|
||||
os_password)
|
||||
project_exists, project_info = keystone.project_exists(
|
||||
user_token,
|
||||
project_id)
|
||||
users = keystone.get_project_users(user_token, project_id)
|
||||
regions = coda.get_coda_regions()
|
||||
|
||||
context = {
|
||||
'project_id': project_id,
|
||||
'project_info': project_info,
|
||||
'users': users,
|
||||
'regions': regions,
|
||||
'user_token': user_token
|
||||
}
|
||||
|
||||
return render(request, 'coda/coda/delete/results.html', context)
|
||||
|
||||
|
||||
def delete_instances(request):
|
||||
"""The deleting instances view."""
|
||||
result = {}
|
||||
project_id = request.POST['project_id']
|
||||
user_token = request.POST['user_token']
|
||||
region = request.POST['region']
|
||||
|
||||
instance_dict = remove_project_resource(region, project_id, 'instances')
|
||||
|
||||
if instance_dict is not None:
|
||||
for user_id, instance_list in instance_dict.iteritems():
|
||||
for instance in instance_list:
|
||||
result[instance['id']] = nova.delete_instance(
|
||||
user_token,
|
||||
region,
|
||||
project_id,
|
||||
instance['id'])
|
||||
else:
|
||||
result = 'ERROR'
|
||||
|
||||
return HttpResponse(json.dumps(result))
|
||||
|
||||
|
||||
def delete_floating_ips(request):
|
||||
"""The deleting floating ips view."""
|
||||
result = {}
|
||||
project_id = request.POST['project_id']
|
||||
user_token = request.POST['user_token']
|
||||
region = request.POST['region']
|
||||
|
||||
floating_ips_dict = remove_project_resource(
|
||||
region,
|
||||
project_id,
|
||||
'floating_ips')
|
||||
|
||||
if floating_ips_dict is not None:
|
||||
for floating_ip in floating_ips_dict:
|
||||
result[floating_ip['id']] = neutron.delete_floating_ip(
|
||||
user_token,
|
||||
region,
|
||||
project_id,
|
||||
floating_ip['id'])
|
||||
else:
|
||||
result = 'ERROR'
|
||||
|
||||
return HttpResponse(json.dumps(result))
|
||||
|
||||
|
||||
def delete_security_groups(request):
|
||||
"""The deleting security groups view."""
|
||||
result = {}
|
||||
project_id = request.POST['project_id']
|
||||
user_token = request.POST['user_token']
|
||||
region = request.POST['region']
|
||||
|
||||
security_groups_dict = remove_project_resource(
|
||||
region,
|
||||
project_id,
|
||||
'security_groups')
|
||||
|
||||
if security_groups_dict is not None:
|
||||
for sec_group in security_groups_dict:
|
||||
result[sec_group['id']] = neutron.delete_security_group(
|
||||
user_token,
|
||||
region,
|
||||
project_id,
|
||||
sec_group['id'])
|
||||
else:
|
||||
result = 'ERROR'
|
||||
|
||||
return HttpResponse(json.dumps(result))
|
||||
|
||||
|
||||
def delete_networks(request):
|
||||
"""The deleting networks view."""
|
||||
result = {}
|
||||
project_id = request.POST['project_id']
|
||||
user_token = request.POST['user_token']
|
||||
region = request.POST['region']
|
||||
|
||||
networks_dict = remove_project_resource(region, project_id, 'networks')
|
||||
remove_project_resource(region, project_id, 'subnets')
|
||||
|
||||
if networks_dict is not None:
|
||||
for network in networks_dict:
|
||||
result[network['id']] = neutron.delete_network(
|
||||
user_token,
|
||||
region,
|
||||
project_id,
|
||||
network['id'])
|
||||
else:
|
||||
result = 'ERROR'
|
||||
|
||||
return HttpResponse(json.dumps(result))
|
||||
|
||||
|
||||
def delete_routers(request):
|
||||
"""The deleting routers view."""
|
||||
result = {}
|
||||
project_id = request.POST['project_id']
|
||||
user_token = request.POST['user_token']
|
||||
region = request.POST['region']
|
||||
|
||||
routers_dict = remove_project_resource(region, project_id, 'routers')
|
||||
|
||||
if routers_dict is not None:
|
||||
for router in routers_dict:
|
||||
result[router['id']] = neutron.delete_router(
|
||||
user_token,
|
||||
region,
|
||||
project_id,
|
||||
router['id'])
|
||||
else:
|
||||
result = 'ERROR'
|
||||
|
||||
return HttpResponse(json.dumps(result))
|
||||
|
||||
|
||||
def delete_volumes(request):
|
||||
"""The deleting volumes view."""
|
||||
result = {}
|
||||
project_id = request.POST['project_id']
|
||||
user_token = request.POST['user_token']
|
||||
region = request.POST['region']
|
||||
|
||||
volumes_dict = remove_project_resource(region, project_id, 'volumes')
|
||||
|
||||
if volumes_dict is not None:
|
||||
for volume in volumes_dict:
|
||||
result[volume['id']] = cinder.delete_volume(
|
||||
user_token,
|
||||
region,
|
||||
project_id,
|
||||
volume['id'])
|
||||
else:
|
||||
result = 'ERROR'
|
||||
|
||||
return HttpResponse(json.dumps(result))
|
||||
|
||||
|
||||
def delete_snapshots(request):
|
||||
"""The deleting snapshots view."""
|
||||
result = {}
|
||||
project_id = request.POST['project_id']
|
||||
user_token = request.POST['user_token']
|
||||
region = request.POST['region']
|
||||
|
||||
snapshots_dict = remove_project_resource(region, project_id, 'snapshots')
|
||||
|
||||
if snapshots_dict is not None:
|
||||
for snapshot in snapshots_dict:
|
||||
result[snapshot['id']] = cinder.delete_snapshot(
|
||||
user_token,
|
||||
region,
|
||||
project_id,
|
||||
snapshot['id'])
|
||||
|
||||
return HttpResponse(json.dumps(result))
|
||||
|
||||
|
||||
def delete_backups(request):
|
||||
"""The deleting backups view."""
|
||||
result = {}
|
||||
project_id = request.POST['project_id']
|
||||
user_token = request.POST['user_token']
|
||||
region = request.POST['region']
|
||||
|
||||
backups_dict = remove_project_resource(region, project_id, 'backups')
|
||||
|
||||
if backups_dict is not None:
|
||||
for backup in backups_dict:
|
||||
result[backup['id']] = cinder.delete_backup(
|
||||
user_token,
|
||||
region,
|
||||
project_id,
|
||||
backup['id'])
|
||||
|
||||
return HttpResponse(json.dumps(result))
|
||||
|
||||
|
||||
def delete_images(request):
|
||||
"""The deleting images view."""
|
||||
result = {}
|
||||
project_id = request.POST['project_id']
|
||||
user_token = request.POST['user_token']
|
||||
region = request.POST['region']
|
||||
|
||||
images_key = region + '_' + project_id + '_images'
|
||||
tenant_images = cache.get(images_key)
|
||||
error_images = []
|
||||
|
||||
if tenant_images is not None:
|
||||
# todo (nathan) improve this
|
||||
# remove the tenant image cached
|
||||
# cache.delete(images_key)
|
||||
# scrubber_images = get_all_images(region)
|
||||
# scrubber_images.pop(tenant_id, None)
|
||||
# cache.set('scrubber_images', scrubber_images, 3600)
|
||||
|
||||
for image in tenant_images:
|
||||
result[image['id']] = glance.delete_image(
|
||||
user_token,
|
||||
region,
|
||||
image['id'])
|
||||
|
||||
if result[image['id']] != 'Image Deleted':
|
||||
error_images.append(image)
|
||||
else:
|
||||
# todo (nathan) log that there were no images to delete
|
||||
result = {}
|
||||
|
||||
# related to above, this is hackish, but it works for now
|
||||
if len(error_images) > 0:
|
||||
cache.set(images_key, error_images, 600)
|
||||
else:
|
||||
cache.set(images_key, {}, 600)
|
||||
|
||||
return HttpResponse(json.dumps(result))
|
||||
|
||||
|
||||
def get_project_resource(region, project_id, resource, update_cache='True'):
|
||||
"""Utility method to get resource map from cache."""
|
||||
resource_map = 'ERROR'
|
||||
resource_key = region + '_' + project_id + '_' + resource
|
||||
|
||||
if resource in DISPATCH_MAP:
|
||||
if update_cache == 'True':
|
||||
coda_token = coda.get_auth_token()
|
||||
resource_map = DISPATCH_MAP[resource](
|
||||
coda_token,
|
||||
region,
|
||||
project_id)
|
||||
else:
|
||||
resource_map = cache.get(resource_key)
|
||||
|
||||
if resource_map is None:
|
||||
coda_token = coda.get_auth_token()
|
||||
resource_map = DISPATCH_MAP[resource](
|
||||
coda_token,
|
||||
region,
|
||||
project_id)
|
||||
|
||||
cache.set(resource_key, resource_map, 600)
|
||||
|
||||
return resource_map
|
||||
|
||||
|
||||
def remove_project_resource(region, tenant_id, resource):
|
||||
"""Utility method to remove resource map from cache."""
|
||||
resource_key = region + '_' + tenant_id + '_' + resource
|
||||
resource_map = cache.get(resource_key)
|
||||
|
||||
if resource_map is not None:
|
||||
cache.delete(resource_key)
|
||||
|
||||
return resource_map
|
@ -1,290 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# TODO add how to use this
|
||||
|
||||
source set_coda_env.sh
|
||||
|
||||
function hasNetwork {
|
||||
networks=`neutron net-list | awk '{if ($2 != "id" && $2 != "|" && NF>1) print $2 " " $4}' | grep -v "ext-net"`
|
||||
|
||||
if [ ${#networks} -eq 0 ]
|
||||
then
|
||||
CODA_NETWORK_ID=""
|
||||
return -1
|
||||
else
|
||||
parts=($networks)
|
||||
CODA_NETWORK_ID=${parts[0]}
|
||||
fi
|
||||
}
|
||||
|
||||
function hasSecGroups {
|
||||
expectedCount=$1
|
||||
groups=`neutron security-group-list | awk '{if ($2 != "id" && NF>1) print $4}' | grep -v default`
|
||||
|
||||
if [ ${#groups} -eq 0 ]
|
||||
then
|
||||
echo "No Security Groups"
|
||||
return -1
|
||||
else
|
||||
parts=($groups)
|
||||
if [ ${#parts[@]} -ne $expectedCount ]
|
||||
then
|
||||
echo "WARNING: Unexpected Number of Security Groups."
|
||||
return -1
|
||||
fi
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
function createSecurityGroup {
|
||||
groupName=$1
|
||||
description=$2
|
||||
exists=`neutron security-group-show $groupName`
|
||||
|
||||
if [[ ${exists:0:1} == "+" ]]
|
||||
then
|
||||
echo "Group $groupName already exists."
|
||||
return -1
|
||||
else
|
||||
neutron security-group-create $groupName --description "$description"
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
function createFloatingIPs {
|
||||
count=$1
|
||||
floatingIPs=`neutron floatingip-list | awk '{if ($2 != "id" && NF>1) print $2}'`
|
||||
|
||||
if [ ${#floatingIPs} -eq 0 ]
|
||||
then
|
||||
echo "Creating $count floating IP's."
|
||||
for x in $(seq 1 $count)
|
||||
do
|
||||
neutron floatingip-create Ext-Net
|
||||
done
|
||||
else
|
||||
parts=($floatingIPs)
|
||||
if [ ${#parts[@]} -gt $count ]
|
||||
then
|
||||
echo "WARNING: Too many floating IP's."
|
||||
elif [ ${#parts[@]} -lt $count ]
|
||||
then
|
||||
diff=`expr $count - ${#parts[@]}`
|
||||
echo "Not enough floating IP's, creating $diff more."
|
||||
for x in $(seq 1 $diff)
|
||||
do
|
||||
neutron floatingip-create Ext-Net
|
||||
done
|
||||
else
|
||||
echo "Floating IP's already created."
|
||||
fi
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
function assignAllFloatingIPs {
|
||||
for x in `nova list | awk '{if ($2 != "ID" && NF>1 && $13 == "|") print $2}'`;
|
||||
do port=`neutron port-list -- --device_id $x | awk '{if ($2 != "id" && NF>1) print $2}'`;
|
||||
fip=`neutron floatingip-list | grep '| *|' | head -1 | awk '{print $2}'`;
|
||||
neutron floatingip-associate $fip $port;
|
||||
done;
|
||||
}
|
||||
|
||||
function hasInstances {
|
||||
expectedCount=$1
|
||||
instances=`nova list | awk '{if ($2 != "ID" && NF>1) print $4}'`
|
||||
|
||||
if [ ${#instances} -eq 0 ]
|
||||
then
|
||||
echo "No Instances"
|
||||
return -1
|
||||
else
|
||||
parts=($instances)
|
||||
if [ ${#parts[@]} -ne $expectedCount ]
|
||||
then
|
||||
echo "WARNING: Unexpected Number of instances."
|
||||
fi
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
function createVolumes {
|
||||
count=$1
|
||||
name=$2
|
||||
volumes=`cinder list | awk '{if ($2 != "ID" && NF>1) print $2}'`
|
||||
|
||||
if [ ${#volumes} -eq 0 ]
|
||||
then
|
||||
echo "Creating $count Volumes."
|
||||
for x in $(seq 1 $count)
|
||||
do
|
||||
cinder create --display-name "$name-0$x" --display-description "Testing a volume $x" 5
|
||||
done
|
||||
else
|
||||
parts=($volumes)
|
||||
if [ ${#parts[@]} -gt $count ]
|
||||
then
|
||||
echo "WARNING: Too many Volumes."
|
||||
elif [ ${#parts[@]} -lt $count ]
|
||||
then
|
||||
diff=`expr $count - ${#parts[@]}`
|
||||
echo "Not enough Volumes, creating $diff more."
|
||||
for x in $(seq 1 $diff)
|
||||
do
|
||||
cinder create --display-name "$name-0$x" --display-description "Testing a volume $x" 5
|
||||
done
|
||||
else
|
||||
echo "Volumes already created."
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
function createSnapshots {
|
||||
volumes=`cinder list | awk '{if ($2 != "ID" && NF>1) print $2}'`
|
||||
snapshots=`cinder snapshot-list | awk '{if ($2 != "ID" && NF>1) print $4}'`
|
||||
|
||||
for vol in $volumes
|
||||
do
|
||||
exists=`echo $snapshots | grep $vol`
|
||||
echo $exists
|
||||
if [ ${#exists} -eq 0 ]
|
||||
then
|
||||
echo "Creating Snapshot of $vol."
|
||||
cinder snapshot-create --display-name "snapshot_$vol" --display-description 'Testing a snapshot' $vol
|
||||
else
|
||||
echo "Snapshot for Volume: $vol already exists."
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
function createBackups {
|
||||
volumes=`cinder list | awk '{if ($2 != "ID" && NF>1) print $2}'`
|
||||
backups=`cinder backup-list | awk '{if ($2 != "ID" && NF>1) print $4}'`
|
||||
|
||||
for vol in $volumes
|
||||
do
|
||||
exists=`echo $backups | grep $vol`
|
||||
echo $exists
|
||||
if [ ${#exists} -eq 0 ]
|
||||
then
|
||||
echo "Creating Backup of $vol."
|
||||
cinder backup-create --display-name "backup_$vol" --display-description 'Testing a backup.' $vol
|
||||
else
|
||||
echo "Backup for Volume: $vol already exists."
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
function createImages {
|
||||
instances=`nova list | awk '{if ($2 != "ID" && NF>1) print $4}'`
|
||||
images=`glance -k image-list --property-filter owner_id=$OS_TENANT_ID | awk '{if ($2 != "ID" && NF>1) print $4}'`
|
||||
|
||||
for i in $instances
|
||||
do
|
||||
exists=`echo $images | grep "$i-image"`
|
||||
echo $exists
|
||||
if [ ${#exists} -eq 0 ]
|
||||
then
|
||||
echo "Creating Image of $i."
|
||||
nova image-create $i "$i-image"
|
||||
else
|
||||
echo "Image of Instance: $i already exists."
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
#==============================================================================================================================================================
|
||||
|
||||
# Create Resources for Project 1
|
||||
echo "Creating Resources for Project 1"
|
||||
export OS_USERNAME=$CODA_USER_1
|
||||
export OS_TENANT_NAME=$CODA_PROJECT_NAME_1
|
||||
export OS_TENANT_ID=$CODA_PROJECT_ID_1
|
||||
|
||||
# Network for Project 1
|
||||
hasNetwork
|
||||
|
||||
if [ ${#CODA_NETWORK_ID} -eq 0 ]
|
||||
then
|
||||
echo "creating coda-network"
|
||||
neutron net-create coda-network
|
||||
neutron subnet-create coda-network 10.0.0.0/24 --name coda-subnet
|
||||
neutron net-create coda2-net
|
||||
neutron subnet-create coda2-net 10.10.0.0/16 --name coda2-subnet
|
||||
neutron router-create coda-router
|
||||
neutron router-interface-add coda-router coda-subnet
|
||||
neutron router-interface-add coda-router coda2-subnet
|
||||
neutron router-gateway-set coda-router Ext-Net
|
||||
hasNetwork #Make sure we get the variable set when done.
|
||||
else
|
||||
echo "coda-network already created."
|
||||
fi
|
||||
|
||||
# Security Groups for Project 1
|
||||
echo "Creating Security Groups."
|
||||
if createSecurityGroup basenode 'The base security group for all nodes.'
|
||||
then
|
||||
neutron security-group-rule-create --direction ingress --protocol tcp --port_range_min 22 --port_range_max 22 --remote-ip-prefix 10.0.0.0/8 basenode
|
||||
neutron security-group-rule-create --direction ingress --protocol tcp --port_range_min 9182 --port_range_max 9182 --remote-ip-prefix 10.0.0.0/8 basenode
|
||||
fi
|
||||
|
||||
if createSecurityGroup chef-server 'Opens Chef ports'
|
||||
then
|
||||
neutron security-group-rule-create --direction ingress --protocol tcp --port_range_min 4000 --port_range_max 4000 --remote-ip-prefix 10.0.0.0/8 chef-server
|
||||
fi
|
||||
|
||||
if createSecurityGroup web-server 'Good for a web server'
|
||||
then
|
||||
neutron security-group-rule-create --direction ingress --protocol tcp --port_range_min 80 --port_range_max 80 --remote-ip-prefix 10.0.0.0/8 web-server
|
||||
neutron security-group-rule-create --direction ingress --protocol tcp --port_range_min 81 --port_range_max 81 --remote-ip-prefix 10.0.0.0/8 web-server
|
||||
neutron security-group-rule-create --direction ingress --protocol tcp --port_range_min 443 --port_range_max 443 --remote-ip-prefix 10.0.0.0/8 web-server
|
||||
neutron security-group-rule-create --direction ingress --protocol tcp --port_range_min 8080 --port_range_max 8080 --remote-ip-prefix 10.0.0.0/8 web-server
|
||||
neutron security-group-rule-create --direction ingress --protocol tcp --port_range_min 8081 --port_range_max 8081 --remote-ip-prefix 10.0.0.0/8 web-server
|
||||
fi
|
||||
|
||||
if createSecurityGroup email 'email ports'
|
||||
then
|
||||
neutron security-group-rule-create --direction ingress --protocol tcp --port_range_min 25 --port_range_max 25 --remote-ip-prefix 10.0.0.0/8 email
|
||||
neutron security-group-rule-create --direction ingress --protocol tcp --port_range_min 110 --port_range_max 110 --remote-ip-prefix 10.0.0.0/8 email
|
||||
neutron security-group-rule-create --direction ingress --protocol tcp --port_range_min 143 --port_range_max 143 --remote-ip-prefix 10.0.0.0/8 email
|
||||
neutron security-group-rule-create --direction ingress --protocol tcp --port_range_min 465 --port_range_max 465 --remote-ip-prefix 10.0.0.0/8 email
|
||||
neutron security-group-rule-create --direction ingress --protocol tcp --port_range_min 993 --port_range_max 993 --remote-ip-prefix 10.0.0.0/8 email
|
||||
neutron security-group-rule-create --direction ingress --protocol tcp --port_range_min 995 --port_range_max 995 --remote-ip-prefix 10.0.0.0/8 email
|
||||
neutron security-group-rule-create --direction ingress --protocol tcp --port_range_min 2525 --port_range_max 2525 --remote-ip-prefix 10.0.0.0/8 email
|
||||
fi
|
||||
|
||||
# Instances for Project 1
|
||||
if hasInstances 4
|
||||
then
|
||||
echo "Instances already created."
|
||||
else
|
||||
echo "Creating instances."
|
||||
# Two for user trumpetsherald
|
||||
nova boot --flavor $CODA_FLAVOR --image $CODA_IMAGE_1 --key_name $CODA_KEY --availability-zone $CODA_AZ1 --security-groups basenode,web-server --nic net-id=$CODA_NETWORK_ID blogs;
|
||||
nova boot --flavor $CODA_FLAVOR --image $CODA_IMAGE_2 --key_name $CODA_KEY --availability-zone $CODA_AZ2 --security-groups basenode,chef-server --nic net-id=$CODA_NETWORK_ID chef-server;
|
||||
|
||||
# Two for user nkimball
|
||||
export OS_USERNAME=$CODA_USER_2
|
||||
nova boot --flavor $CODA_FLAVOR --image $CODA_IMAGE_3 --key_name $CODA_KEY --availability-zone $CODA_AZ1 --security-groups basenode,email --nic net-id=$CODA_NETWORK_ID email;
|
||||
nova boot --flavor $CODA_FLAVOR --image $CODA_IMAGE_4 --key_name $CODA_KEY --availability-zone $CODA_AZ2 --security-groups basenode,web-server --nic net-id=$CODA_NETWORK_ID web-server;
|
||||
fi
|
||||
|
||||
# Floating IP's for Project 1
|
||||
createFloatingIPs 4
|
||||
|
||||
sleep 10
|
||||
|
||||
# Assign All the Floating IP's
|
||||
assignAllFloatingIPs
|
||||
|
||||
# Create Volumes for Project 1
|
||||
createVolumes 2 'test'
|
||||
echo "I'm sleeping for 30 seconds to allow the instances to build before creating images of them."
|
||||
sleep 30
|
||||
#createSnapshots
|
||||
#createBackups
|
||||
createImages
|
||||
#==============================================================================================================================================================
|
45
dashboard.py
45
dashboard.py
@ -1,45 +0,0 @@
|
||||
# Copyright [2015] Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""The coda dashboard module.
|
||||
|
||||
Coda is a Horizon dashboard and panel (both share the name) that
|
||||
facilitates resource clean up of a project once that project is no longer
|
||||
needed http://openstack.org
|
||||
"""
|
||||
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
import horizon
|
||||
|
||||
|
||||
class Codagroup(horizon.PanelGroup):
|
||||
"""Defines the coda group, currently not used."""
|
||||
|
||||
slug = "codagroup"
|
||||
name = _("Coda Group")
|
||||
panels = ('coda',)
|
||||
|
||||
|
||||
class Coda(horizon.Dashboard):
|
||||
"""The coda panel."""
|
||||
|
||||
name = _("Coda")
|
||||
slug = "coda"
|
||||
panels = ('coda',)
|
||||
default_panel = 'coda'
|
||||
|
||||
|
||||
horizon.register(Coda)
|
19
models.py
19
models.py
@ -1,19 +0,0 @@
|
||||
# Copyright [2015] Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""
|
||||
This is a stub file.
|
||||
|
||||
Stub file to work around django bug: https://code.djangoproject.com/ticket/7198
|
||||
"""
|
@ -1,29 +0,0 @@
|
||||
#!/bin/bash
|
||||
export CODA_USER_1=coda_user
|
||||
export CODA_USER_2=coda_user2
|
||||
|
||||
export OS_PASSWORD=hpinvent
|
||||
|
||||
export CODA_PROJECT_NAME_1="coda_project"
|
||||
export CODA_PROJECT_ID_1=8a8b30b83aab4b0d9044b883ab95cd46
|
||||
|
||||
#export CODA_TENANT_NAME_2="Kimballs-Project"
|
||||
#export CODA_TENANT_ID_2=10100821657591
|
||||
|
||||
export OS_AUTH_URL=http://10.23.201.133:5000/v2.0/
|
||||
#export OS_REGION_NAME=region-a.geo-1
|
||||
|
||||
export NOVACLIENT_INSECURE=True
|
||||
export NEUTRONCLIENT_INSECURE=True
|
||||
export CINDERCLIENT_INSECURE=True
|
||||
|
||||
export CODA_KEY=hpcloud
|
||||
|
||||
export CODA_IMAGE_1=983ceae5-046e-46b1-a6ca-22fce45c3d15
|
||||
export CODA_IMAGE_2=983ceae5-046e-46b1-a6ca-22fce45c3d15
|
||||
export CODA_IMAGE_3=983ceae5-046e-46b1-a6ca-22fce45c3d15
|
||||
export CODA_IMAGE_4=983ceae5-046e-46b1-a6ca-22fce45c3d15
|
||||
|
||||
export CODA_FLAVOR=2
|
||||
export CODA_AZ1=nova
|
||||
export CODA_AZ2=nova
|
@ -1,27 +0,0 @@
|
||||
#!/bin/bash
|
||||
export CODA_USER_1=coda_user
|
||||
export CODA_USER_2=coda_user2
|
||||
|
||||
export OS_PASSWORD=coda_p@ssw0rd
|
||||
|
||||
export CODA_PROJECT_NAME_1="coda_project"
|
||||
export CODA_PROJECT_ID_1=project_guid
|
||||
|
||||
|
||||
export OS_AUTH_URL=http://127.0.0.1:5000/v2.0/
|
||||
#export OS_REGION_NAME=region-a.geo-1
|
||||
|
||||
export NOVACLIENT_INSECURE=True
|
||||
export NEUTRONCLIENT_INSECURE=True
|
||||
export CINDERCLIENT_INSECURE=True
|
||||
|
||||
export CODA_KEY=hpcloud
|
||||
|
||||
export CODA_IMAGE_1=imgae_guid
|
||||
export CODA_IMAGE_2=imgae_guid
|
||||
export CODA_IMAGE_3=imgae_guid
|
||||
export CODA_IMAGE_4=imgae_guid
|
||||
|
||||
export CODA_FLAVOR=2
|
||||
export CODA_AZ1=nova
|
||||
export CODA_AZ2=nova
|
@ -1 +0,0 @@
|
||||
/* Additional JavaScript for coda. */
|
@ -1,137 +0,0 @@
|
||||
/*!
|
||||
* JavaScript Cookie v2.0.0-pre
|
||||
* https://github.com/js-cookie/js-cookie
|
||||
*
|
||||
* Copyright 2006, 2015 Klaus Hartl
|
||||
* Released under the MIT license
|
||||
*/
|
||||
(function (factory) {
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define(factory);
|
||||
} else if (typeof exports === 'object') {
|
||||
module.exports = factory();
|
||||
} else {
|
||||
var _OldCookies = window.Cookies;
|
||||
var api = window.Cookies = factory(window.jQuery);
|
||||
api.noConflict = function () {
|
||||
window.Cookies = _OldCookies;
|
||||
return api;
|
||||
};
|
||||
}
|
||||
}(function () {
|
||||
function extend () {
|
||||
var i = 0;
|
||||
var result = {};
|
||||
for (; i < arguments.length; i++) {
|
||||
var attributes = arguments[ i ];
|
||||
for (var key in attributes) {
|
||||
result[key] = attributes[key];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function init (converter) {
|
||||
function api (key, value, attributes) {
|
||||
var result;
|
||||
|
||||
// Write
|
||||
|
||||
if (arguments.length > 1) {
|
||||
attributes = extend({
|
||||
path: '/'
|
||||
}, api.defaults, attributes);
|
||||
|
||||
if (typeof attributes.expires === 'number') {
|
||||
var expires = new Date();
|
||||
expires.setMilliseconds(expires.getMilliseconds() + attributes.expires * 864e+5);
|
||||
attributes.expires = expires;
|
||||
}
|
||||
|
||||
try {
|
||||
result = JSON.stringify(value);
|
||||
if (/^[\{\[]/.test(result)) {
|
||||
value = result;
|
||||
}
|
||||
} catch (e) {}
|
||||
|
||||
value = encodeURIComponent(String(value));
|
||||
value = value.replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent);
|
||||
|
||||
key = encodeURIComponent(String(key));
|
||||
key = key.replace(/%(23|24|26|2B|5E|60|7C)/g, decodeURIComponent);
|
||||
key = key.replace(/[\(\)]/g, escape);
|
||||
|
||||
return (document.cookie = [
|
||||
key, '=', value,
|
||||
attributes.expires && '; expires=' + attributes.expires.toUTCString(), // use expires attribute, max-age is not supported by IE
|
||||
attributes.path && '; path=' + attributes.path,
|
||||
attributes.domain && '; domain=' + attributes.domain,
|
||||
attributes.secure && '; secure'
|
||||
].join(''));
|
||||
}
|
||||
|
||||
// Read
|
||||
|
||||
if (!key) {
|
||||
result = {};
|
||||
}
|
||||
|
||||
// To prevent the for loop in the first place assign an empty array
|
||||
// in case there are no cookies at all. Also prevents odd result when
|
||||
// calling "get()"
|
||||
var cookies = document.cookie ? document.cookie.split('; ') : [];
|
||||
var rdecode = /(%[0-9A-Z]{2})+/g;
|
||||
var i = 0;
|
||||
|
||||
for (; i < cookies.length; i++) {
|
||||
var parts = cookies[i].split('=');
|
||||
var name = parts[0].replace(rdecode, decodeURIComponent);
|
||||
var cookie = parts.slice(1).join('=');
|
||||
|
||||
if (cookie.charAt(0) === '"') {
|
||||
cookie = cookie.slice(1, -1);
|
||||
}
|
||||
|
||||
cookie = converter && converter(cookie, name) || cookie.replace(rdecode, decodeURIComponent);
|
||||
|
||||
if (this.json) {
|
||||
try {
|
||||
cookie = JSON.parse(cookie);
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
if (key === name) {
|
||||
result = cookie;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!key) {
|
||||
result[name] = cookie;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
api.get = api.set = api;
|
||||
api.getJSON = function () {
|
||||
return api.apply({
|
||||
json: true
|
||||
}, [].slice.call(arguments));
|
||||
};
|
||||
api.defaults = {};
|
||||
|
||||
api.remove = function (key, attributes) {
|
||||
api(key, '', extend(attributes, {
|
||||
expires: -1
|
||||
}));
|
||||
};
|
||||
|
||||
api.withConverter = init;
|
||||
|
||||
return api;
|
||||
}
|
||||
|
||||
return init();
|
||||
}));
|
@ -1 +0,0 @@
|
||||
/* Additional SCSS for {{ dash_name }}. */
|
@ -1,11 +0,0 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block sidebar %}
|
||||
{% include 'horizon/common/_sidebar.html' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{% include "horizon/_messages.html" %}
|
||||
{% block coda_main %}{% endblock %}
|
||||
{% endblock %}
|
||||
|
@ -1,5 +0,0 @@
|
||||
"""Utilities for use in templates.
|
||||
|
||||
The jsfunc method replaces - with _ to allow for proper java script
|
||||
function names.
|
||||
"""
|
@ -1,38 +0,0 @@
|
||||
# Copyright [2015] Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
"""Utilities for use in templates.
|
||||
|
||||
The jsfunc method replaces - with _ to allow for proper java script
|
||||
function names.
|
||||
"""
|
||||
|
||||
from django import template
|
||||
from django.template.defaultfilters import stringfilter
|
||||
|
||||
register = template.Library()
|
||||
|
||||
|
||||
@register.filter
|
||||
def get(mapping, key):
|
||||
"""Safe way to get a value from a dict."""
|
||||
return mapping.get(key, '')
|
||||
|
||||
|
||||
@register.filter
|
||||
@stringfilter
|
||||
def jsfunc(value):
|
||||
"""Create a safe javascript function name."""
|
||||
return value.replace('-', '_')
|
Loading…
Reference in New Issue
Block a user