def start_topology(request): logger.debug("---- start_topology ---- ") json_string = request.body json_body = json.loads(json_string) try: if "name" in json_body[0]: topology_name = json_body[0]["name"] # get the topology by name topology = Topology.objects.get(name=topology_name) domain_list = libvirtUtils.get_domains_for_topology( "t" + str(topology.id) + "_") if len(domain_list) == 0: # it has not yet been deployed! logger.debug("not yet deployed!") # let's parse the json and convert to simple lists and dicts config = wistarUtils.load_config_from_topology_json( topology.json, topology.id) if config is None: return apiUtils( False, "Could not load config for topology: %s" % topology.id) logger.debug("Deploying to hypervisor now") # FIXME - should this be pushed into another module? av.inline_deploy_topology(config) # now, topology should be deployed and ready to go! network_list = libvirtUtils.get_networks_for_topology( "t" + str(topology.id) + "_") domain_list = libvirtUtils.get_domains_for_topology( "t" + str(topology.id) + "_") for network in network_list: logger.debug("starting network: %s" % network["name"]) libvirtUtils.start_network(network["name"]) time.sleep(.5) for domain in domain_list: # no sleep time? Just go ahead and melt the disks! time.sleep(.5) logger.debug("starting domain: %s" % domain["uuid"]) libvirtUtils.start_domain(domain["uuid"]) return apiUtils.return_json(True, 'Topology started!', topology_id=topology.id) except Topology.DoesNotExist: return apiUtils.return_json(False, 'Topology Does not Exist') except Exception as ex: logger.debug(str(ex)) return apiUtils.return_json(False, 'Could not start topology!')
def delete(request, topology_id): logger.debug('---- topology delete ----') topology_prefix = "t%s_" % topology_id if configuration.deployment_backend == "kvm": network_list = libvirtUtils.get_networks_for_topology(topology_prefix) for network in network_list: logger.debug("undefine network: " + network["name"]) libvirtUtils.undefine_network(network["name"]) domain_list = libvirtUtils.get_domains_for_topology(topology_prefix) for domain in domain_list: # remove reserved mac addresses for all domains in this topology mac_address = libvirtUtils.get_management_interface_mac_for_domain(domain["name"]) libvirtUtils.release_management_ip_for_mac(mac_address) logger.debug("undefine domain: " + domain["name"]) source_file = libvirtUtils.get_image_for_domain(domain["uuid"]) if libvirtUtils.undefine_domain(domain["uuid"]): if source_file is not None: osUtils.remove_instance(source_file) topology = get_object_or_404(Topology, pk=topology_id) osUtils.remove_instances_for_topology(topology_prefix) osUtils.remove_cloud_init_tmp_dirs(topology_prefix) topology.delete() messages.info(request, 'Topology %s deleted' % topology.name) return HttpResponseRedirect('/topologies/')
def start_topology(request): 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'] delay_str = request.POST.get('delay', '180') try: delay = int(delay_str) except ValueError: delay = 180 if topology_id == "": logger.debug("Found a blank topoId!") return render(request, 'ajax/ajaxError.html', {'error': "Blank Topology Id found"}) domain_list = libvirtUtils.get_domains_for_topology("t" + topology_id + "_") network_list = [] if configuration.deployment_backend == "kvm": network_list = libvirtUtils.get_networks_for_topology("t" + topology_id + "_") for network in network_list: logger.debug("Starting network: " + network["name"]) if libvirtUtils.start_network(network["name"]): time.sleep(1) else: return render( request, 'ajax/ajaxError.html', {'error': "Could not start network: " + network["name"]}) num_domains = len(domain_list) iter_counter = 1 for domain in domain_list: logger.debug("Starting domain " + domain["name"]) if libvirtUtils.is_domain_running(domain["name"]): # skip already started domains logger.debug("domain %s is already started" % domain["name"]) iter_counter += 1 continue if libvirtUtils.start_domain(domain["uuid"]): # let's not sleep after the last domain has been started if iter_counter < num_domains: time.sleep(delay) iter_counter += 1 else: return render( request, 'ajax/ajaxError.html', {'error': "Could not start domain: " + domain["name"]}) logger.debug("All domains started") return refresh_deployment_status(request)
def refresh_deployment_status(request): logger.debug('---- ajax refresh_deployment_status ----') 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'] if topology_id == "": logger.debug( "Found a blank topology_id, returning full hypervisor status") return refresh_hypervisor_status(request) if configuration.deployment_backend == "openstack": logger.info('Refresh openstack deployment status') return refresh_openstack_deployment_status(request, topology_id) else: domain_list = libvirtUtils.get_domains_for_topology("t" + topology_id + "_") network_list = [] is_linux = False if osUtils.check_is_linux(): is_linux = True network_list = libvirtUtils.get_networks_for_topology("t" + topology_id + "_") context = { 'domain_list': domain_list, 'network_list': network_list, 'topologyId': topology_id, 'isLinux': is_linux } return render(request, 'ajax/deploymentStatus.html', context)
def launch(request, topology_id): logger.debug('---- topology launch ----') try: topology = Topology.objects.get(pk=topology_id) except ObjectDoesNotExist as ex: logger.debug(ex) return render(request, 'error.html', {'error': "Topology not found!"}) if configuration.deployment_backend == 'openstack': ret = av.deploy_stack(request, topology_id) if ret is not None: inventory = wistarUtils.get_topology_inventory(topology) wistarUtils.send_new_topology_event(inventory) try: # let's parse the json and convert to simple lists and dicts config = wistarUtils.load_config_from_topology_json(topology.json, topology_id) logger.debug("Deploying topology: %s" % topology_id) # this is a hack - inline deploy should be moved elsewhere # but the right structure isn't really there for a middle layer other # than utility and view layers ... unless I want to mix utility libs av.inline_deploy_topology(config) inventory = wistarUtils.get_topology_inventory(topology) wistarUtils.send_new_topology_event(inventory) except Exception as e: logger.error('exception: %s' % e) return render(request, 'error.html', {'error': str(e)}) if configuration.deployment_backend != 'kvm': # only continue in kvm case, openstack will start instances for us on deployment return domain_list = libvirtUtils.get_domains_for_topology("t%s_" % topology_id) network_list = [] if osUtils.check_is_linux(): network_list = libvirtUtils.get_networks_for_topology("t%s_" % topology_id) for network in network_list: logger.debug("Starting network: " + network["name"]) if libvirtUtils.start_network(network["name"]): time.sleep(1) else: return render(request, 'error.html', {'error': "Could not start network: " + network["name"]}) num_domains = len(domain_list) iter_counter = 1 for domain in domain_list: logger.debug("Starting domain " + domain["name"]) if libvirtUtils.start_domain(domain["uuid"]): if iter_counter < num_domains: time.sleep(1) iter_counter += 1 else: return render(request, 'error.html', {'error': "Could not start domain: " + domain["name"]}) logger.debug("All domains started") messages.info(request, 'Topology %s launched successfully' % topology.name) return HttpResponseRedirect('/topologies/')
def delete_topology(request): """ DEPRECATED :param request: :return: """ logger.debug("---- delete_topology ----") json_string = request.body json_body = json.loads(json_string) required_fields = set(['name']) if not required_fields.issubset(json_body[0]): logger.error("Invalid parameters in json body") return HttpResponse(status=500) topology_name = json_body[0]["name"] try: # get the topology by name topology = Topology.objects.get(name=topology_name) except ObjectDoesNotExist: return apiUtils.return_json(False, "Topology is already deleted or does not exist") try: topology_prefix = "t%s_" % topology.id if hasattr(configuration, "use_openvswitch") and configuration.use_openvswitch: use_ovs = True else: use_ovs = False network_list = libvirtUtils.get_networks_for_topology(topology_prefix) for network in network_list: logger.debug("undefining network: " + network["name"]) libvirtUtils.undefine_network(network["name"]) if use_ovs: ovsUtils.delete_bridge(network["name"]) domain_list = libvirtUtils.get_domains_for_topology(topology_prefix) for domain in domain_list: logger.debug("undefining domain: " + domain["name"]) source_file = libvirtUtils.get_image_for_domain(domain["uuid"]) if libvirtUtils.undefine_domain(domain["uuid"]): if source_file is not None: osUtils.remove_instance(source_file) # remove reserved mac addresses for all domains in this topology mac_address = libvirtUtils.get_management_interface_mac_for_domain(domain["name"]) libvirtUtils.release_management_ip_for_mac(mac_address) topology.delete() return apiUtils.return_json(True, "Topology deleted!") except Exception as e: logger.error(str(e)) return HttpResponse(status=500)
def redeploy_topology(request): required_fields = set(['json', 'topologyId']) if not required_fields.issubset(request.POST): return render(request, 'ajax/ajaxError.html', {'error': "No Topology Id in request"}) topology_id = request.POST['topologyId'] j = request.POST['json'] try: topo = Topology.objects.get(pk=topology_id) topo.json = j topo.save() except ObjectDoesNotExist: return render(request, 'ajax/ajaxError.html', {'error': "Topology doesn't exist"}) try: domains = libvirtUtils.get_domains_for_topology(topology_id) config = wistarUtils.load_config_from_topology_json( topo.json, topology_id) logger.debug('checking for orphaned domains first') # find domains we no longer need for d in domains: logger.debug('checking domain: %s' % d['name']) found = False for config_device in config["devices"]: if config_device['name'] == d['name']: found = True continue if not found: logger.info("undefine domain: " + d["name"]) source_file = libvirtUtils.get_image_for_domain(d["uuid"]) if libvirtUtils.undefine_domain(d["uuid"]): if source_file is not None: osUtils.remove_instance(source_file) osUtils.remove_cloud_init_seed_dir_for_domain(d['name']) except Exception as e: logger.debug("Caught Exception in redeploy") logger.debug(str(e)) return render(request, 'ajax/ajaxError.html', {'error': str(e)}) # forward onto deploy topo try: inline_deploy_topology(config) inventory = wistarUtils.get_topology_inventory(topo) wistarUtils.send_new_topology_event(inventory) except Exception as e: logger.debug("Caught Exception in inline_deploy") logger.debug(str(e)) return render(request, 'ajax/ajaxError.html', {'error': str(e)}) return refresh_deployment_status(request)
def get_domain_status_for_topology(topology_id): domain_status = libvirtUtils.get_domains_for_topology("t" + str(topology_id) + "_") status = "running" for d in domain_status: if d["state"] == "shut off": status = "powered off" break return status
def delete(request, topology_id): logger.debug('---- topology delete ----') topology_prefix = "t%s_" % topology_id topology = get_object_or_404(Topology, pk=topology_id) if configuration.deployment_backend == "kvm": if hasattr(configuration, "use_openvswitch") and configuration.use_openvswitch: use_ovs = True else: use_ovs = False network_list = libvirtUtils.get_networks_for_topology(topology_prefix) for network in network_list: logger.debug("undefine network: " + network["name"]) libvirtUtils.undefine_network(network["name"]) if use_ovs: ovsUtils.delete_bridge(network["name"]) domain_list = libvirtUtils.get_domains_for_topology(topology_prefix) for domain in domain_list: # remove reserved mac addresses for all domains in this topology mac_address = libvirtUtils.get_management_interface_mac_for_domain( domain["name"]) libvirtUtils.release_management_ip_for_mac(mac_address) logger.debug("undefine domain: " + domain["name"]) source_file = libvirtUtils.get_image_for_domain(domain["uuid"]) if libvirtUtils.undefine_domain(domain["uuid"]): if source_file is not None: osUtils.remove_instance(source_file) osUtils.remove_instances_for_topology(topology_prefix) osUtils.remove_cloud_init_tmp_dirs(topology_prefix) elif configuration.deployment_backend == "openstack": stack_name = topology.name.replace(' ', '_') if openstackUtils.connect_to_openstack(): logger.debug(openstackUtils.delete_stack(stack_name)) topology.delete() messages.info(request, 'Topology %s deleted' % topology.name) return HttpResponseRedirect('/topologies/')
def pause_topology(request): 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'] if topology_id == "": logger.debug("Found a blank topoId!") return render(request, 'ajax/ajaxError.html', {'error': "Blank Topology Id found"}) domain_list = libvirtUtils.get_domains_for_topology("t" + topology_id + "_") for domain in domain_list: if domain["state"] == "running": logger.debug("Pausing domain " + domain["name"]) libvirtUtils.suspend_domain(domain["uuid"]) time.sleep(5) else: logger.debug("Domain %s is already shut down" % domain["name"]) network_list = [] if osUtils.check_is_linux(): network_list = libvirtUtils.get_networks_for_topology("t" + topology_id + "_") for network in network_list: logger.debug("Stopping network: " + network["name"]) if libvirtUtils.stop_network(network["name"]): time.sleep(1) else: return render( request, 'ajax/ajaxError.html', {'error': "Could not stop network: " + network["name"]}) logger.debug("All domains paused") return refresh_deployment_status(request)
def deploy_topology(request): if 'topologyId' not in request.POST: return render(request, 'ajax/ajaxError.html', {'error': "No Topology Id in request"}) topology_id = request.POST['topologyId'] try: topo = Topology.objects.get(pk=topology_id) except ObjectDoesNotExist: return render(request, 'ajax/ajaxError.html', {'error': "Topology not found!"}) try: # let's parse the json and convert to simple lists and dicts config = wistarUtils.load_config_from_topology_json( topo.json, topology_id) # FIXME - should this be pushed into another module? inline_deploy_topology(config) inventory = wistarUtils.get_topology_inventory(topo) wistarUtils.send_new_topology_event(inventory) except Exception as e: logger.debug("Caught Exception in deploy") logger.debug(str(e)) return render(request, 'ajax/ajaxError.html', {'error': str(e)}) domain_list = libvirtUtils.get_domains_for_topology("t" + topology_id + "_") network_list = [] if osUtils.check_is_linux(): network_list = libvirtUtils.get_networks_for_topology("t" + topology_id + "_") context = { 'domain_list': domain_list, 'network_list': network_list, 'isLinux': True, 'topologyId': topology_id } return render(request, 'ajax/deploymentStatus.html', context)
def get_topology_config(request): """ Grab a json object representing the topology config as well as the domain status for each object 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"}) topology_id = request.POST['topologyId'] try: topo = Topology.objects.get(pk=topology_id) # let's parse the json and convert to simple lists and dicts config = wistarUtils.load_config_from_topology_json( topo.json, topology_id) domain_status = libvirtUtils.get_domains_for_topology("t" + topology_id + "_") context = { 'config': config, 'domain_status': domain_status, 'topologyId': topology_id } logger.debug("returning") return HttpResponse(json.dumps(context), content_type="application/json") except Exception as ex: logger.debug(ex) return render(request, 'ajax/ajaxError.html', {'error': "Topology not found!"})
def get_topology_status(request): """ get the topology id and status for the given topology_name returns json object indicating sandbox status 1. check exists 2. check deployed 3. check booted 4. check console ready 5. check ips """ context = dict() context["status"] = "not ready" context["deploy-status"] = "not ready" context["boot-status"] = "not ready" context["console-status"] = "not ready" context["configured-status"] = "not ready" context["message"] = "no message" context["topologyId"] = "0" if 'topology_name' not in request.POST: context["message"] = "Invalid parameters in POST" return HttpResponse(json.dumps(context), content_type="application/json") topology_name = request.POST['topology_name'] try: topology = Topology.objects.get(name=topology_name) except ObjectDoesNotExist: context[ "message"] = "topology with name '%s' does not exist" % topology_name return HttpResponse(json.dumps(context), content_type="application/json") try: logger.debug("Got topo " + str(topology.id)) domain_prefix = "t%s_" % topology.id domains = libvirtUtils.get_domains_for_topology(domain_prefix) if len(domains) == 0: context["message"] = "not yet deployed!" return HttpResponse(json.dumps(context), content_type="application/json") context["deploy-status"] = "ready" for d in domains: if d["state"] == "shut off": context["message"] = "not all instances are started" return HttpResponse(json.dumps(context), content_type="application/json") context["boot-status"] = "ready" raw_json = json.loads(topology.json) for json_object in raw_json: if "userData" in json_object and "wistarVm" in json_object[ "userData"]: ud = json_object["userData"] image_type = ud["type"] domain_name = domain_prefix + ud["label"] if image_type == "linux": if not consoleUtils.is_linux_device_at_prompt(domain_name): logger.debug("%s does not have a console ready" % domain_name) context[ "message"] = "not all instances have a console ready" return HttpResponse(json.dumps(context), content_type="application/json") # FIXME - add junos support here context["console-status"] = "ready" for json_object in raw_json: if "userData" in json_object and "wistarVm" in json_object[ "userData"]: ud = json_object["userData"] ip = ud["ip"] if not osUtils.check_ip(ip): context[ "message"] = "not all instances have a management IP" return HttpResponse(json.dumps(context), content_type="application/json") context["configured-status"] = "ready" context["status"] = "ready" context["message"] = "Sandbox is fully booted and available" return HttpResponse(json.dumps(context), content_type="application/json") except Exception as ex: logger.debug(str(ex)) context["message"] = "Caught Exception!" return HttpResponse(json.dumps(context), content_type="application/json")
def start_topology_old(request): """ DEPRECATED verify the topology exists and is started! required parameters: topology_name, id of which to clone, cloud_init data returns json { "status": "running|unknown|powered off", "topology_id": "0" } """ context = {"status": "unknown"} required_fields = set( ['topology_name', 'clone_id', 'script_id', 'script_param']) if not required_fields.issubset(request.POST): context["status"] = "unknown" context["message"] = "Invalid parameters in POST" return HttpResponse(json.dumps(context), content_type="application/json") topology_name = request.POST['topology_name'] clone_id = request.POST['clone_id'] script_id = request.POST['script_id'] script_param = request.POST['script_param'] try: # get the topology by name topo = Topology.objects.get(name=topology_name) except ObjectDoesNotExist: # uh-oh! it doesn't exist, let's clone it and keep going # clone the topology with the new name specified! topology = Topology.objects.get(pk=clone_id) # get a list of all the currently used IPs defined all_used_ips = wistarUtils.get_used_ips() logger.debug(str(all_used_ips)) raw_json = json.loads(topology.json) for json_object in raw_json: if "userData" in json_object and "wistarVm" in json_object[ "userData"]: ud = json_object["userData"] ip = ud["ip"] ip_octets = ip.split('.') # get the next available ip next_ip = wistarUtils.get_next_ip(all_used_ips, 2) # mark it as used so it won't appear in the next iteration all_used_ips.append(next_ip) ip_octets[3] = str(next_ip) newIp = ".".join(ip_octets) ud["ip"] = newIp ud["configScriptId"] = script_id ud["configScriptParam"] = script_param description = "Clone from: %s\nScript Id: %s\nScript Param: %s" % ( clone_id, script_id, script_param) topo = Topology(name=topology_name, description=description, json=json.dumps(raw_json)) topo.save() try: # by this point, the topology already exists logger.debug("Got topo " + str(topo.id)) domain_status = libvirtUtils.get_domains_for_topology("t" + str(topo.id) + "_") if len(domain_status) == 0: # it has not yet been deployed! logger.debug("not yet deployed!") # let's parse the json and convert to simple lists and dicts config = wistarUtils.load_config_from_topology_json( topo.json, topo.id) logger.debug("Deploying to hypervisor now") # FIXME - should this be pushed into another module? av.inline_deploy_topology(config) time.sleep(1) except Exception as e: logger.debug(str(e)) context["status"] = "unknown" context["message"] = "Exception" return HttpResponse(json.dumps(context), content_type="application/json") try: # at this point, the topology now exists and is deployed! network_list = libvirtUtils.get_networks_for_topology("t" + str(topo.id) + "_") domain_list = libvirtUtils.get_domains_for_topology("t" + str(topo.id) + "_") for network in network_list: libvirtUtils.start_network(network["name"]) time.sleep(1) for domain in domain_list: time.sleep(10) libvirtUtils.start_domain(domain["uuid"]) context = { 'status': 'booting', 'topologyId': topo.id, 'message': 'sandbox is booting' } logger.debug("returning") return HttpResponse(json.dumps(context), content_type="application/json") except Exception as ex: logger.debug(str(ex)) context["status"] = "unknown" context["message"] = "Caught Exception %s" % ex return HttpResponse(json.dumps(context), content_type="application/json")
def start_topology(request): logger.debug("---- start_topology ---- ") json_string = request.body try: json_body = json.loads(json_string) except ValueError: return apiUtils(False, "Could not load json payload") try: if "name" in json_body[0]: topology_name = json_body[0]["name"] # do we have a specified delay between starting domains? if 'start_delay' in json_body[0]: delay = int(json_body[0]['start_delay']) else: delay = 0.5 # get the topology by name try: topology = Topology.objects.get(name=topology_name) except ObjectDoesNotExist: logger.error('Could not find topology with name: %s' % topology_name) return apiUtils( False, "Could not find topology with name: %s" % topology_name) domain_list = libvirtUtils.get_domains_for_topology( "t" + str(topology.id) + "_") if len(domain_list) == 0: # it has not yet been deployed! logger.debug("not yet deployed!") # let's parse the json and convert to simple lists and dicts config = wistarUtils.load_config_from_topology_json( topology.json, topology.id) if config is None: return apiUtils( False, "Could not load config for topology: %s" % topology.id) logger.debug("Deploying to hypervisor now") # FIXME - should this be pushed into another module? av.inline_deploy_topology(config) # now, topology should be deployed and ready to go! network_list = libvirtUtils.get_networks_for_topology( "t" + str(topology.id) + "_") domain_list = libvirtUtils.get_domains_for_topology( "t" + str(topology.id) + "_") for network in network_list: logger.debug("starting network: %s" % network["name"]) libvirtUtils.start_network(network["name"]) time.sleep(delay) for domain in domain_list: # no sleep time? Just go ahead and melt the disks! if domain["state"] != 'running': logger.debug("starting domain: %s" % domain["uuid"]) libvirtUtils.start_domain(domain["uuid"]) time.sleep(delay) return apiUtils.return_json(True, 'Topology started!', topology_id=topology.id) except Exception as ex: logger.debug(str(ex)) return apiUtils.return_json(False, 'Could not start topology!')