Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Openstack Snapshot changes #36

Open
wants to merge 14 commits into
base: openstack
Choose a base branch
from
Open
30 changes: 27 additions & 3 deletions ajax/templates/ajax/openstackDeploymentStatus.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,19 @@
{% else %}
is_deployed = true;
{% endif %}

function showSnapSetEditor() {
manuallyTogglePanel('createSnapDet', '');
}

</script>
<table>
<tr>
<th colspan="3"> Stack Status</th>
</tr>
{% if stack == None %}
<tr>
<td>
<td colspan="3">
Not yet deployed to OpenStack!
</td>
</tr>
Expand All @@ -32,15 +37,15 @@
<td>
Status
</td>
<td>
<td colspan="2">
{{ stack.stack_status }}
</td>
</tr>
<tr>
<td>
Status Detail
</td>
<td>
<td colspan="2">
{{ stack.stack_status_reason }}
</td>
</tr>
Expand Down Expand Up @@ -104,5 +109,24 @@
onclick="javascript: refreshDeploymentStatus('{{ topology_id }}');"/>
</td>
</tr>


<tr>
<th colspan="3">
HEAT Snapshots
</th>
</tr>
<tr>
<td colspan ="3">
<a href="javascript:void(0)" onclick="javascript: showSnapSetEditor();">
Create Snapshots
</a>
&nbsp;
<a href="#" onclick="javascript: redir('/ajax/listSnapshot/{{ topology_id }}')">
List Snapshots
</a>
</td>
</tr>

{% endif %}
</table>
2 changes: 1 addition & 1 deletion ajax/templates/ajax/scriptOutput.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
</td>
<tr>
<td colspan="4" style="text-align: right">
<a href="/templates">Manage Scripts</a>
<a href="/scripts">Manage Scripts</a>
</td>
</tr>
</table>
Expand Down
2 changes: 1 addition & 1 deletion ajax/templates/ajax/scripts.html
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
{% endfor %}
<tr>
<td colspan="4" style="text-align: right">
<a href="/templates">Manage Scripts</a>
<a href="/scripts">Manage Scripts</a>
</td>
</tr>
</table>
Expand Down
61 changes: 61 additions & 0 deletions ajax/templates/ajax/snapshot_list.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
{% extends "base.html" %}
{% block title %}Wistar - Lab Rat - Snapshot List{% endblock %}
{% load staticfiles %}
{% block content %}
<div class="centered_box_75">

<h2>Stack Snapshot List</h2>
<ul class="messages">
{% for message in messages %}
<li {% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
{% endfor %}
</ul>
<table>
<tr>
<th>Name</th>
<th>Snapshot Id</th>
<th>Stack Name</th>
<th>Options</th>
</tr>
{% for snapshot in snapshot_list %}
<tr>
<td>
{{snapshot.name }}
</td>
<td>
{{ snapshot.id }}
</td>
<td>
{{ snapshot.stack_name }}
</td>
<td style="width: 100px;">
<div id="menu_{{ snapshot.id }}" style="position: absolute; margin-top: -6px;">
<img src="{% static 'images/more.png' %}" width="12px" height="12px"/>&nbsp;
<ul class="submenu">

<li>
<a href="#" onclick="javascript: redir('/ajax/rollbackSnapshot/{{ snapshot.id }}/{{snapshot.topology_id}}')">Rollback</a>
</li>
<li>
<a href="#" onclick="javascript: redir('/ajax/deleteSnapshot/{{ snapshot.id }}/{{snapshot.topology_id}}')">Delete</a>
</li>

</ul>
</div>
<script>
jQuery("#menu_{{ snapshot.id }}").hover(
function() {
$(this).children('.submenu').slideDown(150);
},
function() {
$(this).children('.submenu').slideUp(150);
}
);
</script>
</td>
</tr>
{% endfor %}
</table>

</div>
{% endblock %}
8 changes: 8 additions & 0 deletions ajax/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,15 @@
url(r'^deployTopology/$', views.deploy_topology, name='deployTopology'),
url(r'^redeployTopology/$', views.redeploy_topology, name='redeployTopology'),
url(r'^deployStack/(?P<topology_id>[^/]+)$', views.deploy_stack, name='deployStack'),
url(r'^updateStack/$', views.update_stack, name='updateStack'),
url(r'^deleteStack/(?P<topology_id>[^/]+)$', views.delete_stack, name='deleteStack'),

url(r'^listSnapshot/(?P<topology_id>[^/]+)$', views.list_snapshot, name='listSnapshot'),
url(r'^deleteSnapshot/(?P<snapshot_id>[^/]+)/(?P<topology_id>[^/]+)/$', views.delete_snapshot,
name='deleteSnapshot'),
url(r'^rollbackSnapshot/(?P<snapshot_id>[^/]+)/(?P<topology_id>[^/]+)/$', views.rollback_snapshot,
name='rollbackSnapshot'),

url(r'^startTopology/$', views.start_topology, name='startTopology'),
url(r'^pauseTopology/$', views.pause_topology, name='pauseTopology'),
url(r'^manageDomain/$', views.manage_domain, name='manageDomain'),
Expand Down
168 changes: 165 additions & 3 deletions ajax/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -874,6 +874,10 @@ def redeploy_topology(request):
except ObjectDoesNotExist:
return render(request, 'ajax/ajaxError.html', {'error': "Topology doesn't exist"})

if configuration.deployment_backend == "openstack":
logger.info('Redirecting to update stack')
return update_stack(request)

try:
domains = libvirtUtils.get_domains_for_topology(topology_id)
config = wistarUtils.load_config_from_topology_json(topo.json, topology_id)
Expand Down Expand Up @@ -1183,7 +1187,6 @@ def get_topology_config(request):
This is useful to get a list of all objects on the topolgy,
filter for objects of a specific type, and verify their boot up state.
i.e. to run a command against all Junos devices for example

"""
if 'topologyId' not in request.POST:
return render(request, 'ajax/ajaxError.html', {'error': "No Topology Id in request"})
Expand All @@ -1208,7 +1211,6 @@ def get_topology_config(request):
def execute_linux_automation(request):
"""
execute cli command on all linux instances in topology

"""
if 'topologyId' not in request.POST:
return render(request, 'ajax/ajaxError.html', {'error': "No Topology Id in request"})
Expand Down Expand Up @@ -1253,7 +1255,6 @@ def execute_linux_automation(request):
def execute_junos_automation(request):
"""
execute cli command on all junos instances in topology

"""
if 'topologyId' not in request.POST:
return render(request, 'ajax/ajaxError.html', {'error': "No Topology Id in request"})
Expand Down Expand Up @@ -1486,3 +1487,164 @@ def delete_stack(request, topology_id):
logger.debug(openstackUtils.delete_stack(stack_name))

return HttpResponseRedirect('/topologies/' + topology_id + '/')


def update_stack(request):
"""
:param request: Django request
:param topology_id: id of the topology to export
:return: renders the updated heat template
"""
required_fields = set(['topologyId'])
if not required_fields.issubset(request.POST):
return render(request, 'ajax/ajaxError.html', {'error': "Invalid Parameters in POST"})

topology_id = request.POST['topologyId']

logger.debug("-----Inside update stack-----")
try:
topology = Topology.objects.get(pk=topology_id)
except ObjectDoesNotExist:
return render(request, 'error.html', {'error': "Topology not found!"})
try:
# let's parse the json and convert to simple lists and dicts
logger.debug("loading config")
config = wistarUtils.load_config_from_topology_json(topology.json, topology_id)
logger.debug("Config is loaded")

# get the tenant_id of the desired project
tenant_id = openstackUtils.get_project_id(configuration.openstack_project)
logger.debug("using tenant_id of: %s" % tenant_id)
if tenant_id is None:
raise Exception("No project found for %s" % configuration.openstack_project)

# FIXME - verify all images are in glance before jumping off here!
stack_name = topology.name.replace(' ', '_')

port_list = openstackUtils.get_stack_ports(stack_name, tenant_id)
print(port_list)
heat_template = wistarUtils.get_heat_json_from_topology_config_for_update(config, port_list)
logger.debug("heat template created---test1")
logger.debug(heat_template)

logger.debug(openstackUtils.update_stack_template(stack_name, heat_template))
return refresh_deployment_status(request)

except Exception as e:
logger.debug("Caught Exception in deploy")
logger.debug(str(e))
return render(request, 'error.html', {'error': str(e)})


def list_snapshot(request, topology_id):
"""
:param request: Django request
:param topology_id: id of the topology to export
:return: creates a snapshot of the heat template
"""
try:
logger.debug("Inside create Snapshot----------")
tenant_id = openstackUtils.get_project_id(configuration.openstack_project)
logger.debug("using tenant_id of: %s" % tenant_id)
if tenant_id is None:
raise Exception("No project found for %s" % configuration.openstack_project)

logger.debug("Topology id -------------------: %s" % topology_id)

try:
topology = Topology.objects.get(pk=topology_id)
except ObjectDoesNotExist:
logger.error('topology id %s was not found!' % topology_id)
return render(request, 'error.html', {'error': "Topology not found!"})

# FIXME - verify all images are in glance before jumping off here!
stack_name = topology.name.replace(' ', '_')
snapshot_list = list()
logger.debug("-------------------stack_name--------------------: %s" % stack_name)
if openstackUtils.connect_to_openstack():
snapshot_list = openstackUtils.get_snapshot_list(tenant_id, stack_name, topology_id)

context = {'snapshot_list': snapshot_list}
logger.debug("Before rendering-----------")
return render(request, 'ajax/snapshot_list.html', context)

except Exception as e:
logger.debug("Caught Exception in deploy")
logger.debug(str(e))
return render(request, 'error.html', {'error': str(e)})


def rollback_snapshot(request, snapshot_id, topology_id):
"""
:param request: Django request
:param topology_id: id of the topology to export
:return: creates a snapshot of the heat template
"""

try:
logger.debug("Inside rollback Snapshot----------")
tenant_id = openstackUtils.get_project_id(configuration.openstack_project)
logger.debug("using tenant_id of: %s" % tenant_id)
if tenant_id is None:
raise Exception("No project found for %s" % configuration.openstack_project)

logger.debug("Topology id -------------------: %s" % topology_id)

try:
topology = Topology.objects.get(pk=topology_id)
except ObjectDoesNotExist:
logger.error('topology id %s was not found!' % topology_id)
return render(request, 'error.html', {'error': "Topology not found!"})

# FIXME - verify all images are in glance before jumping off here!
stack_name = topology.name.replace(' ', '_')
logger.debug("Stack name: %s" % stack_name)
logger.debug("Snapshot id: %s" % snapshot_id)

if openstackUtils.connect_to_openstack():
logger.debug(openstackUtils.rollback_snapshot(tenant_id, stack_name, snapshot_id))

return HttpResponseRedirect('/topologies/' + topology_id + '/')

except Exception as e:
logger.debug("Caught Exception in deploy")
logger.debug(str(e))
return render(request, 'error.html', {'error': str(e)})


def delete_snapshot(request, snapshot_id, topology_id):
"""
:param request: Django request
:param topology_id: id of the topology to export
:return: creates a snapshot of the heat template
"""

try:
logger.debug("Inside rollback Snapshot----------")
tenant_id = openstackUtils.get_project_id(configuration.openstack_project)
logger.debug("using tenant_id of: %s" % tenant_id)
if tenant_id is None:
raise Exception("No project found for %s" % configuration.openstack_project)

logger.debug("Topology id -------------------: %s" % topology_id)

try:
topology = Topology.objects.get(pk=topology_id)
except ObjectDoesNotExist:
logger.error('topology id %s was not found!' % topology_id)
return render(request, 'error.html', {'error': "Topology not found!"})

# FIXME - verify all images are in glance before jumping off here!
stack_name = topology.name.replace(' ', '_')
logger.debug("Stack name: %s" % stack_name)
logger.debug("Snapshot id: %s" % snapshot_id)

if openstackUtils.connect_to_openstack():
logger.debug(openstackUtils.delete_snapshot(tenant_id, stack_name, snapshot_id))

return HttpResponseRedirect('/topologies/' + topology_id + '/')

except Exception as e:
logger.debug("Caught Exception in deploy")
logger.debug(str(e))
return render(request, 'error.html', {'error': str(e)})
Loading