Ejemplo n.º 1
0
    def post(self):
        net, request = self.net, self.request

        if not request.user.is_staff:
            self.data.pop(
                'dc_bound', None
            )  # default DC binding cannot be changed when creating object

        net.owner = request.user  # just a default
        net.alias = net.name  # just a default
        ser = NetworkSerializer(request, net, data=self.data)

        if not ser.is_valid():
            return FailureTaskResponse(request,
                                       ser.errors,
                                       obj=net,
                                       dc_bound=False)

        ser.object.save()
        res = SuccessTaskResponse(request,
                                  ser.data,
                                  status=HTTP_201_CREATED,
                                  obj=net,
                                  dc_bound=False,
                                  detail_dict=ser.detail_dict(),
                                  msg=LOG_NET_CREATE)

        if net.dc_bound:
            attach_dc_virt_object(res.data.get('task_id'),
                                  LOG_NETWORK_ATTACH,
                                  net,
                                  net.dc_bound,
                                  user=request.user)

        return res
Ejemplo n.º 2
0
    def post(self):
        template, request = self.template, self.request

        if not request.user.is_staff:
            self.data.pop(
                'dc_bound', None
            )  # default DC binding cannot be changed when creating object

        template.owner = request.user  # just a default
        template.alias = template.name  # just a default
        ser = TemplateSerializer(request, template, data=self.data)

        if not ser.is_valid():
            return FailureTaskResponse(request,
                                       ser.errors,
                                       obj=template,
                                       dc_bound=False)

        ser.object.save()
        res = SuccessTaskResponse(request,
                                  ser.data,
                                  status=HTTP_201_CREATED,
                                  obj=template,
                                  dc_bound=False,
                                  detail_dict=ser.detail_dict(),
                                  msg=LOG_TEMPLATE_CREATE)

        if template.dc_bound:
            attach_dc_virt_object(res.data.get('task_id'),
                                  LOG_TEMPLATE_ATTACH,
                                  template,
                                  template.dc_bound,
                                  user=request.user)

        return res
Ejemplo n.º 3
0
    def post(self):
        request = self.request
        dc1_settings = DefaultDc().settings
        domain = self.domain
        domain.owner = request.user  # just a default
        domain.type = dc1_settings.DNS_DOMAIN_TYPE_DEFAULT

        if not request.user.is_staff:
            self.data.pop('dc_bound', None)  # default DC binding cannot be changed when creating object

        ser = DomainSerializer(request, domain, data=self.data)

        if not ser.is_valid():
            return FailureTaskResponse(request, ser.errors, obj=domain, dc_bound=False)

        tsig_data = {}
        # in case there will be more tsig_* parameters (but for now, there's only tsig_keys)
        for key, val in self.data.items():
            # remove tsig_* parameters from request data because they belong to other validator
            if key.startswith('tsig_'):
                self.data.pop(key)
                tsig_data[key[5:]] = val    # e.g: tsig_keys -> keys

        tsig_keys_new, tsig_serializers = self.process_tsig_keys(request, tsig_data)

        # save default serializer
        ser.object.save()
        # save tsig serializer(s)
        [ser_tsig.object.save() for ser_tsig in tsig_serializers]
        # link newly defined TSIG keys to this domain
        [new_key.link_to_axfr_domain(domain) for new_key in tsig_keys_new]

        res = SuccessTaskResponse(request, ser.data, status=HTTP_201_CREATED, obj=domain, dc_bound=False,
                                  msg=LOG_DOMAIN_CREATE, detail_dict=ser.detail_dict())

        # Create SOA and NS records for new MASTER/NATIVE domain
        from api.dns.record.views import dns_record
        try:
            if dc1_settings.DNS_SOA_DEFAULT and dc1_settings.DNS_NAMESERVERS:
                soa_attrs = {'hostmaster': dc1_settings.DNS_HOSTMASTER.replace('@', '.'),
                             'nameserver': dc1_settings.DNS_NAMESERVERS[0]}
                soa_data = {'type': Record.SOA, 'name': domain.name,
                            'content': dc1_settings.DNS_SOA_DEFAULT.format(**soa_attrs)}
                call_api_view(request, 'POST', dns_record, domain.name, 0, data=soa_data, log_response=True)

            for ns in dc1_settings.DNS_NAMESERVERS:
                ns_data = {'type': Record.NS, 'name': domain.name, 'content': ns}
                call_api_view(request, 'POST', dns_record, domain.name, 0, data=ns_data, log_response=True)
        except Exception as e:
            logger.exception(e)

        if domain.dc_bound:
            assert request.dc.id == domain.dc_bound
            attach_dc_virt_object(res.data.get('task_id'), LOG_DOMAIN_ATTACH, domain, request.dc,
                                  user=request.user)

        return res
Ejemplo n.º 4
0
    def post(self):
        iso, request = self.iso, self.request

        if not request.user.is_staff:
            self.data.pop(
                'dc_bound', None
            )  # default DC binding cannot be changed when creating object

        iso.owner = request.user  # just a default
        iso.alias = re.sub(r'\.iso\s*$', '', iso.name)  # just a default
        iso.status = Iso.OK  # TODO: status is not used right now
        ser = IsoSerializer(request, iso, data=self.data)

        if not ser.is_valid():
            return FailureTaskResponse(request,
                                       ser.errors,
                                       obj=iso,
                                       dc_bound=False)

        ser.object.save()
        res = SuccessTaskResponse(request,
                                  ser.data,
                                  status=HTTP_201_CREATED,
                                  obj=iso,
                                  dc_bound=False,
                                  detail_dict=ser.detail_dict(),
                                  msg=LOG_ISO_CREATE)

        if iso.dc_bound:
            attach_dc_virt_object(res.data.get('task_id'),
                                  LOG_ISO_ATTACH,
                                  iso,
                                  iso.dc_bound,
                                  user=request.user)

        return res
Ejemplo n.º 5
0
    def group_modify(self, update=False):
        group = self.group
        request = self.request

        if update:
            # We are deleting users that are not assigned to group any more, so we have to store all of them before
            # deleting because we have to update task log for user so he can see he was removed from group
            original_group_users = set(
                group.user_set.select_related('dc_bound', 'default_dc').all())
        else:
            group.alias = group.name  # just a default
            original_group_users = set()

        ser = self.serializer(request, group, data=self.data, partial=update)

        if not ser.is_valid():
            return FailureTaskResponse(request,
                                       ser.errors,
                                       obj=group,
                                       dc_bound=False)

        ser.save()
        if update:
            msg = LOG_GROUP_UPDATE
            status = HTTP_200_OK
        else:
            msg = LOG_GROUP_CREATE
            status = HTTP_201_CREATED

        connection.on_commit(lambda: group_relationship_changed.send(
            group_name=ser.object.name))
        res = SuccessTaskResponse(request,
                                  ser.data,
                                  status=status,
                                  obj=group,
                                  msg=msg,
                                  detail_dict=ser.detail_dict(),
                                  dc_bound=False)

        # let's get the task_id so we use the same one for each log message
        task_id = res.data.get('task_id')
        removed_users = None

        if group.dc_bound and not update:
            attach_dc_virt_object(res.data.get('task_id'),
                                  LOG_GROUP_ATTACH,
                                  group,
                                  group.dc_bound,
                                  user=request.user)

        if ser.object._users_to_save is not None:
            # Update Users log that are attached to group
            current_users = set(ser.object._users_to_save)
            added_users = current_users - original_group_users
            removed_users = original_group_users - current_users
            affected_users = current_users.symmetric_difference(
                original_group_users)

            # Remove user.dc_bound flag for newly added users if group is attached to multiple DCs or
            #                                                          to one DC that is different from user.dc_bound
            if added_users:
                group_dcs_count = group.dc_set.count()

                if group_dcs_count >= 1:
                    if group_dcs_count == 1:
                        dc = group.dc_set.get()
                    else:
                        dc = None

                    for user in added_users:
                        remove_user_dc_binding(task_id, user, dc=dc)

            # Update Users that were removed from group or added to group
            for user in affected_users:
                detail = "groups='%s'" % ','.join(user.roles.all().values_list(
                    'name', flat=True))
                task_log_success(task_id,
                                 LOG_USER_UPDATE,
                                 obj=user,
                                 owner=user,
                                 update_user_tasks=False,
                                 detail=detail)

        # Permission or users for this group were changed, which may affect the cached list of DC admins for DCs which
        # are attached to this group. So we need to clear the list of admins cached for each affected DC
        if ser.object._permissions_to_save is not None or ser.object._users_to_save is not None:
            for dc in group.dc_set.all():
                User.clear_dc_admin_ids(dc)

            # Users were removed from this group and may loose access to DCs which are attached to this group
            # So we better set all users current_dc to default_dc
            if removed_users:
                for user in removed_users:
                    if not user.is_staff:
                        user.reset_current_dc()

        return res
Ejemplo n.º 6
0
    def _run_execute(self,
                     msg,
                     cmd,
                     recover_on_error=False,
                     delete_on_error=False,
                     error_fun=None,
                     vm=None,
                     snap=None,
                     detail_dict=None,
                     stdin=None,
                     cmd_add=None,
                     cb_add=None):
        exc = None
        img, img_server, request = self.img, self.img_server, self.request
        self.obj = img  # self.execute() requirement

        # noinspection PyBroadException
        try:
            cmd += ' -d %s >&2' % img_server.datasets_dir

            if cmd_add:
                cmd += cmd_add

            lock = 'image_manage %s' % img.uuid
            callback = ('api.image.base.tasks.image_manage_cb', {
                'image_uuid': img.uuid
            })
            apiview = {
                'view': 'image_manage',
                'method': request.method,
                'name': img.name
            }
            meta = {
                'msg': msg,
                'output': {
                    'returncode': 'returncode',
                    'stderr': 'message',
                    'stdout': 'json'
                },
                'replace_text': [(img.uuid, img.name)],
                'image_uuid': img.uuid,
                'apiview': apiview,
            }

            if cb_add:
                callback[1].update(cb_add)

            if vm:  # image_snapshot view
                meta['vm_uuid'] = vm.uuid
                meta['replace_text'].append((vm.uuid, vm.hostname))
                callback[1]['vm_uuid'] = vm.uuid
                callback[1]['snap_id'] = snap.id
                apiview['view'] = 'image_snapshot'
                snap_data = {
                    'hostname': vm.hostname,
                    'snapname': snap.name,
                    'disk_id': snap.array_disk_id
                }
                apiview.update(snap_data)
                detail_dict.update(snap_data)

            if self.execute(cmd,
                            meta=meta,
                            lock=lock,
                            callback=callback,
                            tg=TG_DC_UNBOUND,
                            queue=img_server.node.image_queue,
                            stdin=stdin,
                            expires=IMAGE_TASK_EXPIRES):
                if request.method == 'POST' and img.dc_bound:
                    attach_dc_virt_object(self.task_id,
                                          LOG_IMAGE_ATTACH,
                                          img,
                                          img.dc_bound,
                                          user=request.user)

                return TaskResponse(request,
                                    self.task_id,
                                    msg=msg,
                                    obj=img,
                                    api_view=apiview,
                                    detail_dict=detail_dict,
                                    data=self.data)
        except Exception as exc:
            pass

        # Rollback + return error response
        if error_fun:
            error_fun()

        if delete_on_error:
            img.delete()
        else:
            if recover_on_error:
                for attr, value in img.backup.items():
                    setattr(img, attr, value)

                img.backup = {}  # Remove backup
                img.manifest = img.manifest_active
                img.status = Image.OK
                img.save()
            else:
                img.save_status(Image.OK)

        if exc:  # This should never happen
            raise exc

        return FailureTaskResponse(request,
                                   self.error,
                                   obj=img,
                                   dc_bound=self.dc_bound)
Ejemplo n.º 7
0
    def post(self):
        request = self.request
        dc1_settings = DefaultDc().settings
        domain = self.domain
        domain.owner = request.user  # just a default
        domain.type = dc1_settings.DNS_DOMAIN_TYPE_DEFAULT

        if not request.user.is_staff:
            self.data.pop(
                'dc_bound', None
            )  # default DC binding cannot be changed when creating object

        ser = DomainSerializer(request, domain, data=self.data)

        if not ser.is_valid():
            return FailureTaskResponse(request,
                                       ser.errors,
                                       obj=domain,
                                       dc_bound=False)

        ser.object.save()
        res = SuccessTaskResponse(request,
                                  ser.data,
                                  status=HTTP_201_CREATED,
                                  obj=domain,
                                  dc_bound=False,
                                  msg=LOG_DOMAIN_CREATE,
                                  detail_dict=ser.detail_dict())

        # Create SOA and NS records for new MASTER/NATIVE domain
        from api.dns.record.views import dns_record
        try:
            if dc1_settings.DNS_SOA_DEFAULT and dc1_settings.DNS_NAMESERVERS:
                soa_attrs = {
                    'hostmaster':
                    dc1_settings.DNS_HOSTMASTER.replace('@', '.'),
                    'nameserver': dc1_settings.DNS_NAMESERVERS[0]
                }
                soa_data = {
                    'type': Record.SOA,
                    'name': domain.name,
                    'content': dc1_settings.DNS_SOA_DEFAULT.format(**soa_attrs)
                }
                call_api_view(request,
                              'POST',
                              dns_record,
                              domain.name,
                              0,
                              data=soa_data,
                              log_response=True)

            for ns in dc1_settings.DNS_NAMESERVERS:
                ns_data = {
                    'type': Record.NS,
                    'name': domain.name,
                    'content': ns
                }
                call_api_view(request,
                              'POST',
                              dns_record,
                              domain.name,
                              0,
                              data=ns_data,
                              log_response=True)
        except Exception as e:
            logger.exception(e)

        if domain.dc_bound:
            assert request.dc.id == domain.dc_bound
            attach_dc_virt_object(res.data.get('task_id'),
                                  LOG_DOMAIN_ATTACH,
                                  domain,
                                  request.dc,
                                  user=request.user)

        return res