def add_prefix(self, auth, attr, args=None):
        """ 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.
        """

        if args is None:
            args = {}

        self._logger.debug("add_prefix called; attr: %s; args: %s" % (unicode(attr), unicode(args)))

        # args defined?
        if args is None:
            args = {}

        # attr must be a dict!
        if type(attr) != dict:
            raise NipapInputError("'attr' must be a dict")

        # handle pool attributes - find correct one and remove bad pool keys
        # note how this is not related to from-pool but is merely the pool
        # attributes if this prefix is to be part of a pool
        if 'pool_id' in attr or 'pool_name' in attr:
            if 'pool_id' in attr:
                if attr['pool_id'] is None:
                    pool = {
                        'id': None,
                        'name': None
                    }
                else:
                    pool = self._get_pool(auth, { 'id': attr['pool_id'] })

            else:
                if attr['pool_name'] is None:
                    pool = {
                        'id': None,
                        'name': None
                    }
                else:
                    # resolve pool name to pool id
                    pool = self._get_pool(auth, { 'name': attr['pool_name'] })

                # and delete the pool_name attr
                del(attr['pool_name'])

            attr['pool_id'] = pool['id']

        else:
            pool = {
                'id': None,
                'name': None
            }

        attr['authoritative_source'] = auth.authoritative_source

        # sanity checks for manual prefix vs from-pool vs from-prefix
        if 'prefix' in attr:
            if 'from-pool' in args or 'from-prefix' in args:
                raise NipapExtraneousInputError("specify 'prefix' or 'from-prefix' or 'from-pool'")

        else:
            if ('from-pool' not in args and 'from-prefix' not in args) or ('from-pool' in args and 'from-prefix' in args):
                raise NipapExtraneousInputError("specify 'prefix' or 'from-prefix' or 'from-pool'")

        # VRF handling for manually specified prefix
        if 'prefix' in attr:
            # handle VRF - find the correct one and remove bad VRF keys
            vrf = self._get_vrf(auth, attr)
            if 'vrf_rt' in attr:
                del(attr['vrf_rt'])
            if 'vrf_name' in attr:
                del(attr['vrf_name'])
            attr['vrf_id'] = vrf['id']

        # VRF handling for allocation from pool or parent prefix
        if 'from-pool' in args or 'from-prefix' in args:
            # did we get a VRF from the client?
            if 'vrf_id' in attr or 'vrf_rt' in attr or 'vrf_name' in attr:
                # handle VRF - find the correct one and remove bad VRF keys
                vrf = self._get_vrf(auth, attr)
                if 'vrf_rt' in attr:
                    del(attr['vrf_rt'])
                if 'vrf_name' in attr:
                    del(attr['vrf_name'])
                attr['vrf_id'] = vrf['id']

            if 'from-pool' in args:
                from_pool = self._get_pool(auth, args['from-pool'])

                # make sure there are prefixes in pool, if any prefix is present
                # than the implied-vrf is set, otherwise the pool is empty
                if from_pool['vrf_id'] is None:
                    raise NipapInputError('No prefixes in pool')

                # set default type from pool if missing
                if 'type' not in attr:
                    attr['type'] = from_pool['default_type']

                # set implied VRF of pool if missing
                if 'vrf_id' not in attr:
                    attr['vrf_id'] = from_pool['vrf_id']

                # make sure VRF aligns with pool implied VRF
                if attr['vrf_id'] != from_pool['vrf_id']:
                    raise NipapInputError("VRF must be the same as the pools implied VRF")

                vrf = self._get_vrf(auth, attr)

            if 'from-prefix' in args:
                # handle VRF - find the correct one and remove bad VRF keys
                vrf = self._get_vrf(auth, attr)
                if 'vrf_rt' in attr:
                    del(attr['vrf_rt'])
                if 'vrf_name' in attr:
                    del(attr['vrf_name'])
                attr['vrf_id'] = vrf['id']

            # VRF fiddling
            ffp_vrf = self._get_vrf(auth, attr)

            # get a new prefix
            res = self.find_free_prefix(auth, ffp_vrf, args)
            if res != []:
                attr['prefix'] = res[0]
            else:
                # TODO: Raise other exception?
                raise NipapNonExistentError("no free prefix found")

        # do we have all attributes?
        req_attr = [ 'prefix', 'authoritative_source' ]
        self._check_attr(attr, req_attr, _prefix_attrs)
        if ('description' not in attr) and ('node' not in attr):
            raise NipapMissingInputError('Either description or node must be specified.')

        if 'expires' in attr:
            attr['expires'] = _parse_expires(attr['expires'])

        insert, params = self._sql_expand_insert(attr)
        sql = "INSERT INTO ip_net_plan " + insert

        self._execute(sql, params)
        prefix_id = self._lastrowid()
        prefix = self.list_prefix(auth, { 'id': prefix_id })[0]

        # write to audit table
        audit_params = {
            'vrf_id': prefix['vrf_id'],
            'vrf_rt': prefix['vrf_rt'],
            'vrf_name': prefix['vrf_name'],
            'prefix_id': prefix['id'],
            'prefix_prefix': prefix['prefix'],
            'username': auth.username,
            'authenticated_as': auth.authenticated_as,
            'full_name': auth.full_name,
            'authoritative_source': auth.authoritative_source,
            'description': 'Added prefix %s with attr: %s' % (prefix['prefix'], unicode(attr))
        }
        sql, params = self._sql_expand_insert(audit_params)
        self._execute('INSERT INTO ip_net_log %s' % sql, params)

        if pool['id'] is not None:
            audit_params['pool_id'] = pool['id']
            audit_params['pool_name'] = pool['name']
            audit_params['description'] = 'Pool %s expanded with prefix %s in VRF %s' % (pool['name'], prefix['prefix'], unicode(prefix['vrf_rt']))

            sql, params = self._sql_expand_insert(audit_params)
            self._execute('INSERT INTO ip_net_log %s' % sql, params)

        return prefix
def add_prefix ( self , auth , attr , args = None ) : if args is None : args = { } self . _logger . debug ( "add_prefix called; attr: %s; args: %s" % ( unicode ( attr ) , unicode ( args ) ) ) if args is None : args = { } if type ( attr ) != dict : raise NipapInputError ( "'attr' must be a dict" ) if 'pool_id' in attr or 'pool_name' in attr : if 'pool_id' in attr : if attr [ 'pool_id' ] is None : pool = { 'id' : None , 'name' : None } else : pool = self . _get_pool ( auth , { 'id' : attr [ 'pool_id' ] } ) else : if attr [ 'pool_name' ] is None : pool = { 'id' : None , 'name' : None } else : pool = self . _get_pool ( auth , { 'name' : attr [ 'pool_name' ] } ) del ( attr [ 'pool_name' ] ) attr [ 'pool_id' ] = pool [ 'id' ] else : pool = { 'id' : None , 'name' : None } attr [ 'authoritative_source' ] = auth . authoritative_source if 'prefix' in attr : if 'from-pool' in args or 'from-prefix' in args : raise NipapExtraneousInputError ( "specify 'prefix' or 'from-prefix' or 'from-pool'" ) else : if ( 'from-pool' not in args and 'from-prefix' not in args ) or ( 'from-pool' in args and 'from-prefix' in args ) : raise NipapExtraneousInputError ( "specify 'prefix' or 'from-prefix' or 'from-pool'" ) if 'prefix' in attr : vrf = self . _get_vrf ( auth , attr ) if 'vrf_rt' in attr : del ( attr [ 'vrf_rt' ] ) if 'vrf_name' in attr : del ( attr [ 'vrf_name' ] ) attr [ 'vrf_id' ] = vrf [ 'id' ] if 'from-pool' in args or 'from-prefix' in args : if 'vrf_id' in attr or 'vrf_rt' in attr or 'vrf_name' in attr : vrf = self . _get_vrf ( auth , attr ) if 'vrf_rt' in attr : del ( attr [ 'vrf_rt' ] ) if 'vrf_name' in attr : del ( attr [ 'vrf_name' ] ) attr [ 'vrf_id' ] = vrf [ 'id' ] if 'from-pool' in args : from_pool = self . _get_pool ( auth , args [ 'from-pool' ] ) if from_pool [ 'vrf_id' ] is None : raise NipapInputError ( 'No prefixes in pool' ) if 'type' not in attr : attr [ 'type' ] = from_pool [ 'default_type' ] if 'vrf_id' not in attr : attr [ 'vrf_id' ] = from_pool [ 'vrf_id' ] if attr [ 'vrf_id' ] != from_pool [ 'vrf_id' ] : raise NipapInputError ( "VRF must be the same as the pools implied VRF" ) vrf = self . _get_vrf ( auth , attr ) if 'from-prefix' in args : vrf = self . _get_vrf ( auth , attr ) if 'vrf_rt' in attr : del ( attr [ 'vrf_rt' ] ) if 'vrf_name' in attr : del ( attr [ 'vrf_name' ] ) attr [ 'vrf_id' ] = vrf [ 'id' ] ffp_vrf = self . _get_vrf ( auth , attr ) res = self . find_free_prefix ( auth , ffp_vrf , args ) if res != [ ] : attr [ 'prefix' ] = res [ 0 ] else : raise NipapNonExistentError ( "no free prefix found" ) req_attr = [ 'prefix' , 'authoritative_source' ] self . _check_attr ( attr , req_attr , _prefix_attrs ) if ( 'description' not in attr ) and ( 'node' not in attr ) : raise NipapMissingInputError ( 'Either description or node must be specified.' ) if 'expires' in attr : attr [ 'expires' ] = _parse_expires ( attr [ 'expires' ] ) insert , params = self . _sql_expand_insert ( attr ) sql = "INSERT INTO ip_net_plan " + insert self . _execute ( sql , params ) prefix_id = self . _lastrowid ( ) prefix = self . list_prefix ( auth , { 'id' : prefix_id } ) [ 0 ] audit_params = { 'vrf_id' : prefix [ 'vrf_id' ] , 'vrf_rt' : prefix [ 'vrf_rt' ] , 'vrf_name' : prefix [ 'vrf_name' ] , 'prefix_id' : prefix [ 'id' ] , 'prefix_prefix' : prefix [ 'prefix' ] , 'username' : auth . username , 'authenticated_as' : auth . authenticated_as , 'full_name' : auth . full_name , 'authoritative_source' : auth . authoritative_source , 'description' : 'Added prefix %s with attr: %s' % ( prefix [ 'prefix' ] , unicode ( attr ) ) } sql , params = self . _sql_expand_insert ( audit_params ) self . _execute ( 'INSERT INTO ip_net_log %s' % sql , params ) if pool [ 'id' ] is not None : audit_params [ 'pool_id' ] = pool [ 'id' ] audit_params [ 'pool_name' ] = pool [ 'name' ] audit_params [ 'description' ] = 'Pool %s expanded with prefix %s in VRF %s' % ( pool [ 'name' ] , prefix [ 'prefix' ] , unicode ( prefix [ 'vrf_rt' ] ) ) sql , params = self . _sql_expand_insert ( audit_params ) self . _execute ( 'INSERT INTO ip_net_log %s' % sql , params ) return prefix
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.