Esempio n. 1
0
def isolate(request, instance):
    if request.user.is_superuser or request.user.has_perm("ganeti.view_instances"):
        if instance:
            try:
                instance = Instance.objects.get(name=instance)
            except ObjectDoesNotExist:
                raise Http404
        instance_isolate = instance.isolate
        if request.method == "POST":
            form = isolateForm(request.POST)
            if form.is_valid():
                isolate = form.cleaned_data["isolate"]
                if isolate:
                    auditlog = auditlog_entry(request, "Isolate", instance, instance.cluster.slug)
                    jobid = instance.cluster.tag_instance(instance.name, ["%s:isolate" % settings.GANETI_TAG_PREFIX])
                    auditlog.update(job_id=jobid)
                    instance.cluster.migrate_instance(instance.name)
                if not isolate:
                    auditlog = auditlog_entry(request, "De-Isolate", instance, instance.cluster.slug)
                    jobid = instance.cluster.untag_instance(instance.name, ["%s:isolate" % settings.GANETI_TAG_PREFIX])
                    auditlog.update(job_id=jobid)
                    instance.cluster.migrate_instance(instance.name)
                res = {"result": "success"}
                return HttpResponse(json.dumps(res), mimetype="application/json")
            else:
                return render(request, "tagging/isolate.html", {"form": form, "instance": instance})
        elif request.method == "GET":
            form = isolateForm(initial={"isolate": instance_isolate})
            return render(request, "tagging/isolate.html", {"form": form, "instance": instance})
    else:
        return HttpResponseRedirect(reverse("user-instances"))
Esempio n. 2
0
def lock(request, instance):
    if request.user.is_superuser or request.user.has_perm("ganeti.view_instances"):
        if instance:
            try:
                instance = Instance.objects.get(name=instance)
            except ObjectDoesNotExist:
                raise Http404()
        instance_adminlock = instance.adminlock
        if request.method == "POST":
            form = lockForm(request.POST)
            if form.is_valid():
                adminlock = form.cleaned_data["lock"]
                if adminlock:
                    auditlog = auditlog_entry(request, "Lock Instance", instance, instance.cluster.slug)
                    # set the cache for a week
                    cache.set("instances:%s" % (instance.name), True, 60 * 60 * 24 * 7)
                    jobid = instance.cluster.tag_instance(instance.name, ["%s:adminlock" % settings.GANETI_TAG_PREFIX])
                    auditlog.update(job_id=jobid)
                if adminlock is False:
                    cache.delete("instances:%s" % (instance.name))
                    auditlog = auditlog_entry(request, "Unlock Instance", instance, instance.cluster.slug)
                    jobid = instance.cluster.untag_instance(
                        instance.name, ["%s:adminlock" % settings.GANETI_TAG_PREFIX]
                    )
                    auditlog.update(job_id=jobid)
                res = {"result": "success"}
                return HttpResponse(json.dumps(res), mimetype="application/json")
            else:
                return render(request, "tagging/lock.html", {"form": form, "instance": instance})
        elif request.method == "GET":
            form = lockForm(initial={"lock": instance_adminlock})
            return render(request, "tagging/lock.html", {"form": form, "instance": instance})
    else:
        return HttpResponseRedirect(reverse("user-instances"))
Esempio n. 3
0
    def test_auditlog_view(self):
        # dont allow access in unauthorized users
        res = self.client.get(reverse('auditlog'))
        self.assertEqual(res.status_code, 302)

        # users have access to their logs
        self.client.login(username='******', password='******')
        res = self.client.get(reverse('auditlog'))
        self.assertEqual(res.status_code, 200)

        res = self.client.get(reverse('auditlog_json'))
        self.assertEqual(res.status_code, 200)

        # admin users have access
        self.client.login(username='******', password='******')
        res = self.client.get(reverse('auditlog'))
        self.assertEqual(res.status_code, 200)

        res = self.client.get(reverse('auditlog_json'))
        self.assertEqual(res.status_code, 200)

        # the response should be empty
        response = json.loads(res.content)
        self.assertEqual(len(response['aaData']), 0)

        # lets create an audit entry
        # shudtdown instance 'test'
        # user = audittestadmin
        request = self.factory.get(reverse('auditlog_json'))
        request.user = self.superuser
        entry = auditlog_entry(request, "Shutdown", 'test', 'test')

        # get again the auditlog
        res = self.client.get(reverse('auditlog_json'))
        self.assertEqual(res.status_code, 200)
        response = json.loads(res.content)
        self.assertEqual(response['aaData'][0]['user'], entry.requester.username)

        # the response should not be empty this time
        response = json.loads(res.content)
        self.assertEqual(len(response['aaData']), 1)

        # do it again as a simple user
        # should not see anything
        self.client.login(username='******', password='******')

        res = self.client.get(reverse('auditlog_json'))
        self.assertEqual(res.status_code, 200)
        response = json.loads(res.content)

        # the response should be empty for a simple user
        response = json.loads(res.content)
        self.assertEqual(len(response['aaData']), 0)

        # but it sould have an entry for the superuser
        self.client.login(username='******', password='******')
        res = self.client.get(reverse('auditlog_json'))
        self.assertEqual(res.status_code, 200)
        response = json.loads(res.content)
        self.assertEqual(len(response['aaData']), 1)
Esempio n. 4
0
def lock(request, instance):
    if (request.user.is_superuser
            or request.user.has_perm('ganeti.view_instances')):
        if instance:
            try:
                instance = Instance.objects.get(name=instance)
            except ObjectDoesNotExist:
                raise Http404()
        instance_adminlock = instance.adminlock
        if request.method == 'POST':
            form = lockForm(request.POST)
            if form.is_valid():
                adminlock = form.cleaned_data['lock']
                if adminlock:
                    auditlog = auditlog_entry(request, "Lock Instance",
                                              instance, instance.cluster.slug)
                    # set the cache for a week
                    cache.set('instances:%s' % (instance.name), True,
                              60 * 60 * 24 * 7)
                    jobid = instance.cluster.tag_instance(
                        instance.name,
                        ["%s:adminlock" % settings.GANETI_TAG_PREFIX])
                    auditlog.update(job_id=jobid)
                if adminlock is False:
                    cache.delete('instances:%s' % (instance.name))
                    auditlog = auditlog_entry(request, "Unlock Instance",
                                              instance, instance.cluster.slug)
                    jobid = instance.cluster.untag_instance(
                        instance.name,
                        ["%s:adminlock" % settings.GANETI_TAG_PREFIX])
                    auditlog.update(job_id=jobid)
                res = {'result': 'success'}
                return HttpResponse(json.dumps(res),
                                    content_type='application/json')
            else:
                return render(request, 'tagging/lock.html', {
                    'form': form,
                    'instance': instance
                })
        elif request.method == 'GET':
            form = lockForm(initial={'lock': instance_adminlock})
            return render(request, 'tagging/lock.html', {
                'form': form,
                'instance': instance
            })
    else:
        return HttpResponseRedirect(reverse('user-instances'))
Esempio n. 5
0
def reboot(request, cluster_slug, instance):
    cluster = get_object_or_404(Cluster, slug=cluster_slug)
    auditlog = auditlog_entry(request, "Reboot", instance, cluster_slug)
    jobid = cluster.reboot_instance(instance)
    auditlog.update(job_id=jobid)
    action = {'action': _("Please wait... rebooting")}
    clear_cluster_user_cache(request.user.username, cluster_slug)
    return HttpResponse(json.dumps(action))
Esempio n. 6
0
def startup(request, cluster_slug, instance):
    cluster = get_object_or_404(Cluster, slug=cluster_slug)
    auditlog = auditlog_entry(request, 'Start', instance, cluster_slug)
    jobid = cluster.startup_instance(instance)
    auditlog.update(job_id=jobid)
    action = {'action': _('Please wait... starting-up')}
    clear_cluster_user_cache(request.user.username, cluster_slug)
    return HttpResponse(json.dumps(action))
Esempio n. 7
0
def reboot(request, cluster_slug, instance):
    cluster = get_object_or_404(Cluster, slug=cluster_slug)
    auditlog = auditlog_entry(request, "Reboot", instance, cluster_slug)
    jobid = cluster.reboot_instance(instance)
    auditlog.update(job_id=jobid)
    action = {"action": _("Please wait... rebooting")}
    clear_cluster_user_cache(request.user.username, cluster_slug)
    return HttpResponse(json.dumps(action))
Esempio n. 8
0
def isolate(request, instance):
    if (request.user.is_superuser
            or request.user.has_perm('ganeti.view_instances')):
        if instance:
            try:
                instance = Instance.objects.get(name=instance)
            except ObjectDoesNotExist:
                raise Http404
        instance_isolate = instance.isolate
        if request.method == 'POST':
            form = isolateForm(request.POST)
            if form.is_valid():
                isolate = form.cleaned_data['isolate']
                if isolate:
                    auditlog = auditlog_entry(request, "Isolate", instance,
                                              instance.cluster.slug)
                    jobid = instance.cluster.tag_instance(
                        instance.name,
                        ["%s:isolate" % settings.GANETI_TAG_PREFIX])
                    auditlog.update(job_id=jobid)
                    instance.cluster.migrate_instance(instance.name)
                if not isolate:
                    auditlog = auditlog_entry(request, "De-Isolate", instance,
                                              instance.cluster.slug)
                    jobid = instance.cluster.untag_instance(
                        instance.name,
                        ["%s:isolate" % settings.GANETI_TAG_PREFIX])
                    auditlog.update(job_id=jobid)
                    instance.cluster.migrate_instance(instance.name)
                res = {'result': 'success'}
                return HttpResponse(json.dumps(res),
                                    content_type='application/json')
            else:
                return render(request, 'tagging/isolate.html', {
                    'form': form,
                    'instance': instance
                })
        elif request.method == 'GET':
            form = isolateForm(initial={'isolate': instance_isolate})
            return render(request, 'tagging/isolate.html', {
                'form': form,
                'instance': instance
            })
    else:
        return HttpResponseRedirect(reverse('user-instances'))
Esempio n. 9
0
def startup(request, cluster_slug, instance):
    cluster = get_object_or_404(Cluster, slug=cluster_slug)
    auditlog = auditlog_entry(request, 'Start', instance, cluster_slug)
    jobid = cluster.startup_instance(instance)
    auditlog.update(job_id=jobid)
    action = {
        'action': _('Please wait... starting-up')
    }
    clear_cluster_user_cache(request.user.username, cluster_slug)
    return HttpResponse(json.dumps(action))
Esempio n. 10
0
def reinstalldestreview(request, application_hash, action_id):
    action_id = int(action_id)
    instance = None
    if action_id not in [1, 2, 3, 4]:
        return HttpResponseRedirect(reverse('user-instances'))
    # Normalize before trying anything with it.
    activation_key = application_hash.lower()
    try:
        action = InstanceAction.objects.get(
            activation_key=activation_key,
            action=action_id
        )
    except InstanceAction.DoesNotExist:
        activated = True
        return render(
            request,
            'instances/verify_action.html',
            {
                'action': action_id,
                'activated': activated,
                'instance': instance,
                'hash': application_hash
            }
        )
    if action_id == 4:
        instance_action = InstanceAction.objects.activate_request(
            application_hash
        )
        user = User.objects.get(username=request.user)
        user.email = action.action_value
        user.save()
        messages.add_message(
            request,
            messages.INFO,
            _('Mail changed succesfully.')
        )
        return HttpResponseRedirect(reverse('profile'))
    instance = action.instance
    cluster = action.cluster
    if not request.user.userprofile.is_owner(cluster.get_instance(instance)):
        action = ''
        if action_id is 1:
            action = 'reinstall'
        elif action_id is 3:
            action = 'rename'
        elif action_id is 2:
            action = 'destroy'
        auditlog_entry(request, 'Unauthorized ' + action + ' attempt',
                       instance, cluster.slug, True, False)
        mail_unauthorized_action(
            action, instance, request.user.userprofile.user.username
        )
        raise PermissionDenied
    action_value = action.action_value
    activated = False
    try:
        instance_object = Instance.objects.get(name=instance)
    except:
        # This should occur only when user changes email
        pass
    if action.activation_key_expired():
        activated = True
    if request.method == 'POST':
        if not activated:
            instance_action = InstanceAction.objects.activate_request(
                application_hash
            )
            if not instance_action:
                return render(
                    request,
                    'instances/verify_action.html',
                    {
                        'action': action_id,
                        'activated': activated,
                        'instance': instance,
                        'hash': application_hash
                    }
                )
            if action_id in [1, 2, 3]:
                auditlog = auditlog_entry(request, "", instance, cluster.slug, save=False)
            if action_id == 1:
                auditlog.update(action="Reinstall")
                jobid = cluster.reinstall_instance(instance, instance_action)
                # in case there is no selected os
                if jobid:
                    auditlog.update(job_id=jobid)
                else:
                    return HttpResponseServerError()
            if action_id == 2:
                auditlog.update(action="Destroy")
                jobid = cluster.destroy_instance(instance)
                auditlog.update(job_id=jobid)
            if action_id == 3:
                # As rename causes cluster lock we perform some cache
                # engineering on the cluster instances,
                # nodes and the users cache
                refresh_cluster_cache(cluster, instance)
                auditlog.update(action="Rename to %s" % action_value)
                jobid = cluster.rename_instance(instance, action_value)
                auditlog.update(job_id=jobid)
            activated = True
            return HttpResponseRedirect(reverse('user-instances'))
        else:
            return render(
                request,
                'instances/verify_action.html',
                {
                    'action': action_id,
                    'activated': activated,
                    'instance': instance,
                    'instance_object': instance_object,
                    'hash': application_hash
                }
            )
    elif request.method == 'GET':
        return render(
            request,
            'instances/verify_action.html',
            {
                'instance': instance,
                'instance_object': instance_object,
                'action': action_id,
                'action_value': action_value,
                'cluster': cluster,
                'activated': activated,
                'hash': application_hash
            }
        )
    else:
        return HttpResponseRedirect(reverse('user-instances'))
Esempio n. 11
0
def instance(request, cluster_slug, instance):
    cluster = get_object_or_404(Cluster, slug=cluster_slug)
    instance = cluster.get_instance_or_404(instance)
    if request.method == 'POST':
        configform = InstanceConfigForm(request.POST)
        if configform.is_valid():
            needs_reboot = False
            # The instance needs reboot if any of the hvparams have changed.
            if configform.cleaned_data['cdrom_type'] == 'none':
                configform.cleaned_data['cdrom_image_path'] = ""
            for key, val in configform.cleaned_data.items():
                if key == "cdrom_type":
                    continue
                if key == "whitelist_ip":
                    continue
                if configform.cleaned_data[key] != instance.hvparams[key]:
                    if instance.admin_state:
                        needs_reboot = True
            if configform.cleaned_data['cdrom_type'] == 'none':
                configform.cleaned_data['cdrom_image_path'] = ""
            elif (configform.cleaned_data['cdrom_image_path'] !=
                  instance.hvparams['cdrom_image_path']):
                # This should be an http URL
                if (not (
                        configform.cleaned_data['cdrom_image_path'].startswith(
                            'http://') or configform.
                        cleaned_data['cdrom_image_path'].startswith('https://')
                        or configform.cleaned_data['cdrom_image_path'] == "")):
                    # Remove this, we don't want them to
                    # be able to read local files
                    del configform.cleaned_data['cdrom_image_path']
            data = {}
            whitelistip = None
            for key, val in configform.cleaned_data.items():
                if key == "cdrom_type":
                    continue
                if key == "whitelist_ip":
                    whitelistip = val
                    if len(val) == 0:
                        whitelistip = None
                    continue
                data[key] = val
            auditlog = auditlog_entry(
                request, "Setting %s" % (", ".join(
                    ["%s:%s" % (key, value) for key, value in data.items()])),
                instance, cluster_slug)
            jobid = instance.set_params(hvparams=data)
            auditlog.update(job_id=jobid)
            if needs_reboot:
                instance.cluster.tag_instance(
                    instance.name,
                    ["%s:needsreboot" % (settings.GANETI_TAG_PREFIX)])
            if instance.whitelistip and whitelistip is None:
                auditlog = auditlog_entry(
                    request, "Remove whitelist %s" % instance.whitelistip,
                    instance, cluster_slug)
                jobid = instance.cluster.untag_instance(
                    instance.name, [
                        "%s:whitelist_ip:%s" %
                        (settings.GANETI_TAG_PREFIX, instance.whitelistip)
                    ])
                auditlog.update(job_id=jobid)
                instance.cluster.migrate_instance(instance.name)
            if whitelistip:
                if instance.whitelistip:
                    auditlog = auditlog_entry(
                        request, "Remove whitelist %s" % instance.whitelistip,
                        instance, cluster_slug)
                    jobid = instance.cluster.untag_instance(
                        instance.name, [
                            "%s:whitelist_ip:%s" %
                            (settings.GANETI_TAG_PREFIX, instance.whitelistip)
                        ])
                    auditlog.update(job_id=jobid)
                auditlog = auditlog_entry(request,
                                          "Add whitelist %s" % whitelistip,
                                          instance, cluster_slug)
                jobid = instance.cluster.tag_instance(instance.name, [
                    "%s:whitelist_ip:%s" %
                    (settings.GANETI_TAG_PREFIX, whitelistip)
                ])
                auditlog.update(job_id=jobid)
                instance.cluster.migrate_instance(instance.name)
            # Prevent form re-submission via browser refresh
            return HttpResponseRedirect(
                reverse('instance-detail',
                        kwargs={
                            'cluster_slug': cluster_slug,
                            'instance': instance
                        }))
    else:
        if 'cdrom_image_path' in instance.hvparams:
            if instance.hvparams['cdrom_image_path']:
                instance.hvparams['cdrom_type'] = 'iso'
            else:
                instance.hvparams['cdrom_type'] = 'none'
        else:
            instance.hvparams['cdrom_type'] = 'none'
        if instance.whitelistip:
            instance.hvparams['whitelist_ip'] = instance.whitelistip
        else:
            instance.hvparams['whitelist_ip'] = ''
        configform = InstanceConfigForm(instance.hvparams)
    instance.cpu_url = reverse('graph',
                               args=(cluster.slug, instance.name, 'cpu-ts'))
    instance.net_url = []
    for (nic_i, link) in enumerate(instance.nic_links):
        instance.net_url.append(
            reverse('graph',
                    args=(cluster.slug, instance.name, 'net-ts',
                          '/eth%s' % nic_i)))

    instance.netw = []
    try:
        instance.osname = get_os_details(instance.osparams['img_id']).get(
            'description', instance.osparams['img_id'])
    except Exception:
        try:
            instance.osname = instance.osparams['img_id']
        except Exception:
            instance.osname = instance.os
    instance.node_group_locked = instance.pnode in instance.cluster.locked_nodes_from_nodegroup(
    )
    for (nic_i, link) in enumerate(instance.nic_links):
        if instance.nic_ips[nic_i] is None:
            instance.netw.append("%s" % (instance.nic_links[nic_i]))
        else:
            instance.netw.append(
                "%s@%s" % (instance.nic_ips[nic_i], instance.nic_links[nic_i]))
    if instance.isolate and instance.whitelistip is None:

        djmessages.add_message(
            request, msgs.ERROR,
            "Your instance is isolated from the network and" +
            " you have not set an \"Allowed From\" address." +
            " To access your instance from a specific network range," +
            " you can set it via the instance configuration form")
    if instance.needsreboot:
        djmessages.add_message(
            request,
            msgs.ERROR,
            "You have modified one or more of your instance's core " +
            "configuration components  (any of network adapter, hard" +
            " disk type, boot device, cdrom). In order for these changes " +
            "to take effect, you need to <strong>Reboot</strong>" +
            " your instance.",
            extra_tags='safe')
    ret_dict = {'cluster': cluster, 'instance': instance}
    if not request.user.has_perm('ganeti.view_instances') or (
            request.user.is_superuser or request.user in instance.users
            or set.intersection(set(request.user.groups.all()),
                                set(instance.groups))):
        ret_dict['configform'] = configform
    return render(request, 'instances/instance.html', ret_dict)
Esempio n. 12
0
def reinstalldestreview(request, application_hash, action_id):
    action_id = int(action_id)
    instance = None
    if action_id not in [1, 2, 3, 4]:
        return HttpResponseRedirect(reverse('user-instances'))
    # Normalize before trying anything with it.
    activation_key = application_hash.lower()
    try:
        action = InstanceAction.objects.get(
            activation_key=activation_key,
            action=action_id
        )
    except InstanceAction.DoesNotExist:
        activated = True
        return render(
            request,
            'instances/verify_action.html',
            {
                'action': action_id,
                'activated': activated,
                'instance': instance,
                'hash': application_hash
            }
        )
    if action_id == 4:
        instance_action = InstanceAction.objects.activate_request(
            application_hash
        )
        user = User.objects.get(username=request.user)
        user.email = action.action_value
        user.save()
        messages.add_message(
            request,
            messages.INFO,
            _('Mail changed succesfully.')
        )
        return HttpResponseRedirect(reverse('profile'))
    instance = action.instance
    cluster = action.cluster
    if not request.user.userprofile.is_owner(cluster.get_instance(instance)):
        action = ''
        if action_id is 1:
            action = 'reinstall'
        elif action_id is 3:
            action = 'rename'
        elif action_id is 2:
            action = 'destroy'
        auditlog_entry(request, 'Unauthorized ' + action + ' attempt',
                       instance, cluster.slug, True, False)
        mail_unauthorized_action(
            action, instance, request.user.userprofile.user.username
        )
        raise PermissionDenied
    action_value = action.action_value
    activated = False
    try:
        instance_object = Instance.objects.get(name=instance)
    except:
        # This should occur only when user changes email
        pass
    if action.activation_key_expired():
        activated = True
    if request.method == 'POST':
        if not activated:
            instance_action = InstanceAction.objects.activate_request(
                application_hash
            )
            if not instance_action:
                return render(
                    request,
                    'instances/verify_action.html',
                    {
                        'action': action_id,
                        'activated': activated,
                        'instance': instance,
                        'hash': application_hash
                    }
                )
            if action_id in [1, 2, 3]:
                auditlog = auditlog_entry(request, "", instance, cluster.slug, save=False)
            if action_id == 1:
                auditlog.update(action="Reinstall")
                jobid = cluster.reinstall_instance(instance, instance_action)
                # in case there is no selected os
                if jobid:
                    auditlog.update(job_id=jobid)
                else:
                    return HttpResponseServerError()
            if action_id == 2:
                auditlog.update(action="Destroy")
                jobid = cluster.destroy_instance(instance)
                auditlog.update(job_id=jobid)
            if action_id == 3:
                # As rename causes cluster lock we perform some cache
                # engineering on the cluster instances,
                # nodes and the users cache
                refresh_cluster_cache(cluster, instance)
                auditlog.update(action="Rename to %s" % action_value)
                jobid = cluster.rename_instance(instance, action_value)
                auditlog.update(job_id=jobid)
            activated = True
            return HttpResponseRedirect(reverse('user-instances'))
        else:
            return render(
                request,
                'instances/verify_action.html',
                {
                    'action': action_id,
                    'activated': activated,
                    'instance': instance,
                    'instance_object': instance_object,
                    'hash': application_hash
                }
            )
    elif request.method == 'GET':
        return render(
            request,
            'instances/verify_action.html',
            {
                'instance': instance,
                'instance_object': instance_object,
                'action': action_id,
                'action_value': action_value,
                'cluster': cluster,
                'activated': activated,
                'hash': application_hash
            }
        )
    else:
        return HttpResponseRedirect(reverse('user-instances'))
Esempio n. 13
0
def isolate(request, instance):
    if (
        request.user.is_superuser or
        request.user.has_perm('ganeti.view_instances')
    ):
        if instance:
            try:
                instance = Instance.objects.get(name=instance)
            except ObjectDoesNotExist:
                raise Http404
        instance_isolate = instance.isolate
        if request.method == 'POST':
            form = isolateForm(request.POST)
            if form.is_valid():
                isolate = form.cleaned_data['isolate']
                if isolate:
                    auditlog = auditlog_entry(
                        request,
                        "Isolate",
                        instance,
                        instance.cluster.slug
                    )
                    jobid = instance.cluster.tag_instance(
                        instance.name,
                        ["%s:isolate" % settings.GANETI_TAG_PREFIX]
                    )
                    auditlog.update(job_id=jobid)
                    instance.cluster.migrate_instance(instance.name)
                if not isolate:
                    auditlog = auditlog_entry(
                        request,
                        "De-Isolate",
                        instance,
                        instance.cluster.slug
                    )
                    jobid = instance.cluster.untag_instance(
                        instance.name,
                        ["%s:isolate" % settings.GANETI_TAG_PREFIX]
                    )
                    auditlog.update(job_id=jobid)
                    instance.cluster.migrate_instance(instance.name)
                res = {'result': 'success'}
                return HttpResponse(
                    json.dumps(res), content_type='application/json'
                )
            else:
                return render(
                    request,
                    'tagging/isolate.html',
                    {
                        'form': form,
                        'instance': instance
                    }
                )
        elif request.method == 'GET':
            form = isolateForm(initial={'isolate': instance_isolate})
            return render(
                request,
                'tagging/isolate.html',
                {
                    'form': form,
                    'instance': instance
                }
            )
    else:
        return HttpResponseRedirect(reverse('user-instances'))
Esempio n. 14
0
def lock(request, instance):
    if (
        request.user.is_superuser or
        request.user.has_perm('ganeti.view_instances')
    ):
        if instance:
            try:
                instance = Instance.objects.get(name=instance)
            except ObjectDoesNotExist:
                raise Http404()
        instance_adminlock = instance.adminlock
        if request.method == 'POST':
            form = lockForm(request.POST)
            if form.is_valid():
                adminlock = form.cleaned_data['lock']
                if adminlock:
                    auditlog = auditlog_entry(
                        request,
                        "Lock Instance",
                        instance, instance.cluster.slug
                    )
                    # set the cache for a week
                    cache.set('instances:%s' % (instance.name), True, 60 * 60 * 24 * 7)
                    jobid = instance.cluster.tag_instance(
                        instance.name,
                        ["%s:adminlock" % settings.GANETI_TAG_PREFIX]
                    )
                    auditlog.update(job_id=jobid)
                if adminlock is False:
                    cache.delete('instances:%s' % (instance.name))
                    auditlog = auditlog_entry(
                        request,
                        "Unlock Instance",
                        instance,
                        instance.cluster.slug
                    )
                    jobid = instance.cluster.untag_instance(
                        instance.name,
                        ["%s:adminlock" % settings.GANETI_TAG_PREFIX]
                    )
                    auditlog.update(job_id=jobid)
                res = {
                    'result': 'success'
                }
                return HttpResponse(json.dumps(res), content_type='application/json')
            else:
                return render(
                    request,
                    'tagging/lock.html',
                    {
                        'form': form,
                        'instance': instance
                    }
                )
        elif request.method == 'GET':
            form = lockForm(initial={'lock': instance_adminlock})
            return render(
                request,
                'tagging/lock.html',
                {
                    'form': form,
                    'instance': instance
                }
            )
    else:
        return HttpResponseRedirect(reverse('user-instances'))
Esempio n. 15
0
def instance(request, cluster_slug, instance):
    cluster = get_object_or_404(Cluster, slug=cluster_slug)
    instance = cluster.get_instance_or_404(instance)
    if request.method == 'POST':
        configform = InstanceConfigForm(request.POST)
        if configform.is_valid():
            needs_reboot = False
            # The instance needs reboot if any of the hvparams have changed.
            if configform.cleaned_data['cdrom_type'] == 'none':
                configform.cleaned_data['cdrom_image_path'] = ""
            for key, val in configform.cleaned_data.items():
                if key == "cdrom_type":
                    continue
                if key == "whitelist_ip":
                    continue
                if configform.cleaned_data[key] != instance.hvparams[key]:
                    if instance.admin_state:
                        needs_reboot = True
            if configform.cleaned_data['cdrom_type'] == 'none':
                configform.cleaned_data['cdrom_image_path'] = ""
            elif (configform.cleaned_data['cdrom_image_path'] !=
                  instance.hvparams['cdrom_image_path']):
                # This should be an http URL
                if (
                    not (
                        configform.cleaned_data['cdrom_image_path'].startswith(
                            'http://'
                        ) or
                        configform.cleaned_data['cdrom_image_path'].startswith(
                            'https://'
                        ) or
                        configform.cleaned_data['cdrom_image_path'] == ""
                    )
                ):
                    # Remove this, we don't want them to
                    # be able to read local files
                    del configform.cleaned_data['cdrom_image_path']
            data = {}
            whitelistip = None
            for key, val in configform.cleaned_data.items():
                if key == "cdrom_type":
                    continue
                if key == "whitelist_ip":
                    whitelistip = val
                    if len(val) == 0:
                        whitelistip = None
                    continue
                data[key] = val
            auditlog = auditlog_entry(
                request,
                "Setting %s" % (
                    ", ".join(
                        [
                            "%s:%s" % (key, value) for key, value in data.iteritems()
                        ]
                    )
                ),
                instance,
                cluster_slug
            )
            jobid = instance.set_params(hvparams=data)
            auditlog.update(job_id=jobid)
            if needs_reboot:
                instance.cluster.tag_instance(
                    instance.name,
                    ["%s:needsreboot" % (settings.GANETI_TAG_PREFIX)]
                )
            if instance.whitelistip and whitelistip is None:
                auditlog = auditlog_entry(
                    request,
                    "Remove whitelist %s" % instance.whitelistip,
                    instance,
                    cluster_slug
                )
                jobid = instance.cluster.untag_instance(
                    instance.name,
                    ["%s:whitelist_ip:%s" % (
                        settings.GANETI_TAG_PREFIX,
                        instance.whitelistip
                    )]
                )
                auditlog.update(job_id=jobid)
                instance.cluster.migrate_instance(instance.name)
            if whitelistip:
                if instance.whitelistip:
                    auditlog = auditlog_entry(
                        request,
                        "Remove whitelist %s" % instance.whitelistip,
                        instance,
                        cluster_slug
                    )
                    jobid = instance.cluster.untag_instance(
                        instance.name,
                        ["%s:whitelist_ip:%s" % (
                            settings.GANETI_TAG_PREFIX,
                            instance.whitelistip
                        )])
                    auditlog.update(job_id=jobid)
                auditlog = auditlog_entry(
                    request,
                    "Add whitelist %s" % whitelistip, instance, cluster_slug
                )
                jobid = instance.cluster.tag_instance(
                    instance.name,
                    ["%s:whitelist_ip:%s" % (settings.GANETI_TAG_PREFIX, whitelistip)]
                )
                auditlog.update(job_id=jobid)
                instance.cluster.migrate_instance(instance.name)
            # Prevent form re-submission via browser refresh
            return HttpResponseRedirect(
                reverse(
                    'instance-detail',
                    kwargs={'cluster_slug': cluster_slug, 'instance': instance}
                )
            )
    else:
        if 'cdrom_image_path' in instance.hvparams.keys():
            if instance.hvparams['cdrom_image_path']:
                instance.hvparams['cdrom_type'] = 'iso'
            else:
                instance.hvparams['cdrom_type'] = 'none'
        else:
            instance.hvparams['cdrom_type'] = 'none'
        if instance.whitelistip:
            instance.hvparams['whitelist_ip'] = instance.whitelistip
        else:
            instance.hvparams['whitelist_ip'] = ''
        configform = InstanceConfigForm(instance.hvparams)
    instance.cpu_url = reverse(
        'graph',
        args=(cluster.slug, instance.name, 'cpu-ts')
    )
    instance.net_url = []
    for (nic_i, link) in enumerate(instance.nic_links):
        instance.net_url.append(
            reverse(
                'graph',
                args=(cluster.slug, instance.name, 'net-ts', '/eth%s' % nic_i)
            )
        )

    instance.netw = []
    try:
        instance.osname = get_os_details(
            instance.osparams['img_id']).get(
            'description', instance.osparams['img_id']
        )
    except Exception:
        try:
            instance.osname = instance.osparams['img_id']
        except Exception:
            instance.osname = instance.os
    instance.node_group_locked = instance.pnode in instance.cluster.locked_nodes_from_nodegroup()
    for (nic_i, link) in enumerate(instance.nic_links):
        if instance.nic_ips[nic_i] is None:
            instance.netw.append("%s" % (instance.nic_links[nic_i]))
        else:
            instance.netw.append("%s@%s" % (
                instance.nic_ips[nic_i], instance.nic_links[nic_i])
            )
    if instance.isolate and instance.whitelistip is None:

        djmessages.add_message(
            request,
            msgs.ERROR,
            "Your instance is isolated from the network and" +
            " you have not set an \"Allowed From\" address." +
            " To access your instance from a specific network range," +
            " you can set it via the instance configuration form"
        )
    if instance.needsreboot:
        djmessages.add_message(
            request,
            msgs.ERROR,
            "You have modified one or more of your instance's core " +
            "configuration components  (any of network adapter, hard" +
            " disk type, boot device, cdrom). In order for these changes " +
            "to take effect, you need to <strong>Reboot</strong>" +
            " your instance.",
            extra_tags='safe'
        )
    ret_dict = {'cluster': cluster,
                'instance': instance
                }
    if not request.user.has_perm('ganeti.view_instances') or (
        request.user.is_superuser or
        request.user in instance.users or
        set.intersection(set(request.user.groups.all()), set(instance.groups))
    ):
            ret_dict['configform'] = configform
    return render(
        request,
        'instances/instance.html',
        ret_dict
    )
Esempio n. 16
0
    def test_auditlog_view(self):
        # dont allow access in unauthorized users
        res = self.client.get(reverse('auditlog'))
        self.assertEqual(res.status_code, 302)

        # users have access to their logs
        self.client.login(username='******', password='******')
        res = self.client.get(reverse('auditlog'))
        self.assertEqual(res.status_code, 200)

        res = self.client.get(reverse('auditlog_json'))
        self.assertEqual(res.status_code, 200)

        # admin users have access
        self.client.login(username='******', password='******')
        res = self.client.get(reverse('auditlog'))
        self.assertEqual(res.status_code, 200)

        res = self.client.get(reverse('auditlog_json'))
        self.assertEqual(res.status_code, 200)

        # the response should be empty
        response = json.loads(res.content)
        self.assertEqual(len(response['aaData']), 0)

        # lets create an audit entry
        # shudtdown instance 'test'
        # user = audittestadmin
        request = self.factory.get(reverse('auditlog_json'))
        request.user = self.superuser
        entry = auditlog_entry(request, "Shutdown", 'test', 'test')

        # get again the auditlog
        res = self.client.get(reverse('auditlog_json'))
        self.assertEqual(res.status_code, 200)
        response = json.loads(res.content)
        self.assertEqual(response['aaData'][0]['user'],
                         entry.requester.username)

        # the response should not be empty this time
        response = json.loads(res.content)
        self.assertEqual(len(response['aaData']), 1)

        # do it again as a simple user
        # should not see anything
        self.client.login(username='******', password='******')

        res = self.client.get(reverse('auditlog_json'))
        self.assertEqual(res.status_code, 200)
        response = json.loads(res.content)

        # the response should be empty for a simple user
        response = json.loads(res.content)
        self.assertEqual(len(response['aaData']), 0)

        # but it sould have an entry for the superuser
        self.client.login(username='******', password='******')
        res = self.client.get(reverse('auditlog_json'))
        self.assertEqual(res.status_code, 200)
        response = json.loads(res.content)
        self.assertEqual(len(response['aaData']), 1)