Ejemplo n.º 1
0
def erratumView(request):
    context = {}
    if request.method == "GET":
        if request.GET.get("erratum_hosts"):
            form = ErratumForm(request.GET)
            if form.is_valid():
                host_list = []
                env = form.data["environment"]
                erratum = form.data["erratum"]
                # TaskScripts().parseServerForm(env, erratum)
                if env == "all":
                    server_objs = Server.objects.all().order_by("server")
                    env = "whole"
                else:
                    server_objs = Server.objects.filter(env=env).order_by("server")
                for host in server_objs:
                    if host.updates:
                        # TaskScripts().parseServerForm(host.server, host.updates)
                        # TaskScripts().parseServerForm("These are the types of updates",type(host.updates))
                        # updates = eval(host.updates)
                        updates = host.updates.strip("{}").split(",")
                        updates = list(updates)
                    else:
                        updates = []
                    # TaskScripts().parseServerForm(host.server, updates)
                    if any(x in erratum for x in updates):
                        host_list.append(host)
                    else:
                        pass
                total = len(host_list)
                # TaskScripts().parseServerForm(total, host_list)
                context = {"host_list": host_list, "env": env, "total": total}
                return render(request, "autopatch/erratum_hosts.html", context)
    context["encouragement"] = encouragement()
    return render(request, "autopatch/erratum_hosts.html", context)
Ejemplo n.º 2
0
def resultView(request, pk):
    args = []
    server = get_object_or_404(Server, pk=pk)
    template_name = "autopatch/results.html"
    hostgroup = "nothing"
    exclude = "nothing"
    skip = []
    if request.POST.get("set_param"):
        form = ServerForm(request.POST)
        if form.is_valid():
            exclude = form.data["exclude"]
            hostgroup = form.data["hostgroup"]
            skip = form.cleaned_data["skip"]
            comments = form.cleaned_data["comments"]
            s = Server.objects.get(pk=pk)
            # Creating a new Audit entry for the changes_list.html
            cn = "".join(request.user.ldap_user.attrs["cn"])
            Audit.objects.create(
                server=s.server, skip=s.skip, exclude=s.exclude, hostgroup=s.hostgroup, comments=s.comments, user=cn
            )
            s.exclude = exclude
            s.hostgroup = hostgroup
            s.skip = skip
            s.comments = comments
            s.save()
        else:
            pass
    else:
        pass
    id_number = pk
    context = {"exclude": exclude, "encouragement": encouragement(), "hostgroup": hostgroup, "skip": skip}
    return HttpResponseRedirect(reverse("autopatch:detail", kwargs={"pk": id_number}), context)
Ejemplo n.º 3
0
def SetOwners(request):
    # owners is a test variable
    owners_list = []
    context = {"encouragement": encouragement()}
    owner_list = Owner.objects.all().order_by("owner")
    # If the "Set Owners" button is pressed
    if request.method == "GET":
        if request.GET.get("addowners"):
            owners = str(request.GET.get("owners"))
            owners_list = owners.split(",")
            for each in owners_list:
                cl_owner = each.strip()
                if not Owner.objects.filter(owner=cl_owner).exists():
                    owner = Owner(owner=cl_owner)
                    owner.owner = cl_owner
                    owner.save()
                else:
                    pass
            context["owners_list"] = ModMaint().excludedOwners()
            ModMaint().allHostTotals()
            return HttpResponseRedirect(reverse("autopatch:owners"), context)
        # If the "Remove Owners" button is pressed
        elif request.GET.get("delowners"):
            Owner.objects.all().delete()
            context["owners_list"] = ModMaint().excludedOwners()
            ModMaint().allHostTotals()
            return HttpResponseRedirect(reverse("autopatch:owners"), context)
        else:
            pass
    context["owners_list"] = ModMaint().excludedOwners()
    return render(request, "autopatch/owners.html", context)
Ejemplo n.º 4
0
def hostTotals(request):
    context = {"encouragement": encouragement()}
    if request.GET.get("host_totals"):
        envs = (("Prod", ".prod."), ("Stage", ".stage."), ("QA", ".qa."), ("Dev", ".dev"))
        for env, field in envs:
            total = ModMaint().hostCount(env, field)
    return HttpResponseRedirect(reverse("autopatch:tasks"), context)
Ejemplo n.º 5
0
def HostsView(request, env):
    context = {"encouragement": encouragement()}
    # TaskScripts().parseServerForm('Checking environment!',env)
    if env == "Dev":
        field = ".dev"
        env_model = "dev"
    elif env == "QA":
        field = ".qa."
        env_model = "qa"
    elif env == "Stage":
        field = ".stage."
        env_model = "stage"
        # TaskScripts().parseServerForm('Checking env_model!',env_model)
    elif env == "Prod":
        field = ".prod."
        env_model = "prod"
    else:
        return render(request, "autopatch:Home", context)
    if Hosttotal.objects.filter(env=env).exists():
        h = Hosttotal.objects.get(env=env)
        total = h.total
    else:
        total = None
    host_list = Server.objects.all().filter(env=env_model).order_by("server")
    context["host_list"] = host_list
    context["total"] = total
    context["env"] = env
    # TaskScripts().parseServerForm('Checking context!', context)
    return render(request, "autopatch/host_list.html", context)
Ejemplo n.º 6
0
def Git(request):
    unlist = []
    # Checks if a path was give to the git repo
    if request.GET.get("mybtn"):
        manifests = str(request.GET.get("gitpath"))
    elif request.GET.get("clear"):
        Server.objects.all().delete()
        envs = (("Prod", ".prod."), ("Stage", ".stage."), ("QA", ".qa."), ("Dev", ".dev"))
        for env, field in envs:
            total = ModMaint().hostCount(env, field)
        manifests = None
    else:
        manifests = None
    # if a path was give this call parseGit which does the
    # importing of FQDNs and syspatch_* parameters to the Server model
    if manifests:
        # Server.objects.all().delete()
        hosts = ModMaint().parseGit(manifests)
        Audit.objects.all().delete()
    else:
        pass
    # unsassignlist (not in an env) hosts are displayed on the patching-tasks.html template
    unassignlist = Server.objects.all().filter(env="unassigned").order_by("server")
    for each in unassignlist:
        unhost = each.server
        unlist.append(unhost)
    context = {"unlist": unlist, "encouragement": encouragement()}
    return HttpResponseRedirect(reverse("autopatch:tasks"), context)
Ejemplo n.º 7
0
def DetailView(request, pk):
    # Provides the information for the results.html template
    server = get_object_or_404(Server, pk=pk)
    if server.updates != None:
        server.updates = server.updates.strip("{}").replace('"', "").replace(" ", "").split(",")
    if server.plerrata != None:
        server.plerrata = server.plerrata.strip("{}").replace('"', "").replace(" ", "").split(",")
    template_name = "autopatch/results.html"
    context = {"encouragement": encouragement(), "server": server}
    return render_to_response("autopatch/results.html", context, context_instance=RequestContext(request))
Ejemplo n.º 8
0
def profile(request):
    context = {"encouragement": encouragement()}
    # groups = ldap_user.group_names
    # context['groups'] = groups
    uid = request.user.username
    # TaskScripts().parseServerForm(request.user, request.user.ldap_user.attrs)
    # TaskScripts().parseServerForm(request.user, request.user.ldap_user.attrs['mail'][0])
    context["mail"] = request.user.ldap_user.attrs["mail"][0]
    all_groups = request.user.ldap_user.group_names
    context["name"] = "".join(request.user.ldap_user.attrs["displayname"] + request.user.ldap_user.attrs["sn"])
    context["uid"] = uid
    context["all_groups"] = all_groups
    return render_to_response("autopatch/profile.html", context, context_instance=RequestContext(request))
Ejemplo n.º 9
0
def DevView(request):
    dev_list = Server.objects.all().order_by('server')
    env = "Dev"
    field = ".dev"
    if Hosttotal.objects.filter(env=env).exists():
        h = Hosttotal.objects.get(env=env)
        devtotal = h.total
    else:
        devtotal = None
    if(request.GET.get('mybtn')):
        total = ModMaint().hostCount(env, field)
        devtotal = total.get("total")
    context = {'dev_list': dev_list, 'total': devtotal, 'env': env, 'encouragement': encouragement()}
    return render(request, 'autopatch/dev-servers.html', context)
Ejemplo n.º 10
0
def QASat(request):
    context = {'encouragement': encouragement()}
    if request.POST:
        form = LoginForm(request.POST)
        if form.is_valid():
            user = form.cleaned_data['loginname']
            pswd = form.cleaned_data['password']
            URL = form.cleaned_data['satellite']
            name = form.cleaned_data['hostname']
            client = xmlrpc.client.Server(URL, verbose=0)
            session = client.auth.login(user, pswd)
            data = client.system.getId(session, name)
            getid = data[0].get('id')
            context = {'getid': getid}
            client.auth.logout(session)
    return render_to_response('autopatch/patching-tasks.html', context,
                              context_instance=RequestContext(request))
Ejemplo n.º 11
0
def Git(request):
    unlist = []
    if(request.GET.get('mybtn')):
        manifests = str(request.GET.get('gitpath'))
    else:
        manifests = None
    if manifests:
        Server.objects.all().delete()
        hosts = ModMaint().parseGit(manifests)
    else:
        pass
    unassignlist = Server.objects.all().filter(env="unassigned").order_by('server')
    for each in unassignlist:
        unhost = each.server
        unlist.append(unhost)
    context = {'unlist': unlist, 'encouragement': encouragement()}
    return render(request, 'autopatch/patching-tasks.html', context)
Ejemplo n.º 12
0
def SatUpdates(request):
    #SatId will get the ID of each server in Satellite
    #There are 4 buttons on the patching tasks page, one for each env
    context = {'encouragement': encouragement()}
    if request.POST:
        form = LoginForm(request.POST)
        #TaskScripts().parseSatForm(request, form)
        if form.is_valid():
            user = form.cleaned_data['loginname']
            pswd = form.cleaned_data['password']
            url = form.cleaned_data['satellite']
            URL = "https://"+url+"/rpc/api"
            env = form.cleaned_data['environment']
            #name = form.cleaned_data['hostname']
            client = xmlrpc.client.Server(URL, verbose=0)
            session = client.auth.login(user, pswd)
            #session = 'temp'
            #context = Satellite().getIds(request, client, session, env)
            host_list = Server.objects.all().filter(env=env).order_by('server')[:15]
            for host in host_list:
                servername = host.server
                if host.satid:
                    updates = []
                    satid = host.satid
                    client = xmlrpc.client.Server(URL, verbose=0)
                    erratas = client.system.getRelevantErrata(session,satid)
                    if erratas:
                        #TaskScripts().parseSatForm(servername, erratas)
                        for errata in erratas:
                            updates.append(errata['advisory_name']+' ')
                            Updates = ''.join(updates).strip()
                        #TaskScripts().parseSatForm(servername, Updates)
                        host.updates = Updates
                    else:
                        pass
                    host.save()
                else:
                    pass
                #context = {'getid': getid}
            client.auth.logout(session)
    else:
        pass
    return render_to_response('autopatch/patching-tasks.html', context,
                              context_instance=RequestContext(request))
Ejemplo n.º 13
0
def SatId(request):
    #SatId will get the ID of each server in Satellite
    #There are 4 buttons on the patching tasks page, one for each env
    context = {'encouragement': encouragement()}
    if request.POST:
        form = LoginForm(request.POST)
        TaskScripts().parseSatForm(request, form)
        if form.is_valid():
            user = form.cleaned_data['loginname']
            pswd = form.cleaned_data['password']
            url = form.cleaned_data['satellite']
            URL = "https://"+url+"/rpc/api"
            env = form.cleaned_data['environment']
            #name = form.cleaned_data['hostname']
            client = xmlrpc.client.Server(URL, verbose=0)
            session = client.auth.login(user, pswd)
            #session = 'temp'
            #context = Satellite().getIds(request, client, session, env)
            if(env=="dev"):
                dev_list = Server.objects.all().filter(env="dev").order_by('server')[:15]
                for host in dev_list:
                    servername = host.server
                    #print("Servername: ",servername)
                    client = xmlrpc.client.Server(URL, verbose=0)
                    data = client.system.getId(session, servername)
                    #TaskScripts().parseSatForm(servername, data)
                    if data:
                        getid = data[0].get('id')
                        host.satid = getid
                    else:
                        pass
                    host.save()
                    #context = {'getid': getid}
                client.auth.logout(session)
            if(env=="qa"):
                qa_list = Server.objects.all().filter(env="qa").order_by('server')[:15]
                for host in qa_list:
                    servername = host.server
                    #print("Servername: ",servername)
                    client = xmlrpc.client.Server(URL, verbose=0)
                    data = client.system.getId(session, servername)
                    #TaskScripts().parseSatForm(servername, data)
                    if data:
                        getid = data[0].get('id')
                        host.satid = getid
                    else:
                        pass
                    host.save()
                    #context = {'getid': getid}
                client.auth.logout(session)
            if(env=="stage"):
                stage_list = Server.objects.all().filter(env="stage").order_by('server')[:15]
                for host in stage_list:
                    servername = host.server
                    #print("Servername: ",servername)
                    client = xmlrpc.client.Server(URL, verbose=0)
                    data = client.system.getId(session, servername)
                    #TaskScripts().parseSatForm(servername, data)
                    if data:
                        getid = data[0].get('id')
                        host.satid = getid
                    else:
                        pass
                    host.save()
                    #context = {'getid': getid}
                client.auth.logout(session)
            if(env=="prod"):
                prod_list = Server.objects.all().filter(env="prod").order_by('server')[:15]
                for host in prod_list:
                    servername = host.server
                    #print("Servername: ",servername)
                    client = xmlrpc.client.Server(URL, verbose=0)
                    data = client.system.getId(session, servername)
                    #TaskScripts().parseSatForm(servername, data)
                    if data:
                        getid = data[0].get('id')
                        host.satid = getid
                    else:
                        pass
                    host.save()
                    #context = {'getid': getid}
                client.auth.logout(session)
    else:
        pass
    return render_to_response('autopatch/patching-tasks.html', context,
                              context_instance=RequestContext(request))
Ejemplo n.º 14
0
def StageView(request):
    stage_list = Server.objects.all().order_by('server')
    env = "Stage"
    field = ".stage."
    if Hosttotal.objects.filter(env=env).exists():
        h = Hosttotal.objects.get(env=env)
        stagetotal = h.total
    else:
        stagetotal = None
    if(request.GET.get('mybtn')):
        total = ModMaint().hostCount(env, field)
        stagetotal = total.get("total")
    context = {'stage_list': stage_list, 'total': stagetotal, 'env': env, 'encouragement': encouragement()}
    return render(request, 'autopatch/stage-servers.html', context)
Ejemplo n.º 15
0
def ProdView(request):
    prod_list = Server.objects.all().order_by('server')
    env = "Prod"
    field = ".prod."
    if Hosttotal.objects.filter(env=env).exists():
        h = Hosttotal.objects.get(env=env)
        prodtotal = h.total
    else:
        prodtotal = None
    if(request.GET.get('mybtn')):
        total = ModMaint().hostCount(env, field)
        prodtotal = total.get("total")
    context = {'prod_list': prod_list, 'total': prodtotal, 'env': env, 'encouragement': encouragement()}
    return render(request, 'autopatch/prod-servers.html', context)
Ejemplo n.º 16
0
 def get_context_data(self):
     return {'encouragement': encouragement()}
Ejemplo n.º 17
0
def ErrataPackages(request):
    # Get packages affected by an errata
    context = {"encouragement": encouragement()}
    if request.POST:
        form = LoginForm(request.POST)
        if form.is_valid():
            # TaskScripts().parseServerForm("The form is valid", "")
            # Get variables from the form
            user = form.cleaned_data["loginname"]
            pswd = form.cleaned_data["password"]
            url = form.cleaned_data["satellite"]
            URL = "https://" + url + "/rpc/api"
            env = form.cleaned_data["environment"]
            # using xmlrpc to get a session key from the satellite server
            client = xmlrpc.client.Server(URL, verbose=0)
            session = client.auth.login(user, pswd)
            # Get list of hosts in an env
            host_list = Server.objects.all().filter(env=env).order_by("server")
            # Loop through each host and get satellite ID
            client = xmlrpc.client.Server(URL, verbose=0)
            errata_dict = {}
            for host in host_list:
                servername = host.server
                # TaskScripts().parseServerForm("This is the Server's name", servername)
                try:
                    plerrata = host.plerrata.strip("{}").replace('"', "").replace(" ", "").split(",")
                    # TaskScripts().parseServerForm("The errata list is", plerrata)
                    for errata in plerrata:
                        # TaskScripts().parseServerForm(type(plerrata), plerrata)
                        packages = client.errata.listPackages(session, errata)
                        if packages:
                            errata_packages = []
                            for package in packages:
                                # TaskScripts().parseServerForm("This is a package name", package['name'])
                                if package["name"] not in errata_packages:
                                    errata_packages.append(package["name"])
                                    # TaskScripts().parseServerForm("Errata packages: ", errata_packages)
                                else:
                                    pass
                            if errata not in errata_dict:
                                errata_dict.update({errata: errata_packages})
                                # TaskScripts().parseServerForm("This errata not in errata_dict:", errata)
                            else:
                                # TaskScripts().parseServerForm("This errata is already in errata_dict:", errata)
                                pass
                            # TaskScripts().parseServerForm("This is the packages in the errata:", errata_packages)
                        else:
                            pass
                    # for each in Packages.objects.all().order_by('errata'):
                    #     TaskScripts().parseServerForm("The errata name", errata.errata)
                    #     TaskScripts().parseServerForm("The errata name", errata.pkgs)
                    # TaskScripts().parseServerForm("The errata dictionary", errata_dict)
                    # TaskScripts().parseServerForm("For host: ", host)
                except:
                    pass
                ModMaint().errataExcluded(host)
            client.auth.logout(session)
            # for errata in errata_dict:
            #     TaskScripts().parseServerForm(errata,errata_dict[errata])
            ModMaint().errataPackages(errata_dict)
            for host in host_list:
                ModMaint().errataExcluded(host)
    else:
        pass
    return HttpResponseRedirect(reverse("autopatch:tasks"), context)
Ejemplo n.º 18
0
def UpdateErrata(request):
    # This view used to update the top level errata
    args = {}
    args["encouragement"] = encouragement()
    if request.POST:
        form = ErrataForm(request.POST)
        if form.is_valid():
            new_erratas = {}
            # saving the errata levels entered in the form
            RHEA = form.data["RHEA"]
            RHSA = form.data["RHSA"]
            RHBA = form.data["RHBA"]
            oldrhea = ""
            oldrhsa = ""
            oldrhba = ""
            # TaskScripts().parseServerForm(RHEA, RHBA)
            # This keeps the exists errata levels set if none are entered in the form
            if not Errata.objects.exists():
                errata = Errata(pk=1)
            else:
                errata = Errata.objects.get(pk=1)
                oldrhea = errata.RHEA
                oldrhsa = errata.RHSA
                oldrhba = errata.RHBA
            errata_list = {"RHEA": RHEA, "RHSA": RHSA, "RHBA": RHBA}
            # checkErrata is a check for any clear returns to remove errata levels
            new_erratas = ModMaint().checkErrata(errata_list)
            # TaskScripts().parseServerForm('new errata', new_erratas)
            if new_erratas["RHEA"] == "clear":
                errata.RHEA = ""
            elif new_erratas["RHEA"]:
                errata.RHEA = RHEA
            elif oldrhea:
                errata.RHEA = oldrhea
            else:
                pass
            if new_erratas["RHSA"] == "clear":
                errata.RHSA = ""
            elif new_erratas["RHSA"]:
                errata.RHSA = RHSA
            elif oldrhsa:
                errata.RHSA = oldrhsa
            else:
                pass
            if new_erratas["RHBA"] == "clear":
                errata.RHBA = ""
            elif new_erratas["RHBA"]:
                errata.RHBA = RHBA
            elif oldrhba:
                errata.RHBA = oldrhba
            else:
                pass
            errata.save()
            # recalculates the desired errata for each host
            Satellite().recalcPlerrata()
            # if they exist then they are returned to the template
            if Errata.objects.exists():
                # errata = Errata.objects.first()
                errata = Errata.objects.first()
                args["RHEA"] = errata.RHEA
                args["RHSA"] = errata.RHSA
                args["RHBA"] = errata.RHBA
                # TaskScripts().parseServerForm('Errata does exist',errata)
            else:
                args["RHEA"] = ""
                args["RHSA"] = ""
                args["RHBA"] = ""
            args.update(csrf(request))
            return render(request, "autopatch/update_errata.html", args)
    else:
        form = ErrataForm()
    args.update(csrf(request))
    # Checking if errata levels exist
    # if they exist then they are returned to the template
    if Errata.objects.exists():
        # errata = Errata.objects.first()
        errata = Errata.objects.first()
        args["RHEA"] = errata.RHEA
        args["RHSA"] = errata.RHSA
        args["RHBA"] = errata.RHBA
        # TaskScripts().parseServerForm('Errata does exist',errata)
    else:
        args["RHEA"] = ""
        args["RHSA"] = ""
        args["RHBA"] = ""
        # TaskScripts().parseServerForm('Errata doesnt exist!','no errata')
    args["form"] = form
    return render_to_response("autopatch/update_errata.html", args)
Ejemplo n.º 19
0
 def get_context_data(self):
     return {"encouragement": encouragement()}
Ejemplo n.º 20
0
def Home(request):
    # /autopatch/ url
    template = "autopatch/base.html"
    context = {"encouragement": encouragement()}
    return render(request, template, context)
Ejemplo n.º 21
0
def denied(request):
    # if user isn't in the LDAP admin group that is required by some views
    template = "autopatch/denied.html"
    context = {"encouragement": encouragement()}
    return render_to_response(template, context)
Ejemplo n.º 22
0
def SatInfo(request):
    # SatId will get the ID and errata available for each server in Satellite
    # There are 4 buttons on the patching tasks page, one for each env
    context = {"encouragement": encouragement()}
    if request.POST:
        form = LoginForm(request.POST)
        if form.is_valid():
            # Get variables from the form
            user = form.cleaned_data["loginname"]
            pswd = form.cleaned_data["password"]
            url = form.cleaned_data["satellite"]
            URL = "https://" + url + "/rpc/api"
            env = form.cleaned_data["environment"]
            # using xmlrpc to get a session key from the satellite server
            client = xmlrpc.client.Server(URL, verbose=0)
            session = client.auth.login(user, pswd)
            # Get list of hosts in an env
            host_list = Server.objects.all().filter(env=env).order_by("server")
            # Loop through each host and get satellite ID
            client = xmlrpc.client.Server(URL, verbose=0)
            for host in host_list:
                servername = host.server
                # if not host.satid:
                data = client.system.getId(session, servername)
                if data:
                    getid = data[0].get("id")
                    host.satid = getid
                else:
                    pass
                # else:
                #     pass
                # If the host has a satid then check for avail updates
                if host.satid:
                    # TaskScripts().parseServerForm(host, host.satid)
                    updates = []
                    errata_list = client.system.getRelevantErrata(session, host.satid)
                    # If a list of errata is returned from satellite
                    if errata_list:
                        for erratum in errata_list:
                            updates.append(erratum["advisory_name"])
                            all_updates = updates
                        # compare with the set errata levels to get list of desired errata
                        needed_updates = Satellite().desiredErrata(all_updates)
                        if needed_updates:
                            host.plerrata = str(needed_updates).replace("'", '"')
                            host.uptodate = 0
                        else:
                            host.plerrata = None
                            host.uptodate = 1
                        # matching the format that is created by patchautomate.git's app.py
                        auto_format = str(all_updates).replace('"', "").replace("'", "").strip("[]").replace(" ", "")
                        host.updates = "{" + auto_format + "}"
                        if host.plerrata:
                            des_errata = host.plerrata[:20]
                        else:
                            des_errata = None
                        TaskScripts().parseServerForm(host, des_errata)
                        host.save()
                    else:
                        # found no available errata so making sure none is in the db
                        host.updates = ""
                        host.plerrata = None
                        host.uptodate = 1
                        TaskScripts().parseServerForm("This host is up-to-date:", host)
                        host.save()
                else:
                    # found no Sat ID so no errata in db for the host
                    host.updates = ""
                    host.plerrata = None
                    host.uptodate = 1
                    host.save()
                    TaskScripts().parseServerForm(host, "Does not have a SatID!")
                    pass
            TaskScripts().parseServerForm("All done, logging out", "")
            client.auth.logout(session)
    else:
        pass
    return HttpResponseRedirect(reverse("autopatch:tasks"), context)
Ejemplo n.º 23
0
def Home(request):
    template = 'autopatch/base.html'
    context = {'encouragement': encouragement()}
    return render(request, template, context)
Ejemplo n.º 24
0
def ChangesView(request):
    changes_list = Audit.objects.all().order_by("mod_date")
    context = {"changes_list": changes_list, "encouragement": encouragement()}
    return render(request, "autopatch/changes_list.html", context)