@requires_rw<EOL><INDENT>def add_prefix(self, auth, attr, args=None):<DEDENT>
if args is None:<EOL><INDENT>args = {}<EOL><DEDENT>self._logger.debug("<STR_LIT>" % (unicode(attr), unicode(args)))<EOL>if args is None:<EOL><INDENT>args = {}<EOL><DEDENT>if type(attr) != dict:<EOL><INDENT>raise NipapInputError("<STR_LIT>")<EOL><DEDENT>if '<STR_LIT>' in attr or '<STR_LIT>' in attr:<EOL><INDENT>if '<STR_LIT>' in attr:<EOL><INDENT>if attr['<STR_LIT>'] is None:<EOL><INDENT>pool = {<EOL>'<STR_LIT:id>': None,<EOL>'<STR_LIT:name>': None<EOL>}<EOL><DEDENT>else:<EOL><INDENT>pool = self._get_pool(auth, { '<STR_LIT:id>': attr['<STR_LIT>'] })<EOL><DEDENT><DEDENT>else:<EOL><INDENT>if attr['<STR_LIT>'] is None:<EOL><INDENT>pool = {<EOL>'<STR_LIT:id>': None,<EOL>'<STR_LIT:name>': None<EOL>}<EOL><DEDENT>else:<EOL><INDENT>pool = self._get_pool(auth, { '<STR_LIT:name>': attr['<STR_LIT>'] })<EOL><DEDENT>del(attr['<STR_LIT>'])<EOL><DEDENT>attr['<STR_LIT>'] = pool['<STR_LIT:id>']<EOL><DEDENT>else:<EOL><INDENT>pool = {<EOL>'<STR_LIT:id>': None,<EOL>'<STR_LIT:name>': None<EOL>}<EOL><DEDENT>attr['<STR_LIT>'] = auth.authoritative_source<EOL>if '<STR_LIT>' in attr:<EOL><INDENT>if '<STR_LIT>' in args or '<STR_LIT>' in args:<EOL><INDENT>raise NipapExtraneousInputError("<STR_LIT>")<EOL><DEDENT><DEDENT>else:<EOL><INDENT>if ('<STR_LIT>' not in args and '<STR_LIT>' not in args) or ('<STR_LIT>' in args and '<STR_LIT>' in args):<EOL><INDENT>raise NipapExtraneousInputError("<STR_LIT>")<EOL><DEDENT><DEDENT>if '<STR_LIT>' in attr:<EOL><INDENT>vrf = self._get_vrf(auth, attr)<EOL>if '<STR_LIT>' in attr:<EOL><INDENT>del(attr['<STR_LIT>'])<EOL><DEDENT>if '<STR_LIT>' in attr:<EOL><INDENT>del(attr['<STR_LIT>'])<EOL><DEDENT>attr['<STR_LIT>'] = vrf['<STR_LIT:id>']<EOL><DEDENT>if '<STR_LIT>' in args or '<STR_LIT>' in args:<EOL><INDENT>if '<STR_LIT>' in attr or '<STR_LIT>' in attr or '<STR_LIT>' in attr:<EOL><INDENT>vrf = self._get_vrf(auth, attr)<EOL>if '<STR_LIT>' in attr:<EOL><INDENT>del(attr['<STR_LIT>'])<EOL><DEDENT>if '<STR_LIT>' in attr:<EOL><INDENT>del(attr['<STR_LIT>'])<EOL><DEDENT>attr['<STR_LIT>'] = vrf['<STR_LIT:id>']<EOL><DEDENT>if '<STR_LIT>' in args:<EOL><INDENT>from_pool = self._get_pool(auth, args['<STR_LIT>'])<EOL>if from_pool['<STR_LIT>'] is None:<EOL><INDENT>raise NipapInputError('<STR_LIT>')<EOL><DEDENT>if '<STR_LIT:type>' not in attr:<EOL><INDENT>attr['<STR_LIT:type>'] = from_pool['<STR_LIT>']<EOL><DEDENT>if '<STR_LIT>' not in attr:<EOL><INDENT>attr['<STR_LIT>'] = from_pool['<STR_LIT>']<EOL><DEDENT>if attr['<STR_LIT>'] != from_pool['<STR_LIT>']:<EOL><INDENT>raise NipapInputError("<STR_LIT>")<EOL><DEDENT>vrf = self._get_vrf(auth, attr)<EOL><DEDENT>if '<STR_LIT>' in args:<EOL><INDENT>vrf = self._get_vrf(auth, attr)<EOL>if '<STR_LIT>' in attr:<EOL><INDENT>del(attr['<STR_LIT>'])<EOL><DEDENT>if '<STR_LIT>' in attr:<EOL><INDENT>del(attr['<STR_LIT>'])<EOL><DEDENT>attr['<STR_LIT>'] = vrf['<STR_LIT:id>']<EOL><DEDENT>ffp_vrf = self._get_vrf(auth, attr)<EOL>res = self.find_free_prefix(auth, ffp_vrf, args)<EOL>if res != []:<EOL><INDENT>attr['<STR_LIT>'] = res[<NUM_LIT:0>]<EOL><DEDENT>else:<EOL><INDENT>raise NipapNonExistentError("<STR_LIT>")<EOL><DEDENT><DEDENT>req_attr = [ '<STR_LIT>', '<STR_LIT>' ]<EOL>self._check_attr(attr, req_attr, _prefix_attrs)<EOL>if ('<STR_LIT:description>' not in attr) and ('<STR_LIT>' not in attr):<EOL><INDENT>raise NipapMissingInputError('<STR_LIT>')<EOL><DEDENT>if '<STR_LIT>' in attr:<EOL><INDENT>attr['<STR_LIT>'] = _parse_expires(attr['<STR_LIT>'])<EOL><DEDENT>insert, params = self._sql_expand_insert(attr)<EOL>sql = "<STR_LIT>" + insert<EOL>self._execute(sql, params)<EOL>prefix_id = self._lastrowid()<EOL>prefix = self.list_prefix(auth, { '<STR_LIT:id>': prefix_id })[<NUM_LIT:0>]<EOL>audit_params = {<EOL>'<STR_LIT>': prefix['<STR_LIT>'],<EOL>'<STR_LIT>': prefix['<STR_LIT>'],<EOL>'<STR_LIT>': prefix['<STR_LIT>'],<EOL>'<STR_LIT>': prefix['<STR_LIT:id>'],<EOL>'<STR_LIT>': prefix['<STR_LIT>'],<EOL>'<STR_LIT:username>': auth.username,<EOL>'<STR_LIT>': auth.authenticated_as,<EOL>'<STR_LIT>': auth.full_name,<EOL>'<STR_LIT>': auth.authoritative_source,<EOL>'<STR_LIT:description>': '<STR_LIT>' % (prefix['<STR_LIT>'], unicode(attr))<EOL>}<EOL>sql, params = self._sql_expand_insert(audit_params)<EOL>self._execute('<STR_LIT>' % sql, params)<EOL>if pool['<STR_LIT:id>'] is not None:<EOL><INDENT>audit_params['<STR_LIT>'] = pool['<STR_LIT:id>']<EOL>audit_params['<STR_LIT>'] = pool['<STR_LIT:name>']<EOL>audit_params['<STR_LIT:description>'] = '<STR_LIT>' % (pool['<STR_LIT:name>'], prefix['<STR_LIT>'], unicode(prefix['<STR_LIT>']))<EOL>sql, params = self._sql_expand_insert(audit_params)<EOL>self._execute('<STR_LIT>' % sql, params)<EOL><DEDENT>return prefix<EOL>
Add a prefix and return its ID.

            * `auth` [BaseAuth]
                AAA options.
            * `attr` [prefix_attr]
                Prefix attributes.
            * `args` [add_prefix_args]
                Arguments explaining how the prefix should be allocated.

            Returns a dict describing the prefix which was added.

            Prefixes can be added in three ways; manually, from a pool or
            from a prefix.

            Manually
                All prefix data, including the prefix itself is specified in the
                `attr` argument. The `args` argument shall be omitted.

            From a pool
                Most prefixes are expected to be automatically assigned from a pool.
                In this case, the :attr:`prefix` key is omitted from the `attr` argument.
                Also the :attr:`type` key can be omitted and the prefix type will then be
                set to the pools default prefix type. The :func:`find_free_prefix`
                function is used to find available prefixes for this allocation
                method, see its documentation for a description of how the
                `args` argument should be formatted.

            From a prefix
                A prefix can also be selected from another prefix. Also in this case
                the :attr:`prefix` key is omitted from the `attr` argument. See the
                documentation for the :func:`find_free_prefix` for a description of how
                the `args` argument is to be formatted.

            This is the documentation of the internal backend function. It's
            exposed over XML-RPC, please also see the XML-RPC documentation for
            :py:func:`nipap.xmlrpc.NipapXMLRPC.add_prefix` for full
            understanding.