def execute(self, args):
        model_cls = creatable_models.get(args.type)

        form = RawDataValidatingFactory(args.keywords,
                                        model_cls,
                                        marker=getattr(self.current_obj,
                                                       '__contains__', None))

        if form.errors:
            form.write_errors(to=self)
            return

        obj = form.create()

        vh = PreValidateHookMixin(obj)
        try:
            blocking_yield(vh.validate_hook(self.protocol.principal))
        except Exception:
            msg = 'Cancelled executing "%s" due to validate_hook failure' % self.name
            self.write('%s\n' % msg)
            log.msg(msg, system='set')
            return

        interaction = self.protocol.interaction
        if not interaction:
            auth = getUtility(IAuthentication, context=None)
            principal = auth.getPrincipal(None)
        else:
            principal = interaction.participations[0].principal

        obj.__owner__ = principal

        obj_id = self.current_obj.add(obj)

        self.write("%s\n" % obj_id)
Example #2
0
    def render_POST(self, request):
        try:
            data = json.load(request.content)
        except ValueError:
            raise BadRequest("Input data could not be parsed")

        if not isinstance(data, dict):
            raise BadRequest("Input data must be a dictionary")

        form = RawDataValidatingFactory(data, VirtualizationContainer)

        if form.errors or not data.get('backend'):
            backend_error = [dict(id='backend', msg="missing value")
                             ] if not data.get('backend') else []
            return {
                'success':
                False,
                'errors':
                [dict(id=k, msg=v)
                 for k, v in form.error_dict().items()] + backend_error
            }

        vms = form.create()
        self.context.add(vms)

        return {
            'success': True,
            'result': IHttpRestView(vms).render_GET(request)
        }
    def execute(self, args):
        model_cls = creatable_models.get(args.type)

        form = RawDataValidatingFactory(args.keywords, model_cls,
                                        marker=getattr(self.current_obj, '__contains__', None))

        if form.errors:
            form.write_errors(to=self)
            return

        obj = form.create()

        vh = PreValidateHookMixin(obj)
        try:
            blocking_yield(vh.validate_hook(self.protocol.principal))
        except Exception:
            msg = 'Cancelled executing "%s" due to validate_hook failure' % self.name
            self.write('%s\n' % msg)
            log.msg(msg, system='set')
            return

        interaction = self.protocol.interaction
        if not interaction:
            auth = getUtility(IAuthentication, context=None)
            principal = auth.getPrincipal(None)
        else:
            principal = interaction.participations[0].principal

        obj.__owner__ = principal

        obj_id = self.current_obj.add(obj)

        self.write("%s\n" % obj_id)
Example #4
0
    def render_POST(self, request):
        try:
            data = json.load(request.content)
        except ValueError:
            raise BadRequest("Input data could not be parsed")

        if not isinstance(data, dict):
            raise BadRequest("Input data must be a dictionary")

        form = RawDataValidatingFactory(data, VirtualizationContainer)

        if form.errors or not data.get('backend'):
            backend_error = [dict(id='backend', msg="missing value")] if not data.get('backend') else []
            return {'success': False,
                    'errors': [dict(id=k, msg=v) for k, v in form.error_dict().items()] + backend_error}

        vms = form.create()
        self.context.add(vms)

        return {'success': True, 'result': IHttpRestView(vms).render_GET(request)}
def test_apply_and_create_preconditions():
    """There must be no validation errors in objects being updated or created"""
    a = RawDataValidatingFactory({}, Foo)
    assert a.errors
    with assert_raises(AssertionError) as cm:
        a.create()  # should not be able to call `create` with validation errors
    assert cm.exception.args == ("There must be no validation errors", )

    a = RawDataApplier({'bar': 'bad int'}, Foo())
    assert a.errors
    with assert_raises(AssertionError) as cm:
        a.apply()
    assert cm.exception.args == ("There must be no validation errors", )
def test_create_when_required_field_ok():
    a = RawDataValidatingFactory({'bar': '1'}, Foo)
    assert not a.errors
    foo = a.create()
    assert isinstance(foo, Foo)
    assert foo.bar == 1
Example #7
0
    def render_POST(self, request):
        try:
            data = json.load(request.content)
        except ValueError:
            raise BadRequest("Input data could not be parsed")

        if not isinstance(data, dict):
            raise BadRequest("Input data must be a dictionary")

        if 'state' not in data:
            data['state'] = 'active' if data.get('start_on_boot') else 'inactive'

        if data.get('diskspace'):
            data['diskspace'] = {'root': data['diskspace']}

        # XXX: ONC should send us a 'nameserver' list instead of this hackish dns1,dns2
        if 'nameservers' not in data:
            nameservers = []
            for k in ['dns1', 'dns2']:
                if data.get(k, None):
                    nameservers.append(data[k])

            data['nameservers'] = nameservers

        if 'autostart' not in data:
            data['autostart'] = data.get('start_on_boot', False)

        assert data['root_password'] == data['root_password_repeat']
        root_password = data['root_password']

        for k in ('dns1', 'dns2', 'root_password', 'root_password_repeat', 'network-type', 'start_on_boot'):
            if k in data:
                del data[k]

        if 'memory' in data:
            data['memory'] = data['memory'] * 1024  # Memory sent by ONC is in GB, model keeps it in MB

        # HACK: Workaround for primitive form validation with booleans
        for k, v in data.iteritems():
            if type(v) is bool:
                data[k] = str(v)

        # HACK: prevent invalid hostnames
        data['hostname'] = data['hostname'] if _isdotted(data['hostname']) else None
        if not data['hostname']:
            return {'success': False,
                    'errors': [{'id': 'hostname', 'msg': 'Invalid hostname supplied!'}]}

        form = RawDataValidatingFactory(data, Compute, marker=IVirtualCompute)

        if form.errors or not data.get('template'):
            template_error = [dict(id='template', msg="missing value")] if not data.get('template') else []
            return {'success': False,
                    'errors': [dict(id=k, msg=v) for k, v in form.error_dict().items()] + template_error}

        compute = form.create()

        interaction = request.interaction

        if not interaction:
            auth = getUtility(IAuthentication, context=None)
            principal = auth.getPrincipal(None)
        else:
            principal = interaction.participations[0].principal

        @db.transact
        def handle_success(r, compute, principal):
            compute.__owner__ = principal

            compute.root_password = root_password
            self.context.add(compute)

            data['id'] = compute.__name__

            self.add_log_event(principal,
                               'Creation of %s (%s) (via web) successful' % (compute.hostname, compute))

            request.write(json.dumps({'success': True,
                                      'result': IHttpRestView(compute).render_GET(request)},
                                     cls=JsonSetEncoder))
            request.finish()

        def handle_pre_execute_hook_error(f, compute, principal):
            f.trap(Exception)
            self.add_log_event(principal,
                               'Creation of %s (%s) (via web) failed: %s: %s' % (compute.hostname, compute,
                                                                                 type(f.value).__name__,
                                                                                 f.value))
            request.write(json.dumps({'success': False,
                                      'errors': [{'id': 'vm', 'msg': str(f.value)}]}))
            request.finish()

        d = self.validate_hook(principal)
        d.addCallback(handle_success, compute, principal)
        d.addErrback(handle_pre_execute_hook_error, compute, principal)
        return NOT_DONE_YET
Example #8
0
    def render_POST(self, request):
        try:
            data = json.load(request.content)
        except ValueError:
            raise BadRequest("Input data could not be parsed")

        if not isinstance(data, dict):
            raise BadRequest("Input data must be a dictionary")

        if 'state' not in data:
            data['state'] = 'active' if data.get(
                'start_on_boot') else 'inactive'

        if data.get('diskspace'):
            data['diskspace'] = {'root': data['diskspace']}

        # XXX: ONC should send us a 'nameserver' list instead of this hackish dns1,dns2
        if 'nameservers' not in data:
            nameservers = []
            for k in ['dns1', 'dns2']:
                if data.get(k, None):
                    nameservers.append(data[k])

            data['nameservers'] = nameservers

        if 'autostart' not in data:
            data['autostart'] = data.get('start_on_boot', False)

        assert data['root_password'] == data['root_password_repeat']
        root_password = data['root_password']

        for k in ('dns1', 'dns2', 'root_password', 'root_password_repeat',
                  'network-type', 'start_on_boot'):
            if k in data:
                del data[k]

        if 'memory' in data:
            data['memory'] = data[
                'memory'] * 1024  # Memory sent by ONC is in GB, model keeps it in MB

        # HACK: Workaround for primitive form validation with booleans
        for k, v in data.iteritems():
            if type(v) is bool:
                data[k] = str(v)

        # HACK: prevent invalid hostnames
        data['hostname'] = data['hostname'] if _isdotted(
            data['hostname']) else None
        if not data['hostname']:
            return {
                'success': False,
                'errors': [{
                    'id': 'hostname',
                    'msg': 'Invalid hostname supplied!'
                }]
            }

        form = RawDataValidatingFactory(data, Compute, marker=IVirtualCompute)

        if form.errors or not data.get('template'):
            template_error = [dict(id='template', msg="missing value")
                              ] if not data.get('template') else []
            return {
                'success':
                False,
                'errors':
                [dict(id=k, msg=v)
                 for k, v in form.error_dict().items()] + template_error
            }

        compute = form.create()

        interaction = request.interaction

        if not interaction:
            auth = getUtility(IAuthentication, context=None)
            principal = auth.getPrincipal(None)
        else:
            principal = interaction.participations[0].principal

        @db.transact
        def handle_success(r, compute, principal):
            compute.__owner__ = principal

            compute.root_password = root_password
            self.context.add(compute)

            data['id'] = compute.__name__

            self.add_log_event(
                principal, 'Creation of %s (%s) (via web) successful' %
                (compute.hostname, compute))

            request.write(
                json.dumps(
                    {
                        'success': True,
                        'result': IHttpRestView(compute).render_GET(request)
                    },
                    cls=JsonSetEncoder))
            request.finish()

        def handle_pre_execute_hook_error(f, compute, principal):
            f.trap(Exception)
            self.add_log_event(
                principal, 'Creation of %s (%s) (via web) failed: %s: %s' %
                (compute.hostname, compute, type(f.value).__name__, f.value))
            request.write(
                json.dumps({
                    'success': False,
                    'errors': [{
                        'id': 'vm',
                        'msg': str(f.value)
                    }]
                }))
            request.finish()

        d = self.validate_hook(principal)
        d.addCallback(handle_success, compute, principal)
        d.addErrback(handle_pre_execute_hook_error, compute, principal)
        return NOT_DONE_YET