def topology_create(request): # make sure the user is logged in if not permissions.allowed_topology_access_create(request.user): messages.info("Please login as a user who is permitted to create topologies.") return HttpResponseRedirect('/login/?next=/topology/create/') tn = 'vns/topology_create.html' CTForm = make_ctform(request.user) if request.method == 'POST': form = CTForm(request.POST) if form.is_valid(): template_id = form.cleaned_data['template'] ipblock_id = form.cleaned_data['ipblock'] num_to_create = form.cleaned_data['num_to_create'] try: template = db.TopologyTemplate.objects.get(pk=template_id) except db.TopologyTemplate.DoesNotExist: messages.error(request, "No such template") return direct_to_template(request, tn, { 'form': form }) try: ipblock = db.IPBlock.objects.get(pk=ipblock_id) except db.IPBlock.DoesNotExist: messages.error(request, "No such IP block") return direct_to_template(request, tn, { 'form': form }) if not permissions.allowed_topologytemplate_access_use(request.user, template): messages.error(request, "You cannot create topologies from this template") return direct_to_template(request, tn, { 'form': form }) if not permissions.allowed_ipblock_access_use(request.user, ipblock): messages.error(request, "You cannot create topologies in this IP block") return direct_to_template(request, tn, { 'form': form }) if num_to_create > 30: messages.error(request, "You cannot create >30 topologies at once") return direct_to_template(request, tn, { 'form': form }) # TODO: should validate that request.user can use the requested # template and IP block # Tell the DBService that we want to make the database calls from this thread DBService.thread = threading.current_thread() # try to create the topologies src_filters = [] for i in range(num_to_create): err, _, _, _ = instantiate_template(request.user.get_profile().org, request.user, template, ipblock, src_filters, temporary=False, use_recent_alloc_logic=False, public=False, use_first_available=True) if err is not None: messages.error(request, "Successfully allocated %d '%s' topologies from %s. Failed to make the other request topologies: %s." % (i, template.name, ipblock, err)) return direct_to_template(request, tn) messages.success(request, "Successfully allocated %d '%s' topologies from %s." % (num_to_create, template.name, ipblock)) return direct_to_template(request, tn) else: form = CTForm() return direct_to_template(request, tn, { 'form': form })
def topologytemplate_access_check(request, callee, action, template_id=None): """Check that the user is allowed access, and if they are call the given Callable. @param request An HTTP request @param callee Gives the Callable to call @param action One of "add", "change", "use", "delete", describing the permissions needed @param template_id The ID of the template in question; not used for action = "add" @exception ValueError If an action is unrecognised @exception KeyError If an option is missing""" def denied(): """Generate an error message and redirect if we try do something to a template we're not allowed to""" messages.error(request, "Either this topology template doesn't exist or" " you don't have permission to %s it." % action) return HttpResponseRedirect('/') def denied_add(): """Generate an error message and redirect if we try to create a template and are not allowed to""" messages.error(request, "You don't have permission to create topology " "templates.") return HttpResponseRedirect('/') # If we're trying to add a template, don't need to get the template itself if action == "add": if request.user.has_perm("vnswww.add_topologytemplate"): return callee(request) else: return denied_add() else: # Try getting the template - if it doesn't exist, show the same message # as for permission denied template_id = template_id try : template = db.TopologyTemplate.objects.get(id=template_id) except db.TopologyTemplate.DoesNotExist: return denied() if action == "use": if permissions.allowed_topologytemplate_access_use(request.user, template): return callee(request, template) else: return denied() elif action == "change": if permissions.allowed_topologytemplate_access_change(request.user, template): return callee(request, template) else: return denied() elif action == "delete": if permissions.allowed_topologytemplate_access_delete(request.user, template): return callee(request, template) else: return denied() else: raise ValueError("Unknown action: %s" % options["action"])
def group_topology_create(request, group, **kwargs): """Create topologies for a group, with each user in the group becoming the owner of one topology. @param request An HttpRequest @param group The group to add the topologies for""" tn = "vns/group_topology_create.html" # Check we're allowed to create topologies if not permissions.allowed_topology_access_create(request.user): messages.info("Please login as a user who is permitted to create topologies.") return HttpResponseRedirect('/login/?next=/topology/create/') # Import a function to create the form CreateTopologyForm = make_ctform(request.user) if request.method == "POST": form = CreateTopologyForm(request.POST) if form.is_valid(): template_id = form.cleaned_data['template'] ipblock_id = form.cleaned_data['ipblock'] num_to_create = form.cleaned_data['num_to_create'] ip = form.cleaned_data['ip_subnet'] mask = form.cleaned_data['ip_subnet_mask'] # Do lots of permissions and existence checks - need a topology # template and IP block try: template = db.TopologyTemplate.objects.get(pk=template_id) except db.TopologyTemplate.DoesNotExist: messages.error(request, "No such template") return direct_to_template(request, tn, { 'form': form, 'group': group}) try: ipblock = db.IPBlock.objects.get(pk=ipblock_id) except db.IPBlock.DoesNotExist: messages.error(request, "No such IP block") return direct_to_template(request, tn, { 'form': form, 'group': group}) if not permissions.allowed_topologytemplate_access_use(request.user, template): messages.error(request, "You cannot create topologies from this template") return direct_to_template(request, tn, { 'form': form, 'group': group}) if not permissions.allowed_ipblock_access_use(request.user, ipblock): messages.error(request, "You cannot create topologies in this IP block") return direct_to_template(request, tn, { 'form': form, 'group': group}) if num_to_create > 5: messages.error(request, "You cannot create >5 topologies / user at once") return direct_to_template(request, tn, { 'form': form, 'group': group}) # Get a list of users try: users = User.objects.filter(vns_groups=group) except User.DoesNotExist: messages.error("No users in this group to create topologies for") return HttpResponseRedirect("/") # Tell the DBService module to use this thread for accessing the DB DBService.thread = threading.current_thread() # Otherwise, we're good to actually create the topologies, subject # to permissions checks on each user. # These variables track the number with permissions errors, the # number successfully created and the number rwith other errors # to report to the user. num_perms = 0 num_created = 0 num_errs = 0 for u in users: # Check we have permission to change this user if not permissions.allowed_user_access_change(request.user, u): num_perms += 1 continue # Make a list of source IP filters if ip != None and mask != None: src_filters = [(ip, mask)] else: src_filters = [] # Create the topology for _ in xrange(0,num_to_create): err,_,_,_ = instantiate_template(org=u.get_profile().org, owner=u, template=template, ip_block_from=ipblock, src_filters=src_filters, temporary=False, use_recent_alloc_logic=False, public=False, use_first_available=True) # Update the numbers with/without errors if err is not None: num_errs += 1 else: num_created += 1 # Report to the user topology_create_message(request, num_errs, num_perms, num_created) return HttpResponseRedirect('/org/%s/%s/' % (group.org.name, group.name)) else: # The form is not valid messages.error(request, "Invalid form") return direct_to_template(request, tn, {'form':form, 'group':group}) else: # request.method != 'POST' # Need to give them a form but do nothing else return direct_to_template(request, tn, {'form':CreateTopologyForm(), 'group':group})