try:<EOL><INDENT>oauth_request = oauth_provider.utils.get_oauth_request(request)<EOL><DEDENT>except oauth.Error as err:<EOL><INDENT>raise exceptions.AuthenticationFailed(err.message)<EOL><DEDENT>if not oauth_request:<EOL><INDENT>return None<EOL><DEDENT>oauth_params = oauth_provider.consts.OAUTH_PARAMETERS_NAMES<EOL>found = any(param for param in oauth_params if param in oauth_request)<EOL>missing = list(param for param in oauth_params if param not in oauth_request)<EOL>if not found:<EOL><INDENT>return None<EOL><DEDENT>if missing:<EOL><INDENT>msg = '<STR_LIT>' % ('<STR_LIT:U+002CU+0020>'.join(missing))<EOL>raise exceptions.AuthenticationFailed(msg)<EOL><DEDENT>if not self.check_nonce(request, oauth_request):<EOL><INDENT>msg = '<STR_LIT>'<EOL>raise exceptions.AuthenticationFailed(msg)<EOL><DEDENT>try:<EOL><INDENT>consumer_key = oauth_request.get_parameter('<STR_LIT>')<EOL>consumer = oauth_provider_store.get_consumer(request, oauth_request, consumer_key)<EOL><DEDENT>except oauth_provider.store.InvalidConsumerError:<EOL><INDENT>msg = '<STR_LIT>' % oauth_request.get_parameter('<STR_LIT>')<EOL>raise exceptions.AuthenticationFailed(msg)<EOL><DEDENT>if consumer.status != oauth_provider.consts.ACCEPTED:<EOL><INDENT>msg = '<STR_LIT>' % consumer.get_status_display()<EOL>raise exceptions.AuthenticationFailed(msg)<EOL><DEDENT>try:<EOL><INDENT>token_param = oauth_request.get_parameter('<STR_LIT>')<EOL>token = oauth_provider_store.get_access_token(request, oauth_request, consumer, token_param)<EOL><DEDENT>except oauth_provider.store.InvalidTokenError:<EOL><INDENT>msg = '<STR_LIT>' % oauth_request.get_parameter('<STR_LIT>')<EOL>raise exceptions.AuthenticationFailed(msg)<EOL><DEDENT>try:<EOL><INDENT>self.validate_token(request, consumer, token)<EOL><DEDENT>except oauth.Error as err:<EOL><INDENT>raise exceptions.AuthenticationFailed(err.message)<EOL><DEDENT>user = token.user<EOL>if not user.is_active:<EOL><INDENT>msg = '<STR_LIT>' % user.username<EOL>raise exceptions.AuthenticationFailed(msg)<EOL><DEDENT>return (token.user, token)<EOL>

Returns two-tuple of (user, token) if authentication succeeds,
or None otherwise.


return '<STR_LIT>' % self.www_authenticate_realm<EOL>

If permission is denied, return a '401 Unauthorized' response,
with an appropraite 'WWW-Authenticate' header.


def validate_token(self, request, consumer, token):

oauth_server, oauth_request = oauth_provider.utils.initialize_server_request(request)<EOL>oauth_server.verify_request(oauth_request, consumer, token)<EOL>

Check the token and raise an `oauth.Error` exception if invalid.


def check_nonce(self, request, oauth_request):

oauth_nonce = oauth_request['<STR_LIT>']<EOL>oauth_timestamp = oauth_request['<STR_LIT>']<EOL>return check_nonce(request, oauth_request, oauth_nonce, oauth_timestamp)<EOL>

Checks nonce of request, and return True if valid.


auth = get_authorization_header(request).split()<EOL>if len(auth) == <NUM_LIT:1>:<EOL><INDENT>msg = '<STR_LIT>'<EOL>raise exceptions.AuthenticationFailed(msg)<EOL><DEDENT>elif len(auth) > <NUM_LIT:2>:<EOL><INDENT>msg = '<STR_LIT>'<EOL>raise exceptions.AuthenticationFailed(msg)<EOL><DEDENT>if auth and auth[<NUM_LIT:0>].lower() == b'<STR_LIT>':<EOL><INDENT>access_token = auth[<NUM_LIT:1>]<EOL><DEDENT>elif '<STR_LIT>' in request.POST:<EOL><INDENT>access_token = request.POST['<STR_LIT>']<EOL><DEDENT>elif '<STR_LIT>' in request.GET and self.allow_query_params_token:<EOL><INDENT>access_token = request.GET['<STR_LIT>']<EOL><DEDENT>else:<EOL><INDENT>return None<EOL><DEDENT>return self.authenticate_credentials(request, access_token)<EOL>


def authenticate_credentials(self, request, access_token):

try:<EOL><INDENT>token = oauth2_provider.oauth2.models.AccessToken.objects.select_related('<STR_LIT:user>')<EOL>token = token.get(token=access_token, expires__gt=provider_now())<EOL><DEDENT>except oauth2_provider.oauth2.models.AccessToken.DoesNotExist:<EOL><INDENT>raise exceptions.AuthenticationFailed('<STR_LIT>')<EOL><DEDENT>user = token.user<EOL>if not user.is_active:<EOL><INDENT>msg = '<STR_LIT>' % user.get_username()<EOL>raise exceptions.AuthenticationFailed(msg)<EOL><DEDENT>return (user, token)<EOL>

Authenticate the request, given the access token.


Bearer is the only finalized type currently
Check details on the `OAuth2Authentication.authenticate` method


init_py = open(os.path.join(package, '<STR_LIT>')).read()<EOL>return re.search("<STR_LIT>",<EOL>init_py, re.MULTILINE).group(<NUM_LIT:1>)<EOL>

Return package version as listed in `__version__` in `init.py`.


return [dirpath<EOL>for dirpath, dirnames, filenames in os.walk(package)<EOL>if os.path.exists(os.path.join(dirpath, '<STR_LIT>'))]<EOL>

Return root package and all sub-packages.


walk = [(dirpath.replace(package + os.sep, '<STR_LIT>', <NUM_LIT:1>), filenames)<EOL>for dirpath, dirnames, filenames in os.walk(package)<EOL>if not os.path.exists(os.path.join(dirpath, '<STR_LIT>'))]<EOL>filepaths = []<EOL>for base, filenames in walk:<EOL><INDENT>filepaths.extend([os.path.join(base, filename)<EOL>for filename in filenames])<EOL><DEDENT>return {package: filepaths}<EOL>

Return all files under the root package, that are not in a
package themselves.


return self.__class__(self.production, self.pos + <NUM_LIT:1>, self.lookahead)<EOL>

Returns the DottedRule that results from moving the dot.


ret = set()<EOL>if EPSILON in symbols:<EOL><INDENT>return set([EPSILON])<EOL><DEDENT>for symbol in symbols:<EOL><INDENT>ret |= self._first[symbol] - set([EPSILON])<EOL>if EPSILON not in self._first[symbol]:<EOL><INDENT>break<EOL><DEDENT><DEDENT>else:<EOL><INDENT>ret.add(EPSILON)<EOL><DEDENT>return ret<EOL>

Computes the intermediate FIRST set using symbols.


for terminal in self.terminals:<EOL><INDENT>self._first[terminal].add(terminal)<EOL><DEDENT>self._first[END_OF_INPUT].add(END_OF_INPUT)<EOL>while True:<EOL><INDENT>changed = False<EOL>for nonterminal, productions in self.nonterminals.items():<EOL><INDENT>for production in productions:<EOL><INDENT>new_first = self.first(production.rhs)<EOL>if new_first - self._first[nonterminal]:<EOL><INDENT>self._first[nonterminal] |= new_first<EOL>changed = True<EOL><DEDENT><DEDENT><DEDENT>if not changed:<EOL><INDENT>break<EOL><DEDENT><DEDENT>

Computes the FIRST set for every symbol in the grammar.

        Tenatively based on _compute_first in PLY.


self._follow[self.start_symbol].add(END_OF_INPUT)<EOL>while True:<EOL><INDENT>changed = False<EOL>for nonterminal, productions in self.nonterminals.items():<EOL><INDENT>for production in productions:<EOL><INDENT>for i, symbol in enumerate(production.rhs):<EOL><INDENT>if symbol not in self.nonterminals:<EOL><INDENT>continue<EOL><DEDENT>first = self.first(production.rhs[i + <NUM_LIT:1>:])<EOL>new_follow = first - set([EPSILON])<EOL>if EPSILON in first or i == (len(production.rhs) - <NUM_LIT:1>):<EOL><INDENT>new_follow |= self._follow[nonterminal]<EOL><DEDENT>if new_follow - self._follow[symbol]:<EOL><INDENT>self._follow[symbol] |= new_follow<EOL>changed = True<EOL><DEDENT><DEDENT><DEDENT><DEDENT>if not changed:<EOL><INDENT>break<EOL><DEDENT><DEDENT>

Computes the FOLLOW set for every non-terminal in the grammar.

        Tenatively based on _compute_follow in PLY.


first_rule = DottedRule(self.start, <NUM_LIT:0>, END_OF_INPUT)<EOL>return self.closure([first_rule])<EOL>

Computes the initial closure using the START_foo production.


return self.closure(<EOL>{rule.move_dot() for rule in rules<EOL>if not rule.at_end and rule.rhs[rule.pos] == symbol},<EOL>)<EOL>

Computes the next closure for rules based on the symbol we got.

        Args:
            rules - an iterable of DottedRules
            symbol - a string denoting the symbol we've just seen

        Returns: frozenset of DottedRules


closure = set()<EOL>todo = set(rules)<EOL>while todo:<EOL><INDENT>rule = todo.pop()<EOL>closure.add(rule)<EOL>if rule.at_end:<EOL><INDENT>continue<EOL><DEDENT>symbol = rule.rhs[rule.pos]<EOL>for production in self.nonterminals[symbol]:<EOL><INDENT>for first in self.first(rule.rest):<EOL><INDENT>if EPSILON in production.rhs:<EOL><INDENT>new_rule = DottedRule(production, <NUM_LIT:1>, first)<EOL><DEDENT>else:<EOL><INDENT>new_rule = DottedRule(production, <NUM_LIT:0>, first)<EOL><DEDENT>if new_rule not in closure:<EOL><INDENT>todo.add(new_rule)<EOL><DEDENT><DEDENT><DEDENT><DEDENT>return frozenset(closure)<EOL>

Fills out the entire closure based on some initial dotted rules.

        Args:
            rules - an iterable of DottedRules

        Returns: frozenset of DottedRules


initial = self.initial_closure()<EOL>closures = collections.OrderedDict()<EOL>goto = collections.defaultdict(dict)<EOL>todo = set([initial])<EOL>while todo:<EOL><INDENT>closure = todo.pop()<EOL>closures[closure] = closure<EOL>symbols = {rule.rhs[rule.pos] for rule in closure<EOL>if not rule.at_end}<EOL>for symbol in symbols:<EOL><INDENT>next_closure = self.goto(closure, symbol)<EOL>if next_closure in closures or next_closure in todo:<EOL><INDENT>next_closure = (closures.get(next_closure)<EOL>or todo.get(next_closure))<EOL><DEDENT>else:<EOL><INDENT>closures[next_closure] = next_closure<EOL>todo.add(next_closure)<EOL><DEDENT>goto[closure][symbol] = next_closure<EOL><DEDENT><DEDENT>return initial, closures, goto<EOL>

Computes all LR(1) closure sets for the grammar.


@staticmethod<EOL><INDENT>def compute_precedence(terminals, productions, precedence_levels):<DEDENT>

precedence = collections.OrderedDict()<EOL>for terminal in terminals:<EOL><INDENT>precedence[terminal] = DEFAULT_PREC<EOL><DEDENT>level_precs = range(len(precedence_levels), <NUM_LIT:0>, -<NUM_LIT:1>)<EOL>for i, level in zip(level_precs, precedence_levels):<EOL><INDENT>assoc = level[<NUM_LIT:0>]<EOL>for symbol in level[<NUM_LIT:1>:]:<EOL><INDENT>precedence[symbol] = (assoc, i)<EOL><DEDENT><DEDENT>for production, prec_symbol in productions:<EOL><INDENT>if prec_symbol is None:<EOL><INDENT>prod_terminals = [symbol for symbol in production.rhs<EOL>if symbol in terminals] or [None]<EOL>precedence[production] = precedence.get(prod_terminals[-<NUM_LIT:1>],<EOL>DEFAULT_PREC)<EOL><DEDENT>else:<EOL><INDENT>precedence[production] = precedence.get(prec_symbol,<EOL>DEFAULT_PREC)<EOL><DEDENT><DEDENT>return precedence<EOL>

Computes the precedence of terminal and production.

        The precedence of a terminal is it's level in the PRECEDENCE tuple. For
        a production, the precedence is the right-most terminal (if it exists).
        The default precedence is DEFAULT_PREC - (LEFT, 0).

        Returns:
            precedence - dict[terminal | production] = (assoc, level)


ACTION = {}<EOL>GOTO = {}<EOL>labels = {}<EOL>def get_label(closure):<EOL><INDENT>if closure not in labels:<EOL><INDENT>labels[closure] = len(labels)<EOL><DEDENT>return labels[closure]<EOL><DEDENT>def resolve_shift_reduce(lookahead, s_action, r_action):<EOL><INDENT>s_assoc, s_level = precedence[lookahead]<EOL>r_assoc, r_level = precedence[r_action[<NUM_LIT:1>]]<EOL>if s_level < r_level:<EOL><INDENT>return r_action<EOL><DEDENT>elif s_level == r_level and r_assoc == LEFT:<EOL><INDENT>return r_action<EOL><DEDENT>else:<EOL><INDENT>return s_action<EOL><DEDENT><DEDENT>initial, closures, goto = grammar.closures()<EOL>for closure in closures:<EOL><INDENT>label = get_label(closure)<EOL>for rule in closure:<EOL><INDENT>new_action, lookahead = None, rule.lookahead<EOL>if not rule.at_end:<EOL><INDENT>symbol = rule.rhs[rule.pos]<EOL>is_terminal = symbol in grammar.terminals<EOL>has_goto = symbol in goto[closure]<EOL>if is_terminal and has_goto:<EOL><INDENT>next_state = get_label(goto[closure][symbol])<EOL>new_action, lookahead = ('<STR_LIT>', next_state), symbol<EOL><DEDENT><DEDENT>elif rule.production == grammar.start and rule.at_end:<EOL><INDENT>new_action = ('<STR_LIT>',)<EOL><DEDENT>elif rule.at_end:<EOL><INDENT>new_action = ('<STR_LIT>', rule.production)<EOL><DEDENT>if new_action is None:<EOL><INDENT>continue<EOL><DEDENT>prev_action = ACTION.get((label, lookahead))<EOL>if prev_action is None or prev_action == new_action:<EOL><INDENT>ACTION[label, lookahead] = new_action<EOL><DEDENT>else:<EOL><INDENT>types = (prev_action[<NUM_LIT:0>], new_action[<NUM_LIT:0>])<EOL>if types == ('<STR_LIT>', '<STR_LIT>'):<EOL><INDENT>chosen = resolve_shift_reduce(lookahead,<EOL>prev_action,<EOL>new_action)<EOL><DEDENT>elif types == ('<STR_LIT>', '<STR_LIT>'):<EOL><INDENT>chosen = resolve_shift_reduce(lookahead,<EOL>new_action,<EOL>prev_action)<EOL><DEDENT>else:<EOL><INDENT>raise TableConflictError(prev_action, new_action)<EOL><DEDENT>ACTION[label, lookahead] = chosen<EOL><DEDENT><DEDENT>for symbol in grammar.nonterminals:<EOL><INDENT>if symbol in goto[closure]:<EOL><INDENT>GOTO[label, symbol] = get_label(goto[closure][symbol])<EOL><DEDENT><DEDENT><DEDENT>return get_label(initial), ACTION, GOTO<EOL>

Generates the ACTION and GOTO tables for the grammar.

        Returns:
            action - dict[state][lookahead] = (action, ...)
            goto - dict[state][just_reduced] = new_state


lexer = self.LEXER(raw)<EOL>tokens = iter(itertools.chain(lexer, [END_OF_INPUT_TOKEN]))<EOL>stack = [(self.INITIAL_STATE, '<STR_LIT>', '<STR_LIT>')]<EOL>token = next(tokens)<EOL>while stack:<EOL><INDENT>state, _, _ = stack[-<NUM_LIT:1>]<EOL>action = self.ACTION.get((state, token.name))<EOL>if action is None:<EOL><INDENT>raise StartSymbolNotReducedError(self.START)<EOL><DEDENT>if action[<NUM_LIT:0>] == '<STR_LIT>':<EOL><INDENT>production = action[<NUM_LIT:1>]<EOL>if len(production):<EOL><INDENT>args = (item[<NUM_LIT:2>] for item in stack[-len(production):])<EOL>del stack[-len(production):]<EOL><DEDENT>else:<EOL><INDENT>args = []<EOL><DEDENT>prev_state, _, _ = stack[-<NUM_LIT:1>]<EOL>new_state = self.GOTO[prev_state, production.lhs]<EOL>stack.append((<EOL>new_state,<EOL>production.lhs,<EOL>production.func(self, *args),<EOL>))<EOL><DEDENT>elif action[<NUM_LIT:0>] == '<STR_LIT>':<EOL><INDENT>stack.append((action[<NUM_LIT:1>], token.name, token.value))<EOL>token = next(tokens)<EOL><DEDENT>elif action[<NUM_LIT:0>] == '<STR_LIT>':<EOL><INDENT>return stack[-<NUM_LIT:1>][<NUM_LIT:2>]<EOL><DEDENT><DEDENT>

Parses an input string and applies the parser's grammar.


return Response('<STR_LIT>')<EOL>

Works for `functional` views too!
Yeah, that thing rocks!
And allows formatting {}


def decorator(func):<EOL><INDENT>if serializer_class:<EOL><INDENT>func.cls.serializer_class = func.view_class.serializer_class = serializer_class<EOL><DEDENT>if response_serializer_class:<EOL><INDENT>func.cls.response_serializer_class = func.view_class.response_serializer_class = response_serializer_class<EOL><DEDENT>if filter_backends:<EOL><INDENT>func.cls.filter_backends = func.view_class.filter_backends = filter_backends<EOL><DEDENT>if permission_classes:<EOL><INDENT>func.cls.permission_classes = func.view_class.permission_classes = permission_classes<EOL><DEDENT>if authentication_classes:<EOL><INDENT>func.cls.authentication_classes = func.view_class.authentication_classes = authentication_classes<EOL><DEDENT>if doc_format_args or doc_format_kwargs:<EOL><INDENT>func.cls.__doc__ = func.view_class.__doc__ = getdoc(func).format(*doc_format_args, **doc_format_kwargs)<EOL><DEDENT>return func<EOL><DEDENT>return decorator<EOL>

Decorator to make functional view documentable via drf-autodocs


def decorator(func):<EOL><INDENT>func.__doc__ = getdoc(func).format(*args, **kwargs)<EOL>return func<EOL><DEDENT>return decorator<EOL>

Decorator for clean docstring formatting


(szip, dzip) = (src.endswith("<STR_LIT>"), dst.endswith("<STR_LIT>"))<EOL>logging.info("<STR_LIT>"%(src, dst))<EOL>if szip and dzip:<EOL><INDENT>shutil.copy2(src, dst)<EOL><DEDENT>elif szip:<EOL><INDENT>with zipfile.ZipFile(src, mode='<STR_LIT:r>') as z:<EOL><INDENT>tmpdir = tempfile.mkdtemp()<EOL>try:<EOL><INDENT>z.extractall(tmpdir)<EOL>if len(z.namelist()) != <NUM_LIT:1>:<EOL><INDENT>raise RuntimeError("<STR_LIT>""<STR_LIT>"%src)<EOL><DEDENT>tmpfile = join(tmpdir,z.namelist()[<NUM_LIT:0>])<EOL>try:<EOL><INDENT>os.remove(dst)<EOL><DEDENT>except OSError:<EOL><INDENT>pass<EOL><DEDENT>shutil.move(tmpfile, dst)<EOL><DEDENT>finally:<EOL><INDENT>shutil.rmtree(tmpdir, ignore_errors=True)<EOL><DEDENT><DEDENT><DEDENT>elif dzip:<EOL><INDENT>with zipfile.ZipFile(dst, mode='<STR_LIT:w>', compression=ZIP_DEFLATED) as z:<EOL><INDENT>z.write(src, arcname=basename(src))<EOL><DEDENT><DEDENT>else:<EOL><INDENT>shutil.copy2(src, dst)<EOL><DEDENT>

File copy that support compress and decompress of zip files


try:<EOL><INDENT>if isfile(path):<EOL><INDENT>os.remove(path)<EOL><DEDENT>else:<EOL><INDENT>shutil.rmtree(path, ignore_errors=True)<EOL><DEDENT><DEDENT>except OSError:<EOL><INDENT>pass<EOL><DEDENT>


def apply_changesets(args, changesets, catalog):

tmpdir = tempfile.mkdtemp()<EOL>tmp_patch = join(tmpdir, "<STR_LIT>")<EOL>tmp_lcat  = join(tmpdir, "<STR_LIT>")<EOL>for node in changesets:<EOL><INDENT>remove(tmp_patch)<EOL>copy(node.mfile['<STR_LIT>']['<STR_LIT:filename>'], tmp_patch)<EOL>logging.info("<STR_LIT>"%(catalog, tmp_lcat))<EOL>shutil.move(catalog, tmp_lcat)<EOL>cmd = args.patch_cmd.replace("<STR_LIT>", tmp_lcat).replace("<STR_LIT>", tmp_patch).replace("<STR_LIT>", catalog)<EOL>logging.info("<STR_LIT>"%cmd)<EOL>subprocess.check_call(cmd, shell=True)<EOL><DEDENT>shutil.rmtree(tmpdir, ignore_errors=True)<EOL>

Apply to the 'catalog' the changesets in the metafile list 'changesets


lockfile = "<STR_LIT>"%filename<EOL>if isfile(lockfile):<EOL><INDENT>return False<EOL><DEDENT>else:<EOL><INDENT>with open(lockfile, "<STR_LIT:w>"):<EOL><INDENT>pass<EOL><DEDENT><DEDENT>return True<EOL>

Locks the file by writing a '.lock' file.
       Returns True when the file is locked and
       False when the file was locked already


lockfile = "<STR_LIT>"%filename<EOL>if isfile(lockfile):<EOL><INDENT>os.remove(lockfile)<EOL>return True<EOL><DEDENT>else:<EOL><INDENT>return False<EOL><DEDENT>

Unlocks the file by remove a '.lock' file.
       Returns True when the file is unlocked and
       False when the file was unlocked already


def copy_smart_previews(local_catalog, cloud_catalog, local2cloud=True):

lcat_noext = local_catalog[<NUM_LIT:0>:local_catalog.rfind("<STR_LIT>")]<EOL>ccat_noext = cloud_catalog[<NUM_LIT:0>:cloud_catalog.rfind("<STR_LIT>")]<EOL>lsmart = join(dirname(local_catalog),"<STR_LIT>"%basename(lcat_noext))<EOL>csmart = join(dirname(cloud_catalog),"<STR_LIT>"%basename(ccat_noext))<EOL>if local2cloud and os.path.isdir(lsmart):<EOL><INDENT>logging.info("<STR_LIT>"%(lsmart, csmart))<EOL>distutils.dir_util.copy_tree(lsmart,csmart, update=<NUM_LIT:1>)<EOL><DEDENT>elif os.path.isdir(csmart):<EOL><INDENT>logging.info("<STR_LIT>"%(csmart, lsmart))<EOL>distutils.dir_util.copy_tree(csmart,lsmart, update=<NUM_LIT:1>)<EOL><DEDENT>

Copy Smart Previews from local to cloud or
       vica versa when 'local2cloud==False'
       NB: nothing happens if source dir doesn't exist


with open(filename, mode='<STR_LIT:rb>') as f:<EOL><INDENT>d = hashlib.sha1()<EOL>for buf in iter(partial(f.read, <NUM_LIT:2>**<NUM_LIT:20>), b'<STR_LIT>'):<EOL><INDENT>d.update(buf)<EOL><DEDENT><DEDENT>return d.hexdigest()<EOL>

Return a hash of the file From <http://stackoverflow.com/a/7829658>


(lcat, ccat) = (args.local_catalog, args.cloud_catalog)<EOL>logging.info("<STR_LIT>"%(lcat, ccat))<EOL>if not isfile(lcat):<EOL><INDENT>args.error("<STR_LIT>"%lcat)<EOL><DEDENT>if isfile(ccat):<EOL><INDENT>args.error("<STR_LIT>"%ccat)<EOL><DEDENT>(lmeta, cmeta) = ("<STR_LIT>"%lcat, "<STR_LIT>"%ccat)<EOL>if isfile(lmeta):<EOL><INDENT>args.error("<STR_LIT>"%lmeta)<EOL><DEDENT>if isfile(cmeta):<EOL><INDENT>args.error("<STR_LIT>"%cmeta)<EOL><DEDENT>logging.info("<STR_LIT>"%(lcat))<EOL>if not lock_file(lcat):<EOL><INDENT>raise RuntimeError("<STR_LIT>"%lcat)<EOL><DEDENT>util.copy(lcat, ccat)<EOL>mfile = MetaFile(lmeta)<EOL>utcnow = datetime.utcnow().strftime(DATETIME_FORMAT)[:-<NUM_LIT:4>]<EOL>mfile['<STR_LIT>']['<STR_LIT>'] = hashsum(lcat)<EOL>mfile['<STR_LIT>']['<STR_LIT>'] = utcnow<EOL>mfile['<STR_LIT>']['<STR_LIT:filename>'] = lcat<EOL>mfile['<STR_LIT>']['<STR_LIT:filename>'] = ccat<EOL>mfile['<STR_LIT>']['<STR_LIT>'] = hashsum(lcat)<EOL>mfile['<STR_LIT>']['<STR_LIT>'] = utcnow<EOL>mfile.flush()<EOL>mfile = MetaFile(cmeta)<EOL>mfile['<STR_LIT>']['<STR_LIT>'] = True<EOL>mfile['<STR_LIT>']['<STR_LIT>'] = hashsum(lcat)<EOL>mfile['<STR_LIT>']['<STR_LIT>'] = utcnow<EOL>mfile['<STR_LIT>']['<STR_LIT:filename>'] = basename(ccat)<EOL>mfile.flush()<EOL>if not args.no_smart_previews:<EOL><INDENT>copy_smart_previews(lcat, ccat, local2cloud=True)<EOL><DEDENT>logging.info("<STR_LIT>"%(lcat))<EOL>unlock_file(lcat)<EOL>logging.info("<STR_LIT>")<EOL>

Initiate the local catalog and push it the cloud


(lcat, ccat) = (args.local_catalog, args.cloud_catalog)<EOL>logging.info("<STR_LIT>"%(ccat, lcat))<EOL>if isfile(lcat):<EOL><INDENT>args.error("<STR_LIT>"%lcat)<EOL><DEDENT>if not isfile(ccat):<EOL><INDENT>args.error("<STR_LIT>"%ccat)<EOL><DEDENT>(lmeta, cmeta) = ("<STR_LIT>"%lcat, "<STR_LIT>"%ccat)<EOL>if isfile(lmeta):<EOL><INDENT>args.error("<STR_LIT>"%lmeta)<EOL><DEDENT>if not isfile(cmeta):<EOL><INDENT>args.error("<STR_LIT>"%cmeta)<EOL><DEDENT>logging.info("<STR_LIT>"%(lcat))<EOL>if not lock_file(lcat):<EOL><INDENT>raise RuntimeError("<STR_LIT>"%lcat)<EOL><DEDENT>util.copy(ccat, lcat)<EOL>cloudDAG = ChangesetDAG(ccat)<EOL>path = cloudDAG.path(cloudDAG.root.hash, cloudDAG.leafs[<NUM_LIT:0>].hash)<EOL>util.apply_changesets(args, path, lcat)<EOL>mfile = MetaFile(lmeta)<EOL>utcnow = datetime.utcnow().strftime(DATETIME_FORMAT)[:-<NUM_LIT:4>]<EOL>mfile['<STR_LIT>']['<STR_LIT>'] = hashsum(lcat)<EOL>mfile['<STR_LIT>']['<STR_LIT>'] = utcnow<EOL>mfile['<STR_LIT>']['<STR_LIT:filename>'] = lcat<EOL>mfile['<STR_LIT>']['<STR_LIT:filename>'] = cloudDAG.leafs[<NUM_LIT:0>].mfile['<STR_LIT>']['<STR_LIT:filename>']<EOL>mfile['<STR_LIT>']['<STR_LIT>'] = cloudDAG.leafs[<NUM_LIT:0>].mfile['<STR_LIT>']['<STR_LIT>']<EOL>mfile['<STR_LIT>']['<STR_LIT>'] = cloudDAG.leafs[<NUM_LIT:0>].mfile['<STR_LIT>']['<STR_LIT>']<EOL>mfile.flush()<EOL>if not args.no_smart_previews:<EOL><INDENT>copy_smart_previews(lcat, ccat, local2cloud=False)<EOL><DEDENT>logging.info("<STR_LIT>"%(lcat))<EOL>unlock_file(lcat)<EOL>logging.info("<STR_LIT>")<EOL>

Initiate the local catalog by downloading the cloud catalog


logging.info("<STR_LIT>")<EOL>(lcat, ccat) = (args.local_catalog, args.cloud_catalog)<EOL>(lmeta, cmeta) = ("<STR_LIT>"%lcat, "<STR_LIT>"%ccat)<EOL>if not isfile(lcat):<EOL><INDENT>args.error("<STR_LIT>"%lcat)<EOL><DEDENT>if not isfile(ccat):<EOL><INDENT>args.error("<STR_LIT>"%ccat)<EOL><DEDENT>logging.info("<STR_LIT>"%(lcat))<EOL>if not lock_file(lcat):<EOL><INDENT>raise RuntimeError("<STR_LIT>"%lcat)<EOL><DEDENT>logging.info("<STR_LIT>"%lcat)<EOL>util.remove("<STR_LIT>"%lcat)<EOL>util.copy(lcat, "<STR_LIT>"%lcat)<EOL>lmfile = MetaFile(lmeta)<EOL>cmfile = MetaFile(cmeta)<EOL>cloudDAG = ChangesetDAG(ccat)<EOL>path = cloudDAG.path(lmfile['<STR_LIT>']['<STR_LIT>'], cloudDAG.leafs[<NUM_LIT:0>].hash)<EOL>util.apply_changesets(args, path, lcat)<EOL>if not args.no_smart_previews:<EOL><INDENT>copy_smart_previews(lcat, ccat, local2cloud=False)<EOL><DEDENT>logging.info("<STR_LIT>"%lcat)<EOL>util.remove("<STR_LIT>"%lcat)<EOL>util.copy(lcat, "<STR_LIT>"%lcat)<EOL>logging.info("<STR_LIT>"%(lcat))<EOL>unlock_file(lcat)<EOL>if args.lightroom_exec_debug:<EOL><INDENT>logging.info("<STR_LIT>"%(args.lightroom_exec_debug, lcat))<EOL>with open(lcat, "<STR_LIT:a>") as f:<EOL><INDENT>f.write("<STR_LIT>"%args.lightroom_exec_debug)<EOL><DEDENT><DEDENT>elif args.lightroom_exec:<EOL><INDENT>logging.info("<STR_LIT>"%(args.lightroom_exec, lcat))<EOL>subprocess.call([args.lightroom_exec, lcat])<EOL><DEDENT>tmpdir = tempfile.mkdtemp()<EOL>tmp_patch = join(tmpdir, "<STR_LIT>")<EOL>diff_cmd = args.diff_cmd.replace("<STR_LIT>", "<STR_LIT>"%lcat).replace("<STR_LIT>", lcat).replace("<STR_LIT>", tmp_patch)<EOL>logging.info("<STR_LIT>"%diff_cmd)<EOL>subprocess.call(diff_cmd, shell=True)<EOL>patch = "<STR_LIT>"%(ccat, hashsum(tmp_patch))<EOL>util.copy(tmp_patch, patch)<EOL>mfile = MetaFile("<STR_LIT>"%patch)<EOL>utcnow = datetime.utcnow().strftime(DATETIME_FORMAT)[:-<NUM_LIT:4>]<EOL>mfile['<STR_LIT>']['<STR_LIT>'] = False<EOL>mfile['<STR_LIT>']['<STR_LIT>'] = hashsum(tmp_patch)<EOL>mfile['<STR_LIT>']['<STR_LIT>'] = utcnow<EOL>mfile['<STR_LIT>']['<STR_LIT:filename>'] = basename(patch)<EOL>mfile['<STR_LIT>']['<STR_LIT>']          = cloudDAG.leafs[<NUM_LIT:0>].mfile['<STR_LIT>']['<STR_LIT>']<EOL>mfile['<STR_LIT>']['<STR_LIT>']             = cloudDAG.leafs[<NUM_LIT:0>].mfile['<STR_LIT>']['<STR_LIT>']<EOL>mfile['<STR_LIT>']['<STR_LIT>'] = cloudDAG.leafs[<NUM_LIT:0>].mfile['<STR_LIT>']['<STR_LIT>']<EOL>mfile['<STR_LIT>']['<STR_LIT:filename>']         = basename(cloudDAG.leafs[<NUM_LIT:0>].mfile['<STR_LIT>']['<STR_LIT:filename>'])<EOL>mfile.flush()<EOL>mfile = MetaFile(lmeta)<EOL>mfile['<STR_LIT>']['<STR_LIT>'] = hashsum(lcat)<EOL>mfile['<STR_LIT>']['<STR_LIT>'] = utcnow<EOL>mfile['<STR_LIT>']['<STR_LIT:filename>'] = patch<EOL>mfile['<STR_LIT>']['<STR_LIT>'] = hashsum(tmp_patch)<EOL>mfile['<STR_LIT>']['<STR_LIT>'] = utcnow<EOL>mfile.flush()<EOL>shutil.rmtree(tmpdir, ignore_errors=True)<EOL>if not args.no_smart_previews:<EOL><INDENT>copy_smart_previews(lcat, ccat, local2cloud=True)<EOL><DEDENT>logging.info("<STR_LIT>"%(lcat))<EOL>unlock_file(lcat)<EOL>

Normal procedure:
        * Pull from cloud (if necessary)
        * Run Lightroom
        * Push to cloud


def default_config_path():<EOL><INDENT>"""<STR_LIT>"""<EOL>if os.name == "<STR_LIT>":<EOL><INDENT>return join(os.getenv('<STR_LIT>'), "<STR_LIT>")<EOL><DEDENT>else:<EOL><INDENT>return join(os.path.expanduser("<STR_LIT>"), "<STR_LIT>")<EOL><DEDENT><DEDENT>parser = argparse.ArgumentParser(<EOL>description='<STR_LIT>',<EOL>formatter_class=argparse.ArgumentDefaultsHelpFormatter)<EOL>cmd_group = parser.add_mutually_exclusive_group()<EOL>cmd_group.add_argument(<EOL>'<STR_LIT>',<EOL>help='<STR_LIT>',<EOL>action="<STR_LIT:store_true>"<EOL>)<EOL>cmd_group.add_argument(<EOL>'<STR_LIT>',<EOL>help='<STR_LIT>',<EOL>action="<STR_LIT:store_true>"<EOL>)<EOL>parser.add_argument(<EOL>'<STR_LIT>',<EOL>help='<STR_LIT>',<EOL>type=lambda x: os.path.expanduser(x)<EOL>)<EOL>parser.add_argument(<EOL>'<STR_LIT>',<EOL>help='<STR_LIT>',<EOL>type=lambda x: os.path.expanduser(x)<EOL>)<EOL>lr_exec = parser.add_mutually_exclusive_group()<EOL>lr_exec.add_argument(<EOL>'<STR_LIT>',<EOL>help='<STR_LIT>',<EOL>type=str<EOL>)<EOL>lr_exec.add_argument(<EOL>'<STR_LIT>',<EOL>help='<STR_LIT>',<EOL>type=str<EOL>)<EOL>parser.add_argument(<EOL>'<STR_LIT>', '<STR_LIT>',<EOL>help='<STR_LIT>',<EOL>action="<STR_LIT:store_true>"<EOL>)<EOL>parser.add_argument(<EOL>'<STR_LIT>',<EOL>help="<STR_LIT>",<EOL>action="<STR_LIT:store_true>"<EOL>)<EOL>parser.add_argument(<EOL>'<STR_LIT>',<EOL>help="<STR_LIT>",<EOL>type=str,<EOL>default=default_config_path()<EOL>)<EOL>parser.add_argument(<EOL>'<STR_LIT>',<EOL>help="<STR_LIT>"<EOL>"<STR_LIT>",<EOL>type=str,<EOL>)<EOL>parser.add_argument(<EOL>'<STR_LIT>',<EOL>help="<STR_LIT>"<EOL>"<STR_LIT>",<EOL>type=str,<EOL>)<EOL>args = parser.parse_args(args=argv)<EOL>args.error = parser.error<EOL>if args.config_file in ['<STR_LIT>', '<STR_LIT:none>', '<STR_LIT:None>', "<STR_LIT>", '<STR_LIT>']:<EOL><INDENT>args.config_file = None<EOL><DEDENT>if args.verbose:<EOL><INDENT>logging.basicConfig(level=logging.INFO)<EOL><DEDENT>config_parser.read(args)<EOL>(lcat, ccat) = (args.local_catalog, args.cloud_catalog)<EOL>if lcat is None:<EOL><INDENT>parser.error("<STR_LIT>")<EOL><DEDENT>if ccat is None:<EOL><INDENT>parser.error("<STR_LIT>")<EOL><DEDENT>return args<EOL>


def _path(a, b):<EOL><INDENT>if a is b:<EOL><INDENT>return [a]<EOL><DEDENT>else:<EOL><INDENT>assert len(a.children) == <NUM_LIT:1><EOL>return [a] + _path(a.children[<NUM_LIT:0>], b)<EOL><DEDENT><DEDENT>a = self.nodes[a_hash]<EOL>b = self.nodes[b_hash]<EOL>return _path(a, b)[<NUM_LIT:1>:]<EOL>

Return nodes in the path between 'a' and 'b' going from
        parent to child NOT including 'a


if args.config_file is None or not isfile(args.config_file):<EOL><INDENT>return<EOL><DEDENT>logging.info("<STR_LIT>"%args.config_file)<EOL>config = cparser.ConfigParser()<EOL>config.read(args.config_file)<EOL>if not config.has_section('<STR_LIT>'):<EOL><INDENT>raise RuntimeError("<STR_LIT>")<EOL><DEDENT>for (name, value) in config.items('<STR_LIT>'):<EOL><INDENT>if value == "<STR_LIT:True>":<EOL><INDENT>value = True<EOL><DEDENT>elif value == "<STR_LIT:False>":<EOL><INDENT>value = False<EOL><DEDENT>if getattr(args, name) is None:<EOL><INDENT>setattr(args, name, value)<EOL><DEDENT><DEDENT>

Reading the configure file and adds non-existing attributes to 'args


logging.info("<STR_LIT>"%args.config_file)<EOL>if args.config_file is None:<EOL><INDENT>return<EOL><DEDENT>config = cparser.ConfigParser()<EOL>config.add_section("<STR_LIT>")<EOL>for p in [x for x in dir(args) if not x.startswith("<STR_LIT:_>")]:<EOL><INDENT>if p in IGNORE_ARGS:<EOL><INDENT>continue<EOL><DEDENT>value = getattr(args, p)<EOL>if value is not None:<EOL><INDENT>config.set('<STR_LIT>', p, str(value))<EOL><DEDENT><DEDENT>with open(args.config_file, '<STR_LIT:w>') as f:<EOL><INDENT>config.write(f)<EOL><DEDENT>

Writing the configure file with the attributes in 'args


<EOL>serialized = []<EOL>for rule in rules:<EOL><INDENT>direction = rule["<STR_LIT>"]<EOL>source = '<STR_LIT>'<EOL>destination = '<STR_LIT>'<EOL>if rule.get("<STR_LIT>"):<EOL><INDENT>prefix = rule["<STR_LIT>"]<EOL>if direction == "<STR_LIT>":<EOL><INDENT>source = self._convert_remote_network(prefix)<EOL><DEDENT>else:<EOL><INDENT>if (Capabilities.EGRESS not in<EOL>CONF.QUARK.environment_capabilities):<EOL><INDENT>raise q_exc.EgressSecurityGroupRulesNotEnabled()<EOL><DEDENT>else:<EOL><INDENT>destination = self._convert_remote_network(prefix)<EOL><DEDENT><DEDENT><DEDENT>optional_fields = {}<EOL>protocol_map = protocols.PROTOCOL_MAP[rule["<STR_LIT>"]]<EOL>if rule["<STR_LIT>"] == protocol_map["<STR_LIT>"]:<EOL><INDENT>optional_fields["<STR_LIT>"] = rule["<STR_LIT>"]<EOL>optional_fields["<STR_LIT>"] = rule["<STR_LIT>"]<EOL><DEDENT>else:<EOL><INDENT>optional_fields["<STR_LIT>"] = rule["<STR_LIT>"]<EOL>optional_fields["<STR_LIT>"] = rule["<STR_LIT>"]<EOL><DEDENT>payload = {"<STR_LIT>": rule["<STR_LIT>"],<EOL>"<STR_LIT>": rule["<STR_LIT>"],<EOL>"<STR_LIT>": source,<EOL>"<STR_LIT>": destination,<EOL>"<STR_LIT:action>": "<STR_LIT>",<EOL>"<STR_LIT>": direction}<EOL>payload.update(optional_fields)<EOL>serialized.append(payload)<EOL><DEDENT>return serialized<EOL>


rules = []<EOL>for group in groups:<EOL><INDENT>rules.extend(self.serialize_rules(group.rules))<EOL><DEDENT>return rules<EOL>

Creates a payload for the redis server

        The rule schema is the following:

        REDIS KEY - port_device_id.port_mac_address/sg
        REDIS VALUE - A JSON dump of the following:

        port_mac_address must be lower-cased and stripped of non-alphanumeric
        characters

        {"id": "<arbitrary uuid>",
          "rules": [
            {"ethertype": <hexademical integer>,
             "protocol": <integer>,
             "port start": <integer>,  # optional
             "port end": <integer>,    # optional
             "icmp type": <integer>,   # optional
             "icmp code": <integer>,   # optional
             "source network": <string>,
             "destination network": <string>,
             "action": <string>,
             "direction": <string>},
          ],
          "security groups ack": <boolean>
        }

        Example:
        {"id": "004c6369-9f3d-4d33-b8f5-9416bf3567dd",
         "rules": [
           {"ethertype": 0x800,
            "protocol": "tcp",
            "port start": 1000,
            "port end": 1999,
            "source network": "10.10.10.0/24",
            "destination network": "",
            "action": "allow",
            "direction": "ingress"},
          ],
          "security groups ack": "true"
        }

        port start/end and icmp type/code are mutually exclusive pairs.


def apply_rules(self, device_id, mac_address, rules):

LOG.info("<STR_LIT>" %<EOL>(device_id, mac_address))<EOL>rule_dict = {SECURITY_GROUP_RULE_KEY: rules}<EOL>redis_key = self.vif_key(device_id, mac_address)<EOL>self.set_field(redis_key, SECURITY_GROUP_HASH_ATTR, rule_dict)<EOL>self.set_field_raw(redis_key, SECURITY_GROUP_ACK, False)<EOL>

Writes a series of security group rules to a redis server.


LOG.debug("<STR_LIT>".format(<EOL>interfaces))<EOL>interfaces = tuple(interfaces)<EOL>vif_keys = [self.vif_key(vif.device_id, vif.mac_address)<EOL>for vif in interfaces]<EOL>sec_grp_all = self.get_fields_all(vif_keys)<EOL>ret = {}<EOL>for vif, group in zip(interfaces, sec_grp_all):<EOL><INDENT>if group:<EOL><INDENT>ret[vif] = {SECURITY_GROUP_ACK: None,<EOL>SECURITY_GROUP_HASH_ATTR: []}<EOL>temp_ack = group[SECURITY_GROUP_ACK].lower()<EOL>temp_rules = group[SECURITY_GROUP_HASH_ATTR]<EOL>if temp_rules:<EOL><INDENT>temp_rules = json.loads(temp_rules)<EOL>ret[vif][SECURITY_GROUP_HASH_ATTR] = temp_rules["<STR_LIT>"]<EOL><DEDENT>if "<STR_LIT:true>" in temp_ack:<EOL><INDENT>ret[vif][SECURITY_GROUP_ACK] = True<EOL><DEDENT>elif "<STR_LIT:false>" in temp_ack:<EOL><INDENT>ret[vif][SECURITY_GROUP_ACK] = False<EOL><DEDENT>else:<EOL><INDENT>ret.pop(vif, None)<EOL>LOG.debug("<STR_LIT>" % temp_ack)<EOL><DEDENT><DEDENT><DEDENT>return ret<EOL>

Gets security groups for interfaces from Redis

        Returns a dictionary of xapi.VIFs with values of the current
        acknowledged status in Redis.

        States not explicitly handled:
        * ack key, no rules - This is the same as just tagging the VIF,
          the instance will be inaccessible
        * rules key, no ack - Nothing will happen, the VIF will
          not be tagged.


@utils.retry_loop(<NUM_LIT:3>)<EOL><INDENT>def update_group_states_for_vifs(self, vifs, ack):<DEDENT>

vif_keys = [self.vif_key(vif.device_id, vif.mac_address)<EOL>for vif in vifs]<EOL>self.set_fields(vif_keys, SECURITY_GROUP_ACK, ack)<EOL>

Updates security groups by setting the ack field


body = {"<STR_LIT:id>": job.get('<STR_LIT:id>'),<EOL>"<STR_LIT:action>": job.get('<STR_LIT:action>'),<EOL>"<STR_LIT>": job.get('<STR_LIT>'),<EOL>"<STR_LIT>": job.get('<STR_LIT>'),<EOL>"<STR_LIT>": job.get('<STR_LIT>'),<EOL>"<STR_LIT>": job.get('<STR_LIT>'),<EOL>"<STR_LIT>": job.get('<STR_LIT>', None)}<EOL>if not body['<STR_LIT>']:<EOL><INDENT>body['<STR_LIT>'] = job.get('<STR_LIT:id>')<EOL><DEDENT>completed = <NUM_LIT:0><EOL>for sub in job.subtransactions:<EOL><INDENT>if sub.get('<STR_LIT>'):<EOL><INDENT>completed += <NUM_LIT:1><EOL><DEDENT><DEDENT>pct = <NUM_LIT:100> if job.get('<STR_LIT>') else <NUM_LIT:0><EOL>if len(job.subtransactions) > <NUM_LIT:0>:<EOL><INDENT>pct = float(completed) / len(job.subtransactions) * <NUM_LIT><EOL><DEDENT>body['<STR_LIT>'] = int(pct)<EOL>body['<STR_LIT>'] = completed<EOL>body['<STR_LIT>'] = len(job.subtransactions)<EOL>return body<EOL>

Creates the view for a job while calculating progress.

    Since a root job does not have a transaction id (TID) it will return its
    id as the TID.


conf = global_conf.copy()<EOL>conf.update(local_conf)<EOL>def wrapper(app):<EOL><INDENT>return ResponseAsyncIdAdder(app, conf)<EOL><DEDENT>return wrapper<EOL>

Returns a WSGI filter app for use with paste.deploy.


resp = self._get_resp(req)<EOL>context = self._get_ctx(req)<EOL>if hasattr(context, '<STR_LIT>'):<EOL><INDENT>try:<EOL><INDENT>json_body = json.loads(resp.body)<EOL>json_body['<STR_LIT>'] = context.async_job['<STR_LIT>']['<STR_LIT:id>']<EOL>resp.body = json.dumps(json_body)<EOL>resp.headers['<STR_LIT>'] = context.async_job['<STR_LIT>']['<STR_LIT:id>']<EOL><DEDENT>except ValueError:  <EOL><INDENT>return resp<EOL><DEDENT>except Exception as e:  <EOL><INDENT>LOG.error("<STR_LIT>" % e)<EOL><DEDENT><DEDENT>return resp<EOL>

Attempts to put the job_id into the response body and header.


def delete_locks(context, network_ids, addresses):

addresses_no_longer_null_routed = _find_addresses_to_be_unlocked(<EOL>context, network_ids, addresses)<EOL>LOG.info("<STR_LIT>",<EOL>len(addresses_no_longer_null_routed),<EOL>[addr.id for addr in addresses_no_longer_null_routed])<EOL>for address in addresses_no_longer_null_routed:<EOL><INDENT>lock_holder = None<EOL>try:<EOL><INDENT>lock_holder = db_api.lock_holder_find(<EOL>context, lock_id=address.lock_id, name=LOCK_NAME,<EOL>scope=db_api.ONE)<EOL>if lock_holder:<EOL><INDENT>db_api.lock_holder_delete(context, address, lock_holder)<EOL><DEDENT><DEDENT>except Exception:<EOL><INDENT>LOG.exception("<STR_LIT>", lock_holder)<EOL>continue<EOL><DEDENT><DEDENT>context.session.flush()<EOL>

Deletes locks for each IP address that is no longer null-routed.


def create_locks(context, network_ids, addresses):

for address in addresses:<EOL><INDENT>address_model = None<EOL>try:<EOL><INDENT>address_model = _find_or_create_address(<EOL>context, network_ids, address)<EOL>lock_holder = None<EOL>if address_model.lock_id:<EOL><INDENT>lock_holder = db_api.lock_holder_find(<EOL>context,<EOL>lock_id=address_model.lock_id, name=LOCK_NAME,<EOL>scope=db_api.ONE)<EOL><DEDENT>if not lock_holder:<EOL><INDENT>LOG.info("<STR_LIT>",<EOL>address_model.address_readable,<EOL>address_model.id)<EOL>db_api.lock_holder_create(<EOL>context, address_model, name=LOCK_NAME, type="<STR_LIT>")<EOL><DEDENT><DEDENT>except Exception:<EOL><INDENT>LOG.exception("<STR_LIT>",<EOL>address_model)<EOL>continue<EOL><DEDENT><DEDENT>context.session.flush()<EOL>

Creates locks for each IP address that is null-routed.

    The function creates the IP address if it is not present in the database.


query = context.session.query(models.IPAddress)<EOL>period_start, period_end = billing.calc_periods()<EOL>ip_list = billing.build_full_day_ips(query, period_start, period_end)<EOL>import random<EOL>ind = random.randint(<NUM_LIT:0>, len(ip_list) - <NUM_LIT:1>)<EOL>address = ip_list[ind]<EOL>address.allocated_at = datetime.datetime.utcnow() -datetime.timedelta(days=<NUM_LIT:1>)<EOL>context.session.add(address)<EOL>context.session.flush()<EOL>

This is a helper method for testing.

    When run with the current context, it will create a case 2 entries
    in the database. See top of file for what case 2 is.


<EOL>config_opts = ['<STR_LIT>', '<STR_LIT>']<EOL>config.init(config_opts)<EOL>network_strategy.STRATEGY.load()<EOL>billing.PUBLIC_NETWORK_ID = network_strategy.STRATEGY.get_public_net_id()<EOL>config.setup_logging()<EOL>context = neutron_context.get_admin_context()<EOL>query = context.session.query(models.IPAddress)<EOL>(period_start, period_end) = billing.calc_periods(hour, minute)<EOL>full_day_ips = billing.build_full_day_ips(query,<EOL>period_start,<EOL>period_end)<EOL>partial_day_ips = billing.build_partial_day_ips(query,<EOL>period_start,<EOL>period_end)<EOL>if notify:<EOL><INDENT>for ipaddress in full_day_ips:<EOL><INDENT>click.echo('<STR_LIT>'.format(period_start, period_end))<EOL>payload = billing.build_payload(ipaddress,<EOL>billing.IP_EXISTS,<EOL>start_time=period_start,<EOL>end_time=period_end)<EOL>billing.do_notify(context,<EOL>billing.IP_EXISTS,<EOL>payload)<EOL><DEDENT>for ipaddress in partial_day_ips:<EOL><INDENT>click.echo('<STR_LIT>'.format(period_start, period_end))<EOL>payload = billing.build_payload(ipaddress,<EOL>billing.IP_EXISTS,<EOL>start_time=ipaddress.allocated_at,<EOL>end_time=period_end)<EOL>billing.do_notify(context,<EOL>billing.IP_EXISTS,<EOL>payload)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>click.echo('<STR_LIT>'.format(len(full_day_ips)))<EOL>for ipaddress in full_day_ips:<EOL><INDENT>pp(billing.build_payload(ipaddress,<EOL>billing.IP_EXISTS,<EOL>start_time=period_start,<EOL>end_time=period_end))<EOL><DEDENT>click.echo('<STR_LIT>')<EOL>click.echo('<STR_LIT>'.format(len(partial_day_ips)))<EOL>for ipaddress in partial_day_ips:<EOL><INDENT>pp(billing.build_payload(ipaddress,<EOL>billing.IP_EXISTS,<EOL>start_time=ipaddress.allocated_at,<EOL>end_time=period_end))<EOL><DEDENT><DEDENT>

Runs billing report. Optionally sends notifications to billing


def _load_worker_plugin_with_module(self, module, version):

classes = inspect.getmembers(module, inspect.isclass)<EOL>loaded = <NUM_LIT:0><EOL>for cls_name, cls in classes:<EOL><INDENT>if hasattr(cls, '<STR_LIT>'):<EOL><INDENT>if version not in cls.versions:<EOL><INDENT>continue<EOL><DEDENT><DEDENT>else:<EOL><INDENT>continue<EOL><DEDENT>if issubclass(cls, base_worker.QuarkAsyncPluginBase):<EOL><INDENT>LOG.debug("<STR_LIT>" % cls_name)<EOL>plugin = cls()<EOL>self.plugins.append(plugin)<EOL>loaded += <NUM_LIT:1><EOL><DEDENT><DEDENT>LOG.debug("<STR_LIT>" %<EOL>(len(classes), loaded))<EOL>

Instantiates worker plugins that have requsite properties.

        The required properties are:
        * must have PLUGIN_EP entrypoint registered (or it wouldn't be in the
          list)
        * must have class attribute versions (list) of supported RPC versions
        * must subclass QuarkAsyncPluginBase


emgr = extension.ExtensionManager(PLUGIN_EP, invoke_on_load=False)<EOL>return ((ext.name, ext.plugin) for ext in emgr)<EOL>

Looks for modules with amtching entry points.


for name, module in itertools.chain(self._discover_via_entrypoints()):<EOL><INDENT>self._load_worker_plugin_with_module(module, version)<EOL><DEDENT>

Loads plugins that match the PLUGIN_EP entrypoint.


if cfg.CONF.QUARK_ASYNC.rpc_workers < <NUM_LIT:1>:<EOL><INDENT>cfg.CONF.set_override('<STR_LIT>', <NUM_LIT:1>, "<STR_LIT>")<EOL><DEDENT>try:<EOL><INDENT>rpc = service.RpcWorker(self.plugins)<EOL>launcher = common_service.ProcessLauncher(CONF, wait_interval=<NUM_LIT:1.0>)<EOL>launcher.launch_service(rpc, workers=CONF.QUARK_ASYNC.rpc_workers)<EOL>return launcher<EOL><DEDENT>except Exception:<EOL><INDENT>with excutils.save_and_reraise_exception():<EOL><INDENT>LOG.exception(_LE('<STR_LIT>'<EOL>'<STR_LIT>'))<EOL><DEDENT><DEDENT>

Launches configured # of workers per loaded plugin.


pool = eventlet.GreenPool()<EOL>quark_rpc = self.serve_rpc()<EOL>pool.spawn(quark_rpc.wait)<EOL>pool.waitall()<EOL>

Initializes eventlet and starts wait for workers to exit.

        Spawns the workers returned from serve_rpc


<EOL>id_range = xrange(sa_range['<STR_LIT>'],<EOL>sa_range['<STR_LIT>'] + <NUM_LIT:1>)<EOL>sa_dicts = []<EOL>total = <NUM_LIT:0><EOL>for i in id_range:<EOL><INDENT>sa_dicts.append({<EOL>'<STR_LIT>': sa_range['<STR_LIT>'],<EOL>'<STR_LIT>': sa_range['<STR_LIT>'],<EOL>'<STR_LIT:id>': i,<EOL>'<STR_LIT>': sa_range['<STR_LIT:id>'],<EOL>'<STR_LIT>': True<EOL>})<EOL>total = total + <NUM_LIT:1><EOL><DEDENT>db_api.segment_allocation_range_populate_bulk(self.context, sa_dicts)<EOL>self.context.session.flush()<EOL>allocs = db_api.segment_allocation_find(<EOL>self.context, segment_allocation_range_id=sa_range['<STR_LIT:id>']).all()<EOL>self.assertEqual(len(allocs), len(id_range))<EOL>


sa_dict = self._make_segment_allocation_range_dict(**kwargs)<EOL>sa_range = db_api.segment_allocation_range_create(<EOL>self.context, **sa_dict)<EOL>self.context.session.flush()<EOL>self._populate_segment_allocation_range(sa_range)<EOL>return sa_range<EOL>

Create a segment allocation range in the database.


def _allocate_segment(self, sa_range, count=<NUM_LIT:1>):

allocs = []<EOL>for i in xrange(sa_range['<STR_LIT>'], sa_range['<STR_LIT>'] + count):<EOL><INDENT>filters = {<EOL>'<STR_LIT>': sa_range['<STR_LIT:id>'],<EOL>'<STR_LIT>': True<EOL>}<EOL>alloc = db_api.segment_allocation_find(<EOL>self.context, **filters).first()<EOL>if not alloc:<EOL><INDENT>raise Exception("<STR_LIT>")<EOL><DEDENT>update = {<EOL>'<STR_LIT>': False<EOL>}<EOL>allocs.append(<EOL>db_api.segment_allocation_update(<EOL>self.context, alloc, **update)<EOL>)<EOL>self.context.session.flush()<EOL><DEDENT>self.assertEqual(len(allocs), count)<EOL>return allocs<EOL>


def _sa_range_to_dict(self, sa_range, allocations=None):

size = (sa_range['<STR_LIT>'] + <NUM_LIT:1>) - sa_range['<STR_LIT>']<EOL>sa_range_dict = dict(sa_range)<EOL>sa_range_dict.pop('<STR_LIT>')<EOL>sa_range_dict['<STR_LIT:size>'] = size<EOL>if allocations is not None:<EOL><INDENT>sa_range_dict['<STR_LIT>'] = size - allocations<EOL><DEDENT>return sa_range_dict<EOL>

Helper to turn a model into a dict for assertions.


def _assert_tags(self, model, tags=None):

tags = tags if tags else []<EOL>expected_tags = (self.existing_tags + tags)<EOL>self.assertEqual(sorted(model.tags),<EOL>sorted(expected_tags))<EOL>

Assert given tags and already existing tags are present.


LOG.debug("<STR_LIT>")<EOL>with session.begin():<EOL><INDENT>query = session.query(<EOL>models.Subnet.segment_id,<EOL>func.count(models.IPAddress.address))<EOL>query = query.group_by(models.Subnet.segment_id)<EOL>query = _filter(query, **kwargs)<EOL>reuse_window = timeutils.utcnow() - datetime.timedelta(<EOL>seconds=cfg.CONF.QUARK.ipam_reuse_after)<EOL>query = query.outerjoin(<EOL>models.IPAddress,<EOL>and_(models.Subnet.id == models.IPAddress.subnet_id,<EOL>or_(not_(models.IPAddress.lock_id.is_(None)),<EOL>models.IPAddress._deallocated.is_(None),<EOL>models.IPAddress._deallocated == <NUM_LIT:0>,<EOL>models.IPAddress.deallocated_at > reuse_window)))<EOL>query = query.outerjoin(<EOL>models.IPPolicyCIDR,<EOL>and_(<EOL>models.Subnet.ip_policy_id == models.IPPolicyCIDR.ip_policy_id,<EOL>models.IPAddress.address >= models.IPPolicyCIDR.first_ip,<EOL>models.IPAddress.address <= models.IPPolicyCIDR.last_ip))<EOL>query = query.filter(or_(<EOL>models.IPAddress._deallocated.is_(None),<EOL>models.IPAddress._deallocated == <NUM_LIT:0>,<EOL>models.IPPolicyCIDR.id.is_(None)))<EOL>ret = ((segment_id, address_count)<EOL>for segment_id, address_count in query.all())<EOL>return dict(ret)<EOL><DEDENT>

Returns dictionary with keys segment_id and value used IPs count.

    Used IP address count is determined by:
    - allocated IPs
    - deallocated IPs whose `deallocated_at` is within the `reuse_after`
    window compared to the present time, excluding IPs that are accounted for
    in the current IP policy (because IP policy is mutable and deallocated IPs
    are not checked nor deleted on IP policy creation, thus deallocated IPs
    that don't fit the current IP policy can exist in the neutron database).


def get_unused_ips(session, used_ips_counts, **kwargs):

LOG.debug("<STR_LIT>")<EOL>with session.begin():<EOL><INDENT>query = session.query(<EOL>models.Subnet.segment_id,<EOL>models.Subnet)<EOL>query = _filter(query, **kwargs)<EOL>query = query.group_by(models.Subnet.segment_id, models.Subnet.id)<EOL>ret = defaultdict(int)<EOL>for segment_id, subnet in query.all():<EOL><INDENT>net_size = netaddr.IPNetwork(subnet._cidr).size<EOL>ip_policy = subnet["<STR_LIT>"] or {"<STR_LIT:size>": <NUM_LIT:0>}<EOL>ret[segment_id] += net_size - ip_policy["<STR_LIT:size>"]<EOL><DEDENT>for segment_id in used_ips_counts:<EOL><INDENT>ret[segment_id] -= used_ips_counts[segment_id]<EOL><DEDENT>return ret<EOL><DEDENT>

Returns dictionary with key segment_id, and value unused IPs count.

    Unused IP address count is determined by:
    - adding subnet's cidr's size
    - subtracting IP policy exclusions on subnet
    - subtracting used ips per segment


global _INSPECTOR<EOL>if _INSPECTOR:<EOL><INDENT>return _INSPECTOR<EOL><DEDENT>else:<EOL><INDENT>bind = op.get_bind()<EOL>_INSPECTOR = sa.engine.reflection.Inspector.from_engine(bind)<EOL><DEDENT>return _INSPECTOR<EOL>


inspector = get_inspector()<EOL>return inspector.get_columns(table)<EOL>

Returns list of columns for given table.


output = []<EOL>tables = get_tables()<EOL>for table in tables:<EOL><INDENT>try:<EOL><INDENT>columns = get_columns(table)<EOL><DEDENT>except sa.exc.NoSuchTableError:<EOL><INDENT>continue<EOL><DEDENT>for column in columns:<EOL><INDENT>if column['<STR_LIT:name>'] == '<STR_LIT>':<EOL><INDENT>output.append((table, column))<EOL><DEDENT><DEDENT><DEDENT>return output<EOL>

Returns combined list of tuples: [(table, column)].

    List is built, based on retrieved tables, where column with name
    ``tenant_id`` exists.


with op.batch_alter_table(t2_name) as batch_op:<EOL><INDENT>batch_op.drop_column('<STR_LIT>')<EOL><DEDENT>with op.batch_alter_table(t1_name) as batch_op:<EOL><INDENT>batch_op.drop_column('<STR_LIT>')<EOL><DEDENT>

alexm: i believe this method is never called


context.configure(url=neutron_config.database.connection)<EOL>with context.begin_transaction():<EOL><INDENT>context.run_migrations()<EOL><DEDENT>

Run migrations in 'offline' mode.

    This configures the context with just a URL
    and not an Engine, though an Engine is acceptable
    here as well.  By skipping the Engine creation
    we don't even need a DBAPI to be available.

    Calls to context.execute() here emit the given string to the
    script output.


Run migrations in 'online' mode.

    In this scenario we need to create an Engine
    and associate a connection with the context.


return getattr(self, "<STR_LIT>" % self.discriminator)<EOL>


if not group:<EOL><INDENT>return None<EOL><DEDENT>if not hasattr(group, "<STR_LIT>") or len(group.ports) <= <NUM_LIT:0>:<EOL><INDENT>return []<EOL><DEDENT>return group.ports<EOL>

Gather all ports associated to security group.

    Returns:
    * list, or None


def security_group_rule_update(context, rule, **kwargs):

rule.update(kwargs)<EOL>context.session.add(rule)<EOL>return rule<EOL>

Updates a security group rule.

    NOTE(alexm) this is non-standard functionality.


def segment_allocation_find(context, lock_mode=False, **filters):

range_ids = filters.pop("<STR_LIT>", None)<EOL>query = context.session.query(models.SegmentAllocation)<EOL>if lock_mode:<EOL><INDENT>query = query.with_lockmode("<STR_LIT>")<EOL><DEDENT>query = query.filter_by(**filters)<EOL>if range_ids:<EOL><INDENT>query.filter(<EOL>models.SegmentAllocation.segment_allocation_range_id.in_(<EOL>range_ids))<EOL><DEDENT>return query<EOL>


context.session.bulk_insert_mappings(<EOL>models.SegmentAllocation,<EOL>sa_dicts<EOL>)<EOL>

Bulk-insert deallocated segment allocations.

    NOTE(morgabra): This is quite performant when populating large ranges,
    but you don't get any ORM conveniences or protections here.


if not hasattr(cls, '<STR_LIT>'):<EOL><INDENT>raise NotImplementedError()<EOL><DEDENT>return cls.NAME<EOL>


return "<STR_LIT>" % cls.get_name().upper()<EOL>

Tag 'key', saved in the database as <prefix>:<value>


self.validate(value)<EOL>self._pop(model)<EOL>value = self.serialize(value)<EOL>model.tags.append(value)<EOL>


for tag in model.tags:<EOL><INDENT>if self.is_tag(tag):<EOL><INDENT>value = self.deserialize(tag)<EOL>try:<EOL><INDENT>self.validate(value)<EOL>return value<EOL><DEDENT>except TagValidationError:<EOL><INDENT>continue<EOL><DEDENT><DEDENT><DEDENT>return None<EOL>


tags = []<EOL>for tag in model.tags:<EOL><INDENT>if self.is_tag(tag):<EOL><INDENT>tags.append(tag)<EOL><DEDENT><DEDENT>if tags:<EOL><INDENT>for tag in tags:<EOL><INDENT>model.tags.remove(tag)<EOL><DEDENT><DEDENT>return tags<EOL>

Pop all matching tags off the model and return them.


tags = self._pop(model)<EOL>if tags:<EOL><INDENT>for tag in tags:<EOL><INDENT>value = self.deserialize(tag)<EOL>try:<EOL><INDENT>self.validate(value)<EOL>return value<EOL><DEDENT>except TagValidationError:<EOL><INDENT>continue<EOL><DEDENT><DEDENT><DEDENT>

Pop all matching tags off the port, return a valid one.


return tag[<NUM_LIT:0>:len(self.get_prefix())] == self.get_prefix()<EOL>


for tag in model.tags:<EOL><INDENT>if self.is_tag(tag):<EOL><INDENT>return True<EOL><DEDENT><DEDENT>return False<EOL>


try:<EOL><INDENT>vlan_id_int = int(value)<EOL>assert vlan_id_int >= self.MIN_VLAN_ID<EOL>assert vlan_id_int <= self.MAX_VLAN_ID<EOL><DEDENT>except Exception:<EOL><INDENT>msg = ("<STR_LIT>"<EOL>"<STR_LIT>"<EOL>"<STR_LIT>" % {'<STR_LIT>': value,<EOL>'<STR_LIT>': self.MIN_VLAN_ID,<EOL>'<STR_LIT>': self.MAX_VLAN_ID})<EOL>raise TagValidationError(value, msg)<EOL><DEDENT>return True<EOL>

Validates a VLAN ID.

        :param value: The VLAN ID to validate against.
        :raises TagValidationError: Raised if the VLAN ID is invalid.


tags = {}<EOL>for name, tag in self.tags.items():<EOL><INDENT>for mtag in model.tags:<EOL><INDENT>if tag.is_tag(mtag):<EOL><INDENT>tags[name] = tag.get(model)<EOL><DEDENT><DEDENT><DEDENT>return tags<EOL>

Get all known tags from a model.

        Returns a dict of {<tag_name>:<tag_value>}.


for name, tag in self.tags.items():<EOL><INDENT>if name in tags:<EOL><INDENT>value = tags.pop(name)<EOL>if value:<EOL><INDENT>try:<EOL><INDENT>tag.set(model, value)<EOL><DEDENT>except TagValidationError as e:<EOL><INDENT>raise n_exc.BadRequest(<EOL>resource="<STR_LIT>",<EOL>msg="<STR_LIT:%s>" % (e.message))<EOL><DEDENT><DEDENT><DEDENT><DEDENT>

Validate and set all known tags on a port.


def update_sg(self, context, sg, rule_id, action):

db_sg = db_api.security_group_find(context, id=sg, scope=db_api.ONE)<EOL>if not db_sg:<EOL><INDENT>return None<EOL><DEDENT>with context.session.begin():<EOL><INDENT>job_body = dict(action="<STR_LIT>" % (action, rule_id),<EOL>resource_id=rule_id,<EOL>tenant_id=db_sg['<STR_LIT>'])<EOL>job_body = dict(job=job_body)<EOL>job = job_api.create_job(context.elevated(), job_body)<EOL>rpc_client = QuarkSGAsyncProducerClient()<EOL>try:<EOL><INDENT>rpc_client.populate_subtasks(context, sg, job['<STR_LIT:id>'])<EOL><DEDENT>except om_exc.MessagingTimeout:<EOL><INDENT>LOG.error("<STR_LIT>")<EOL>return None<EOL><DEDENT><DEDENT>return {"<STR_LIT>": job['<STR_LIT:id>']}<EOL>


def populate_subtasks(self, context, sg, parent_job_id):

db_sg = db_api.security_group_find(context, id=sg, scope=db_api.ONE)<EOL>if not db_sg:<EOL><INDENT>return None<EOL><DEDENT>ports = db_api.sg_gather_associated_ports(context, db_sg)<EOL>if len(ports) == <NUM_LIT:0>:<EOL><INDENT>return {"<STR_LIT>": <NUM_LIT:0>}<EOL><DEDENT>for port in ports:<EOL><INDENT>job_body = dict(action="<STR_LIT>" % port['<STR_LIT:id>'],<EOL>tenant_id=db_sg['<STR_LIT>'],<EOL>resource_id=port['<STR_LIT:id>'],<EOL>parent_id=parent_job_id)<EOL>job_body = dict(job=job_body)<EOL>job = job_api.create_job(context.elevated(), job_body)<EOL>rpc_consumer = QuarkSGAsyncConsumerClient()<EOL>try:<EOL><INDENT>rpc_consumer.update_port(context, port['<STR_LIT:id>'], job['<STR_LIT:id>'])<EOL><DEDENT>except om_exc.MessagingTimeout:<EOL><INDENT>LOG.error("<STR_LIT>")<EOL><DEDENT><DEDENT>return None<EOL>

Produces a list of ports to be updated async.


def update_ports_for_sg(self, context, portid, jobid):

port = db_api.port_find(context, id=portid, scope=db_api.ONE)<EOL>if not port:<EOL><INDENT>LOG.warning("<STR_LIT>")<EOL>return<EOL><DEDENT>net_driver = port_api._get_net_driver(port.network, port=port)<EOL>base_net_driver = port_api._get_net_driver(port.network)<EOL>sg_list = [sg for sg in port.security_groups]<EOL>success = False<EOL>error = None<EOL>retries = <NUM_LIT:3><EOL>retry_delay = <NUM_LIT:2><EOL>for retry in xrange(retries):<EOL><INDENT>try:<EOL><INDENT>net_driver.update_port(context, port_id=port["<STR_LIT>"],<EOL>mac_address=port["<STR_LIT>"],<EOL>device_id=port["<STR_LIT>"],<EOL>base_net_driver=base_net_driver,<EOL>security_groups=sg_list)<EOL>success = True<EOL>error = None<EOL>break<EOL><DEDENT>except Exception as error:<EOL><INDENT>LOG.warning("<STR_LIT>")<EOL>time.sleep(retry_delay)<EOL><DEDENT><DEDENT>status_str = "<STR_LIT>"<EOL>if not success:<EOL><INDENT>status_str = "<STR_LIT>" % (<EOL>portid, retries, error)<EOL><DEDENT>update_body = dict(completed=True, status=status_str)<EOL>update_body = dict(job=update_body)<EOL>job_api.update_job(context.elevated(), jobid, update_body)<EOL>


self.endpoints.extend(self.callbacks)<EOL>

Registers callbacks to RPC assigned by subclasses.

        This does nothing if the subclasses do not set callbacks value.


self._setup_rpc()<EOL>if not self.endpoints:<EOL><INDENT>return []<EOL><DEDENT>self.conn = n_rpc.create_connection()<EOL>self.conn.create_consumer(self.topic, self.endpoints,<EOL>fanout=False)<EOL>return self.conn.consume_in_threads()<EOL>


if not self._context:<EOL><INDENT>self._context = context.get_admin_context()<EOL><DEDENT>return self._context<EOL>


def do_notify(context, event_type, payload):

LOG.debug('<STR_LIT>'.format(payload))<EOL>notifier = n_rpc.get_notifier('<STR_LIT>')<EOL>notifier.info(context, event_type, payload)<EOL>

Generic Notifier.

    Parameters:
        - `context`: session context
        - `event_type`: the event type to report, i.e. ip.usage
        - `payload`: dict containing the payload to send


@env.has_capability(env.Capabilities.IP_BILLING)<EOL>def notify(context, event_type, ipaddress, send_usage=False, *args, **kwargs):

if (event_type == IP_ADD and not CONF.QUARK.notify_ip_add) or(event_type == IP_DEL and not CONF.QUARK.notify_ip_delete) or(event_type == IP_ASSOC and not CONF.QUARK.notify_flip_associate) or(event_type == IP_DISASSOC and not CONF.QUARK.notify_flip_disassociate)or (event_type == IP_EXISTS and not CONF.QUARK.notify_ip_exists):<EOL><INDENT>LOG.debug('<STR_LIT>'.<EOL>format(event_type))<EOL>return<EOL><DEDENT>if '<STR_LIT>' in kwargs and kwargs['<STR_LIT>']:<EOL><INDENT>LOG.debug('<STR_LIT>')<EOL>return<EOL><DEDENT>ts = ipaddress.allocated_at if event_type == IP_ADD else _now()<EOL>payload = build_payload(ipaddress, event_type, event_time=ts)<EOL>do_notify(context, event_type, payload)<EOL>if send_usage:<EOL><INDENT>if ipaddress.allocated_at is not None andipaddress.allocated_at >= _midnight_today():<EOL><INDENT>start_time = ipaddress.allocated_at<EOL><DEDENT>else:<EOL><INDENT>start_time = _midnight_today()<EOL><DEDENT>payload = build_payload(ipaddress,<EOL>IP_EXISTS,<EOL>start_time=start_time,<EOL>end_time=ts)<EOL>do_notify(context, IP_EXISTS, payload)<EOL><DEDENT>

Method to send notifications.

    We must send USAGE when a public IPv4 address is deallocated or a FLIP is
    associated.
    Parameters:
        - `context`: the context for notifier
        - `event_type`: the event type for IP allocate, deallocate, associate,
        disassociate
        - `ipaddress`: the ipaddress object to notify about
    Returns:
        nothing
    Notes: this may live in the billing module


<EOL>payload = {<EOL>'<STR_LIT>': str(event_type),<EOL>'<STR_LIT>': str(ipaddress.used_by_tenant_id),<EOL>'<STR_LIT>': str(ipaddress.address_readable),<EOL>'<STR_LIT>': int(ipaddress.version),<EOL>'<STR_LIT>': str(ipaddress.address_type),<EOL>'<STR_LIT:id>': str(ipaddress.id)<EOL>}<EOL>if event_type == IP_EXISTS:<EOL><INDENT>if start_time is None or end_time is None:<EOL><INDENT>raise ValueError('<STR_LIT>'<EOL>.format(event_type))<EOL><DEDENT>payload.update({<EOL>'<STR_LIT>': str(convert_timestamp(start_time)),<EOL>'<STR_LIT>': str(convert_timestamp(end_time))<EOL>})<EOL><DEDENT>elif event_type in [IP_ADD, IP_DEL, IP_ASSOC, IP_DISASSOC]:<EOL><INDENT>if event_time is None:<EOL><INDENT>raise ValueError('<STR_LIT>'<EOL>.format(event_type))<EOL><DEDENT>payload.update({<EOL>'<STR_LIT>': str(convert_timestamp(event_time)),<EOL>'<STR_LIT>': str(ipaddress.subnet_id),<EOL>'<STR_LIT>': str(ipaddress.network_id),<EOL>'<STR_LIT>': True if ipaddress.network_id == PUBLIC_NETWORK_ID<EOL>else False,<EOL>})<EOL><DEDENT>else:<EOL><INDENT>raise ValueError('<STR_LIT>'.format(event_type))<EOL><DEDENT>return payload<EOL>

Method builds a payload out of the passed arguments.

    Parameters:
        `ipaddress`: the models.IPAddress object
        `event_type`: USAGE,CREATE,DELETE,SUSPEND,or UNSUSPEND
        `start_time`: startTime for cloudfeeds
        `end_time`: endTime for cloudfeeds
    Returns a dictionary suitable to notify billing.
    Message types mapping to cloud feeds for references:
        ip.exists       - USAGE
        ip.add          - CREATE
        ip.delete       - DELETE
        ip.associate    - UP
        ip.disassociate  - DOWN
    Refer to: http://rax.io/cf-api for more details.


def build_full_day_ips(query, period_start, period_end):

<EOL>ip_list = query.filter(models.IPAddress.version == <NUM_LIT:4>).filter(models.IPAddress.network_id == PUBLIC_NETWORK_ID).filter(models.IPAddress.used_by_tenant_id is not None).filter(models.IPAddress.allocated_at != null()).filter(models.IPAddress.allocated_at < period_start).filter(or_(models.IPAddress._deallocated is False,<EOL>models.IPAddress.deallocated_at == null(),<EOL>models.IPAddress.deallocated_at >= period_end)).all()<EOL>return ip_list<EOL>

Method to build an IP list for the case 1

    when the IP was allocated before the period start
    and is still allocated after the period end.
    This method only looks at public IPv4 addresses.


def build_partial_day_ips(query, period_start, period_end):

<EOL>ip_list = query.filter(models.IPAddress.version == <NUM_LIT:4>).filter(models.IPAddress.network_id == PUBLIC_NETWORK_ID).filter(models.IPAddress.used_by_tenant_id is not None).filter(and_(models.IPAddress.allocated_at != null(),<EOL>models.IPAddress.allocated_at >= period_start,<EOL>models.IPAddress.allocated_at < period_end)).filter(or_(models.IPAddress._deallocated is False,<EOL>models.IPAddress.deallocated_at == null(),<EOL>models.IPAddress.deallocated_at >= period_end)).all()<EOL>return ip_list<EOL>

Method to build an IP list for the case 2

    when the IP was allocated after the period start and
    is still allocated after the period end.
    This method only looks at public IPv4 addresses.


<EOL>period_end = datetime.datetime.utcnow().replace(hour=hour,<EOL>minute=minute,<EOL>second=<NUM_LIT:0>,<EOL>microsecond=<NUM_LIT:0>)<EOL>period_start = period_end - datetime.timedelta(days=<NUM_LIT:1>)<EOL>period_end -= datetime.timedelta(seconds=<NUM_LIT:1>)<EOL>return (period_start, period_end)<EOL>

Returns a tuple of start_period and end_period.

    Assumes that the period is 24-hrs.
    Parameters:
        - `hour`: the hour from 0 to 23 when the period ends
        - `minute`: the minute from 0 to 59 when the period ends
    This method will calculate the end of the period as the closest hour/minute
    going backwards.
    It will also calculate the start of the period as the passed hour/minute
    but 24 hrs ago.
    Example, if we pass 0, 0 - we will get the events from 0:00 midnight of the
    day before yesterday until today's midnight.
    If we pass 2,0 - we will get the start time as 2am of the previous morning
    till 2am of today's morning.
    By default it's midnight.


return ts.replace(microsecond=<NUM_LIT:0>).isoformat() + '<STR_LIT>'<EOL>

Converts the timestamp to a format suitable for Billing.

    Examples of a good timestamp for startTime, endTime, and eventTime:
        '2016-05-20T00:00:00Z'
    We must drop microseconds so that Yagi does not get upset.
    Note the trailing 'Z'. Python does not add the 'Z' so we tack it on
    ourselves.


return datetime.datetime.utcnow().replace(microsecond=<NUM_LIT:0>)<EOL>

Method to get the utcnow without microseconds


def __init__(self, device_id, record, ref):

self.device_id = device_id<EOL>self.record = record<EOL>self.ref = ref<EOL>self.success = False<EOL>

Constructs VIF

        `device_id` and `mac_address` should be strings if they will later be
        compared to decoded VIF instances (via from_string).

        `ref` is the OpaqueRef string for the vif as returned from xenapi.


LOG.debug("<STR_LIT>")<EOL>recs = session.xenapi.VM.get_all_records()<EOL>is_inst = lambda r: (r['<STR_LIT>'].lower() == '<STR_LIT>' and<EOL>not r['<STR_LIT>'] and<EOL>not r['<STR_LIT>'] and<EOL>('<STR_LIT>' in r['<STR_LIT>'] or<EOL>r['<STR_LIT>'].startswith('<STR_LIT>')))<EOL>instances = dict()<EOL>for vm_ref, rec in recs.iteritems():<EOL><INDENT>if not is_inst(rec):<EOL><INDENT>continue<EOL><DEDENT>instances[vm_ref] = VM(ref=vm_ref,<EOL>uuid=rec["<STR_LIT>"]["<STR_LIT>"],<EOL>vifs=rec["<STR_LIT>"],<EOL>dom_id=rec["<STR_LIT>"])<EOL><DEDENT>return instances<EOL>

Returns a dict of `VM OpaqueRef` (str) -> `xapi.VM`.


LOG.debug("<STR_LIT>")<EOL>with self.sessioned() as session:<EOL><INDENT>instances = self.get_instances(session)<EOL>recs = session.xenapi.VIF.get_all_records()<EOL><DEDENT>interfaces = set()<EOL>for vif_ref, rec in recs.iteritems():<EOL><INDENT>vm = instances.get(rec["<STR_LIT>"])<EOL>if not vm:<EOL><INDENT>continue<EOL><DEDENT>device_id = vm.uuid<EOL>interfaces.add(VIF(device_id, rec, vif_ref))<EOL><DEDENT>return interfaces<EOL>

Returns a set of VIFs from `get_instances` return value.


def update_interfaces(self, added_sg, updated_sg, removed_sg):

if not (added_sg or updated_sg or removed_sg):<EOL><INDENT>return<EOL><DEDENT>with self.sessioned() as session:<EOL><INDENT>self._set_security_groups(session, added_sg)<EOL>self._unset_security_groups(session, removed_sg)<EOL>combined = added_sg + updated_sg + removed_sg<EOL>self._refresh_interfaces(session, combined)<EOL><DEDENT>

Handles changes to interfaces' security groups

        Calls refresh_interfaces on argument VIFs. Set security groups on
        added_sg's VIFs. Unsets security groups on removed_sg's VIFs.


nicira_iface_id = vif.record.get('<STR_LIT>').get('<STR_LIT>')<EOL>if nicira_iface_id:<EOL><INDENT>return True<EOL><DEDENT>return False<EOL>

Determine if a vif is on isonet

    Returns True if a vif belongs to an isolated network by checking
    for a nicira interface id.


def partition_vifs(xapi_client, interfaces, security_group_states):

added = []<EOL>updated = []<EOL>removed = []<EOL>for vif in interfaces:<EOL><INDENT>if ('<STR_LIT>' in CONF.QUARK.environment_capabilities and<EOL>is_isonet_vif(vif)):<EOL><INDENT>continue<EOL><DEDENT>vif_has_groups = vif in security_group_states<EOL>if vif.tagged and vif_has_groups andsecurity_group_states[vif][sg_cli.SECURITY_GROUP_ACK]:<EOL><INDENT>continue<EOL><DEDENT>if vif.tagged:<EOL><INDENT>if vif_has_groups:<EOL><INDENT>updated.append(vif)<EOL><DEDENT>else:<EOL><INDENT>removed.append(vif)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>if vif_has_groups:<EOL><INDENT>added.append(vif)<EOL><DEDENT><DEDENT><DEDENT>return added, updated, removed<EOL>

Splits VIFs into three explicit categories and one implicit

    Added - Groups exist in Redis that have not been ack'd and the VIF
            is not tagged.
            Action: Tag the VIF and apply flows
    Updated - Groups exist in Redis that have not been ack'd and the VIF
              is already tagged
              Action: Do not tag the VIF, do apply flows
    Removed - Groups do NOT exist in Redis but the VIF is tagged
              Action: Untag the VIF, apply default flows
    Self-Heal - Groups are ack'd in Redis but the VIF is untagged. We treat
                this case as if it were an "added" group.
                Action: Tag the VIF and apply flows
    NOOP - The VIF is not tagged and there are no matching groups in Redis.
           This is our implicit category
           Action: Do nothing


def get_groups_to_ack(groups_to_ack, init_sg_states, curr_sg_states):

security_groups_changed = []<EOL>for vif in groups_to_ack:<EOL><INDENT>initial_state = init_sg_states[vif][sg_cli.SECURITY_GROUP_HASH_ATTR]<EOL>current_state = curr_sg_states[vif][sg_cli.SECURITY_GROUP_HASH_ATTR]<EOL>bad_match_msg = ('<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>' % vif)<EOL>if len(initial_state) != len(current_state):<EOL><INDENT>security_groups_changed.append(vif)<EOL>LOG.info(bad_match_msg)<EOL><DEDENT>elif len(initial_state) > <NUM_LIT:0>:<EOL><INDENT>for rule in current_state:<EOL><INDENT>if rule not in initial_state:<EOL><INDENT>security_groups_changed.append(vif)<EOL>LOG.info(bad_match_msg)<EOL>break<EOL><DEDENT><DEDENT><DEDENT><DEDENT>ret = [group for group in groups_to_ack<EOL>if group not in security_groups_changed]<EOL>return ret<EOL>

Compares initial security group rules with current sg rules.

    Given the groups that were successfully returned from
        xapi_client.update_interfaces call, compare initial and current
        security group rules to determine if an update occurred during
        the window that the xapi_client.update_interfaces was executing.
        Return a list of vifs whose security group rules have not changed.


groups_client = sg_cli.SecurityGroupsClient()<EOL>xapi_client = xapi.XapiClient()<EOL>interfaces = set()<EOL>while True:<EOL><INDENT>try:<EOL><INDENT>interfaces = xapi_client.get_interfaces()<EOL><DEDENT>except Exception:<EOL><INDENT>LOG.exception("<STR_LIT>")<EOL>_sleep()<EOL>continue<EOL><DEDENT>try:<EOL><INDENT>sg_states = groups_client.get_security_group_states(interfaces)<EOL>new_sg, updated_sg, removed_sg = partition_vifs(xapi_client,<EOL>interfaces,<EOL>sg_states)<EOL>xapi_client.update_interfaces(new_sg, updated_sg, removed_sg)<EOL>groups_to_ack = [v for v in new_sg + updated_sg if v.success]<EOL>sg_sts_curr = groups_client.get_security_group_states(interfaces)<EOL>groups_to_ack = get_groups_to_ack(groups_to_ack, sg_states,<EOL>sg_sts_curr)<EOL>ack_groups(groups_client, groups_to_ack)<EOL><DEDENT>except Exception:<EOL><INDENT>LOG.exception("<STR_LIT>"<EOL>"<STR_LIT>")<EOL>_sleep()<EOL>continue<EOL><DEDENT>_sleep()<EOL><DEDENT>

Fetches changes and applies them to VIFs periodically

    Process as of RM11449:
    * Get all groups from redis
    * Fetch ALL VIFs from Xen
    * Walk ALL VIFs and partition them into added, updated and removed
    * Walk the final "modified" VIFs list and apply flows to each


tenant_quotas = context.session.query(Quota)<EOL>tenant_quotas = tenant_quotas.filter_by(tenant_id=tenant_id)<EOL>tenant_quotas.delete()<EOL>

Delete the quota entries for a given tenant_id.

        Atfer deletion, this tenant will use default quota values in conf.


def _chunks(self, iterable, chunk_size):

iterator = iter(iterable)<EOL>chunk = list(itertools.islice(iterator, <NUM_LIT:0>, chunk_size))<EOL>while chunk:<EOL><INDENT>yield chunk<EOL>chunk = list(itertools.islice(iterator, <NUM_LIT:0>, chunk_size))<EOL><DEDENT>

Chunks data into chunk with size<=chunk_size.


def _check_collisions(self, new_range, existing_ranges):

def _contains(num, r1):<EOL><INDENT>return (num >= r1[<NUM_LIT:0>] and<EOL>num <= r1[<NUM_LIT:1>])<EOL><DEDENT>def _is_overlap(r1, r2):<EOL><INDENT>return (_contains(r1[<NUM_LIT:0>], r2) or<EOL>_contains(r1[<NUM_LIT:1>], r2) or<EOL>_contains(r2[<NUM_LIT:0>], r1) or<EOL>_contains(r2[<NUM_LIT:1>], r1))<EOL><DEDENT>for existing_range in existing_ranges:<EOL><INDENT>if _is_overlap(new_range, existing_range):<EOL><INDENT>return True<EOL><DEDENT><DEDENT>return False<EOL>


def _try_allocate(self, context, segment_id, network_id):

LOG.info("<STR_LIT>"<EOL>"<STR_LIT>"<EOL>% (network_id, segment_id, self.segment_type))<EOL>filter_dict = {<EOL>"<STR_LIT>": segment_id,<EOL>"<STR_LIT>": self.segment_type,<EOL>"<STR_LIT>": False<EOL>}<EOL>available_ranges = db_api.segment_allocation_range_find(<EOL>context, scope=db_api.ALL, **filter_dict)<EOL>available_range_ids = [r["<STR_LIT:id>"] for r in available_ranges]<EOL>try:<EOL><INDENT>with context.session.begin(subtransactions=True):<EOL><INDENT>filter_dict = {<EOL>"<STR_LIT>": True,<EOL>"<STR_LIT>": segment_id,<EOL>"<STR_LIT>": self.segment_type,<EOL>"<STR_LIT>": available_range_ids<EOL>}<EOL>allocations = db_api.segment_allocation_find(<EOL>context, lock_mode=True, **filter_dict).limit(<NUM_LIT:100>).all()<EOL>if allocations:<EOL><INDENT>allocation = random.choice(allocations)<EOL>update_dict = {<EOL>"<STR_LIT>": False,<EOL>"<STR_LIT>": None,<EOL>"<STR_LIT>": network_id<EOL>}<EOL>allocation = db_api.segment_allocation_update(<EOL>context, allocation, **update_dict)<EOL>LOG.info("<STR_LIT>"<EOL>"<STR_LIT>"<EOL>% (allocation["<STR_LIT:id>"], network_id, segment_id,<EOL>self.segment_type))<EOL>return allocation<EOL><DEDENT><DEDENT><DEDENT>except Exception:<EOL><INDENT>LOG.exception("<STR_LIT>")<EOL><DEDENT>LOG.info("<STR_LIT>"<EOL>"<STR_LIT>"<EOL>% (network_id, segment_id, self.segment_type))<EOL>

Find a deallocated network segment id and reallocate it.

        NOTE(morgabra) This locks the segment table, but only the rows
        in use by the segment, which is pretty handy if we ever have
        more than 1 segment or segment type.


def _create_flip(context, flip, port_fixed_ips):

if port_fixed_ips:<EOL><INDENT>context.session.begin()<EOL>try:<EOL><INDENT>ports = [val['<STR_LIT:port>'] for val in port_fixed_ips.values()]<EOL>flip = db_api.port_associate_ip(context, ports, flip,<EOL>port_fixed_ips.keys())<EOL>for port_id in port_fixed_ips:<EOL><INDENT>fixed_ip = port_fixed_ips[port_id]['<STR_LIT>']<EOL>flip = db_api.floating_ip_associate_fixed_ip(context, flip,<EOL>fixed_ip)<EOL><DEDENT>flip_driver = registry.DRIVER_REGISTRY.get_driver()<EOL>flip_driver.register_floating_ip(flip, port_fixed_ips)<EOL>context.session.commit()<EOL><DEDENT>except Exception:<EOL><INDENT>context.session.rollback()<EOL>raise<EOL><DEDENT><DEDENT>billing.notify(context, billing.IP_ASSOC, flip)<EOL>

Associates the flip with ports and creates it with the flip driver

    :param context: neutron api request context.
    :param flip: quark.db.models.IPAddress object representing a floating IP
    :param port_fixed_ips: dictionary of the structure:
    {"<id of port>": {"port": <quark.db.models.Port>,
     "fixed_ip": "<fixed ip address>"}}
    :return: None


def _update_flip(context, flip_id, ip_type, requested_ports):

<EOL>notifications = {<EOL>billing.IP_ASSOC: set(),<EOL>billing.IP_DISASSOC: set()<EOL>}<EOL>context.session.begin()<EOL>try:<EOL><INDENT>flip = db_api.floating_ip_find(context, id=flip_id, scope=db_api.ONE)<EOL>if not flip:<EOL><INDENT>if ip_type == ip_types.SCALING:<EOL><INDENT>raise q_exc.ScalingIpNotFound(id=flip_id)<EOL><DEDENT>raise q_exc.FloatingIpNotFound(id=flip_id)<EOL><DEDENT>current_ports = flip.ports<EOL>req_port_ids = [request_port.get('<STR_LIT>')<EOL>for request_port in requested_ports]<EOL>curr_port_ids = [curr_port.id for curr_port in current_ports]<EOL>added_port_ids = [port_id for port_id in req_port_ids<EOL>if port_id and port_id not in curr_port_ids]<EOL>removed_port_ids = [port_id for port_id in curr_port_ids<EOL>if port_id not in req_port_ids]<EOL>remaining_port_ids = set(curr_port_ids) - set(removed_port_ids)<EOL>if (ip_type == ip_types.FLOATING and curr_port_ids and<EOL>curr_port_ids == req_port_ids):<EOL><INDENT>d = dict(flip_id=flip_id, port_id=curr_port_ids[<NUM_LIT:0>])<EOL>raise q_exc.PortAlreadyAssociatedToFloatingIp(**d)<EOL><DEDENT>if (ip_type == ip_types.FLOATING and<EOL>not curr_port_ids and not req_port_ids):<EOL><INDENT>raise q_exc.FloatingIpUpdateNoPortIdSupplied()<EOL><DEDENT>flip_subnet = v._make_subnet_dict(flip.subnet)<EOL>for added_port_id in added_port_ids:<EOL><INDENT>port = _get_port(context, added_port_id)<EOL>nw = port.network<EOL>nw_ports = v._make_ports_list(nw.ports)<EOL>fixed_ips = [ip.get('<STR_LIT>') for p in nw_ports<EOL>for ip in p.get('<STR_LIT>')]<EOL>gw_ip = flip_subnet.get('<STR_LIT>')<EOL>if gw_ip in fixed_ips:<EOL><INDENT>port_with_gateway_ip = None<EOL>for port in nw_ports:<EOL><INDENT>for ip in port.get('<STR_LIT>'):<EOL><INDENT>if gw_ip in ip.get('<STR_LIT>'):<EOL><INDENT>port_with_gateway_ip = port<EOL>break<EOL><DEDENT><DEDENT><DEDENT>port_id = port_with_gateway_ip.get('<STR_LIT:id>')<EOL>network_id = port_with_gateway_ip.get('<STR_LIT>')<EOL>raise q_exc.FixedIpAllocatedToGatewayIp(port_id=port_id,<EOL>network_id=network_id)<EOL><DEDENT><DEDENT>port_fixed_ips = {}<EOL>for port_id in remaining_port_ids:<EOL><INDENT>port = db_api.port_find(context, id=port_id, scope=db_api.ONE)<EOL>fixed_ip = _get_flip_fixed_ip_by_port_id(flip, port_id)<EOL>port_fixed_ips[port_id] = {'<STR_LIT:port>': port, '<STR_LIT>': fixed_ip}<EOL><DEDENT>for port_id in removed_port_ids:<EOL><INDENT>port = db_api.port_find(context, id=port_id, scope=db_api.ONE)<EOL>flip = db_api.port_disassociate_ip(context, [port], flip)<EOL>notifications[billing.IP_DISASSOC].add(flip)<EOL>fixed_ip = _get_flip_fixed_ip_by_port_id(flip, port_id)<EOL>if fixed_ip:<EOL><INDENT>flip = db_api.floating_ip_disassociate_fixed_ip(<EOL>context, flip, fixed_ip)<EOL><DEDENT><DEDENT>for port_id in added_port_ids:<EOL><INDENT>port = db_api.port_find(context, id=port_id, scope=db_api.ONE)<EOL>if not port:<EOL><INDENT>raise n_exc.PortNotFound(port_id=port_id)<EOL><DEDENT>if any(ip for ip in port.ip_addresses<EOL>if (ip.get('<STR_LIT>') == ip_types.FLOATING)):<EOL><INDENT>raise q_exc.PortAlreadyContainsFloatingIp(port_id=port_id)<EOL><DEDENT>if any(ip for ip in port.ip_addresses<EOL>if (ip.get('<STR_LIT>') == ip_types.SCALING)):<EOL><INDENT>raise q_exc.PortAlreadyContainsScalingIp(port_id=port_id)<EOL><DEDENT>fixed_ip = _get_next_available_fixed_ip(port)<EOL>LOG.info('<STR_LIT>' % fixed_ip)<EOL>if not fixed_ip:<EOL><INDENT>raise q_exc.NoAvailableFixedIpsForPort(port_id=port_id)<EOL><DEDENT>port_fixed_ips[port_id] = {'<STR_LIT:port>': port, '<STR_LIT>': fixed_ip}<EOL>flip = db_api.port_associate_ip(context, [port], flip, [port_id])<EOL>notifications[billing.IP_ASSOC].add(flip)<EOL>flip = db_api.floating_ip_associate_fixed_ip(context, flip,<EOL>fixed_ip)<EOL><DEDENT>flip_driver = registry.DRIVER_REGISTRY.get_driver()<EOL>if not remaining_port_ids and not added_port_ids:<EOL><INDENT>flip_driver.remove_floating_ip(flip)<EOL><DEDENT>elif added_port_ids and not curr_port_ids:<EOL><INDENT>flip_driver.register_floating_ip(flip, port_fixed_ips)<EOL><DEDENT>else:<EOL><INDENT>flip_driver.update_floating_ip(flip, port_fixed_ips)<EOL><DEDENT>context.session.commit()<EOL><DEDENT>except Exception:<EOL><INDENT>context.session.rollback()<EOL>raise<EOL><DEDENT>for notif_type, flip_set in notifications.iteritems():<EOL><INDENT>for flip in flip_set:<EOL><INDENT>billing.notify(context, notif_type, flip)<EOL><DEDENT><DEDENT>context.session.refresh(flip)<EOL>return flip<EOL>

Update a flip based IPAddress

    :param context: neutron api request context.
    :param flip_id: id of the flip or scip
    :param ip_type: ip_types.FLOATING | ip_types.SCALING
    :param requested_ports: dictionary of the structure:
    {"port_id": "<id of port>", "fixed_ip": "<fixed ip address>"}
    :return: quark.models.IPAddress


LOG.info('<STR_LIT>' %<EOL>(id, context.tenant_id, content))<EOL>network_id = content.get('<STR_LIT>')<EOL>if not network_id:<EOL><INDENT>raise n_exc.BadRequest(resource='<STR_LIT>',<EOL>msg='<STR_LIT>')<EOL><DEDENT>fixed_ip_address = content.get('<STR_LIT>')<EOL>ip_address = content.get('<STR_LIT>')<EOL>port_id = content.get('<STR_LIT>')<EOL>port = None<EOL>port_fixed_ip = {}<EOL>network = _get_network(context, network_id)<EOL>if port_id:<EOL><INDENT>port = _get_port(context, port_id)<EOL>fixed_ip = _get_fixed_ip(context, fixed_ip_address, port)<EOL>port_fixed_ip = {port.id: {'<STR_LIT:port>': port, '<STR_LIT>': fixed_ip}}<EOL><DEDENT>flip = _allocate_ip(context, network, port, ip_address, ip_types.FLOATING)<EOL>_create_flip(context, flip, port_fixed_ip)<EOL>return v._make_floating_ip_dict(flip, port_id)<EOL>

Allocate or reallocate a floating IP.

    :param context: neutron api request context.
    :param content: dictionary describing the floating ip, with keys
        as listed in the RESOURCE_ATTRIBUTE_MAP object in
        neutron/api/v2/attributes.py.  All keys will be populated.

    :returns: Dictionary containing details for the new floating IP.  If values
        are declared in the fields parameter, then only those keys will be
        present.


def update_floatingip(context, id, content):

LOG.info('<STR_LIT>' %<EOL>(id, context.tenant_id, content))<EOL>if '<STR_LIT>' not in content:<EOL><INDENT>raise n_exc.BadRequest(resource='<STR_LIT>',<EOL>msg='<STR_LIT>')<EOL><DEDENT>requested_ports = []<EOL>if content.get('<STR_LIT>'):<EOL><INDENT>requested_ports = [{'<STR_LIT>': content.get('<STR_LIT>')}]<EOL><DEDENT>flip = _update_flip(context, id, ip_types.FLOATING, requested_ports)<EOL>return v._make_floating_ip_dict(flip)<EOL>

Update an existing floating IP.

    :param context: neutron api request context.
    :param id: id of the floating ip
    :param content: dictionary with keys indicating fields to update.
        valid keys are those that have a value of True for 'allow_put'
        as listed in the RESOURCE_ATTRIBUTE_MAP object in
        neutron/api/v2/attributes.py.

    :returns: Dictionary containing details for the new floating IP.  If values
        are declared in the fields parameter, then only those keys will be
        present.


LOG.info('<STR_LIT>' % (id, context.tenant_id))<EOL>_delete_flip(context, id, ip_types.FLOATING)<EOL>

deallocate a floating IP.

    :param context: neutron api request context.
    :param id: id of the floating ip


def get_floatingip(context, id, fields=None):

LOG.info('<STR_LIT>' % (id, context.tenant_id))<EOL>filters = {'<STR_LIT>': ip_types.FLOATING, '<STR_LIT>': False}<EOL>floating_ip = db_api.floating_ip_find(context, id=id, scope=db_api.ONE,<EOL>**filters)<EOL>if not floating_ip:<EOL><INDENT>raise q_exc.FloatingIpNotFound(id=id)<EOL><DEDENT>return v._make_floating_ip_dict(floating_ip)<EOL>

Retrieve a floating IP.

    :param context: neutron api request context.
    :param id: The UUID of the floating IP.
    :param fields: a list of strings that are valid keys in a
        floating IP dictionary as listed in the RESOURCE_ATTRIBUTE_MAP
        object in neutron/api/v2/attributes.py. Only these fields
        will be returned.

    :returns: Dictionary containing details for the floating IP.  If values
        are declared in the fields parameter, then only those keys will be
        present.


def get_floatingips(context, filters=None, fields=None, sorts=['<STR_LIT:id>'],<EOL>limit=None, marker=None, page_reverse=False):

LOG.info('<STR_LIT>' %<EOL>(context.tenant_id, filters, fields))<EOL>floating_ips = _get_ips_by_type(context, ip_types.FLOATING,<EOL>filters=filters, fields=fields)<EOL>return [v._make_floating_ip_dict(flip) for flip in floating_ips]<EOL>

Retrieve a list of floating ips.

    :param context: neutron api request context.
    :param filters: a dictionary with keys that are valid keys for
        a floating ip as listed in the RESOURCE_ATTRIBUTE_MAP object
        in neutron/api/v2/attributes.py.  Values in this dictionary
        are an iterable containing values that will be used for an exact
        match comparison for that value.  Each result returned by this
        function will have matched one of the values for each key in
        filters.
    :param fields: a list of strings that are valid keys in a
        floating IP dictionary as listed in the RESOURCE_ATTRIBUTE_MAP
        object in neutron/api/v2/attributes.py. Only these fields
        will be returned.

    :returns: List of floating IPs that are accessible to the tenant who
        submits the request (as indicated by the tenant id of the context)
        as well as any filters.


LOG.info('<STR_LIT>' %<EOL>(context.tenant_id, filters))<EOL>if filters is None:<EOL><INDENT>filters = {}<EOL><DEDENT>filters['<STR_LIT>'] = False<EOL>filters['<STR_LIT>'] = ip_types.FLOATING<EOL>count = db_api.ip_address_count_all(context, filters)<EOL>LOG.info('<STR_LIT>' % (count,<EOL>context.tenant_id))<EOL>return count<EOL>

Return the number of floating IPs.

    :param context: neutron api request context
    :param filters: a dictionary with keys that are valid keys for
        a floating IP as listed in the RESOURCE_ATTRIBUTE_MAP object
        in neutron/api/v2/attributes.py.  Values in this dictionary
        are an iterable containing values that will be used for an exact
        match comparison for that value.  Each result returned by this
        function will have matched one of the values for each key in
        filters.

    :returns: The number of floating IPs that are accessible to the tenant who
        submits the request (as indicated by the tenant id of the context)
        as well as any filters.

    NOTE: this method is optional, as it was not part of the originally
          defined plugin API.


LOG.info('<STR_LIT>',<EOL>context.tenant_id, content)<EOL>network_id = content.get('<STR_LIT>')<EOL>ip_address = content.get('<STR_LIT>')<EOL>requested_ports = content.get('<STR_LIT>', [])<EOL>network = _get_network(context, network_id)<EOL>port_fixed_ips = {}<EOL>for req_port in requested_ports:<EOL><INDENT>port = _get_port(context, req_port['<STR_LIT>'])<EOL>fixed_ip = _get_fixed_ip(context, req_port.get('<STR_LIT>'),<EOL>port)<EOL>port_fixed_ips[port.id] = {"<STR_LIT:port>": port, "<STR_LIT>": fixed_ip}<EOL><DEDENT>scip = _allocate_ip(context, network, None, ip_address, ip_types.SCALING)<EOL>_create_flip(context, scip, port_fixed_ips)<EOL>return v._make_scaling_ip_dict(scip)<EOL>

Allocate or reallocate a scaling IP.

    :param context: neutron api request context.
    :param content: dictionary describing the scaling ip, with keys
        as listed in the RESOURCE_ATTRIBUTE_MAP object in
        neutron/api/v2/attributes.py.  All keys will be populated.

    :returns: Dictionary containing details for the new scaling IP.  If values
        are declared in the fields parameter, then only those keys will be
        present.


def update_scalingip(context, id, content):

LOG.info('<STR_LIT>' %<EOL>(id, context.tenant_id, content))<EOL>requested_ports = content.get('<STR_LIT>', [])<EOL>flip = _update_flip(context, id, ip_types.SCALING, requested_ports)<EOL>return v._make_scaling_ip_dict(flip)<EOL>

Update an existing scaling IP.

    :param context: neutron api request context.
    :param id: id of the scaling ip
    :param content: dictionary with keys indicating fields to update.
        valid keys are those that have a value of True for 'allow_put'
        as listed in the RESOURCE_ATTRIBUTE_MAP object in
        neutron/api/v2/attributes.py.

    :returns: Dictionary containing details for the new scaling IP.  If values
        are declared in the fields parameter, then only those keys will be
        present.


LOG.info('<STR_LIT>' % (id, context.tenant_id))<EOL>_delete_flip(context, id, ip_types.SCALING)<EOL>

Deallocate a scaling IP.

    :param context: neutron api request context.
    :param id: id of the scaling ip


def get_scalingip(context, id, fields=None):

LOG.info('<STR_LIT>' % (id, context.tenant_id))<EOL>filters = {'<STR_LIT>': ip_types.SCALING, '<STR_LIT>': False}<EOL>scaling_ip = db_api.floating_ip_find(context, id=id, scope=db_api.ONE,<EOL>**filters)<EOL>if not scaling_ip:<EOL><INDENT>raise q_exc.ScalingIpNotFound(id=id)<EOL><DEDENT>return v._make_scaling_ip_dict(scaling_ip)<EOL>

Retrieve a scaling IP.

    :param context: neutron api request context.
    :param id: The UUID of the scaling IP.
    :param fields: a list of strings that are valid keys in a
        scaling IP dictionary as listed in the RESOURCE_ATTRIBUTE_MAP
        object in neutron/api/v2/attributes.py. Only these fields
        will be returned.

    :returns: Dictionary containing details for the scaling IP.  If values
        are declared in the fields parameter, then only those keys will be
        present.


def get_scalingips(context, filters=None, fields=None, sorts=['<STR_LIT:id>'],<EOL>limit=None, marker=None, page_reverse=False):

LOG.info('<STR_LIT>' %<EOL>(context.tenant_id, filters, fields))<EOL>scaling_ips = _get_ips_by_type(context, ip_types.SCALING,<EOL>filters=filters, fields=fields)<EOL>return [v._make_scaling_ip_dict(scip) for scip in scaling_ips]<EOL>

Retrieve a list of scaling ips.

    :param context: neutron api request context.
    :param filters: a dictionary with keys that are valid keys for
        a scaling ip as listed in the RESOURCE_ATTRIBUTE_MAP object
        in neutron/api/v2/attributes.py.  Values in this dictionary
        are an iterable containing values that will be used for an exact
        match comparison for that value.  Each result returned by this
        function will have matched one of the values for each key in
        filters.
    :param fields: a list of strings that are valid keys in a
        scaling IP dictionary as listed in the RESOURCE_ATTRIBUTE_MAP
        object in neutron/api/v2/attributes.py. Only these fields
        will be returned.

    :returns: List of scaling IPs that are accessible to the tenant who
        submits the request (as indicated by the tenant id of the context)
        as well as any filters.


def _validate_subnet_cidr(context, network_id, new_subnet_cidr):

if neutron_cfg.cfg.CONF.allow_overlapping_ips:<EOL><INDENT>return<EOL><DEDENT>try:<EOL><INDENT>new_subnet_ipset = netaddr.IPSet([new_subnet_cidr])<EOL><DEDENT>except TypeError:<EOL><INDENT>LOG.exception("<STR_LIT>" % new_subnet_cidr)<EOL>raise n_exc.BadRequest(resource="<STR_LIT>",<EOL>msg="<STR_LIT>")<EOL><DEDENT>filters = {<EOL>'<STR_LIT>': network_id,<EOL>'<STR_LIT>': [False]<EOL>}<EOL>subnet_list = db_api.subnet_find(context=context.elevated(), **filters)<EOL>for subnet in subnet_list:<EOL><INDENT>if (netaddr.IPSet([subnet.cidr]) & new_subnet_ipset):<EOL><INDENT>err_msg = (_("<STR_LIT>"<EOL>"<STR_LIT>"<EOL>"<STR_LIT>") %<EOL>{'<STR_LIT>': new_subnet_cidr,<EOL>'<STR_LIT>': network_id})<EOL>LOG.error(_("<STR_LIT>"<EOL>"<STR_LIT>"<EOL>"<STR_LIT>"),<EOL>{'<STR_LIT>': new_subnet_cidr,<EOL>'<STR_LIT>': subnet.id,<EOL>'<STR_LIT>': subnet.cidr})<EOL>raise n_exc.InvalidInput(error_message=err_msg)<EOL><DEDENT><DEDENT>

Validate the CIDR for a subnet.

    Verifies the specified CIDR does not overlap with the ones defined
    for the other subnets specified for this network, or with any other
    CIDR if overlapping IPs are disabled.


LOG.info("<STR_LIT>" % context.tenant_id)<EOL>net_id = subnet["<STR_LIT>"]["<STR_LIT>"]<EOL>with context.session.begin():<EOL><INDENT>net = db_api.network_find(context=context, limit=None, sorts=['<STR_LIT:id>'],<EOL>marker=None, page_reverse=False, fields=None,<EOL>id=net_id, scope=db_api.ONE)<EOL>if not net:<EOL><INDENT>raise n_exc.NetworkNotFound(net_id=net_id)<EOL><DEDENT>sub_attrs = subnet["<STR_LIT>"]<EOL>always_pop = ["<STR_LIT>", "<STR_LIT>", "<STR_LIT>", "<STR_LIT>",<EOL>"<STR_LIT>"]<EOL>admin_only = ["<STR_LIT>", "<STR_LIT>", "<STR_LIT>",<EOL>"<STR_LIT>"]<EOL>utils.filter_body(context, sub_attrs, admin_only, always_pop)<EOL>_validate_subnet_cidr(context, net_id, sub_attrs["<STR_LIT>"])<EOL>cidr = netaddr.IPNetwork(sub_attrs["<STR_LIT>"])<EOL>err_vals = {'<STR_LIT>': sub_attrs["<STR_LIT>"], '<STR_LIT>': net_id}<EOL>err = _("<STR_LIT>"<EOL>"<STR_LIT>"<EOL>"<STR_LIT>")<EOL>if cidr.version == <NUM_LIT:6> and cidr.prefixlen > <NUM_LIT:64>:<EOL><INDENT>err_vals["<STR_LIT>"] = <NUM_LIT><EOL>err_msg = err % err_vals<EOL>raise n_exc.InvalidInput(error_message=err_msg)<EOL><DEDENT>elif cidr.version == <NUM_LIT:4> and cidr.prefixlen > <NUM_LIT:30>:<EOL><INDENT>err_vals["<STR_LIT>"] = <NUM_LIT><EOL>err_msg = err % err_vals<EOL>raise n_exc.InvalidInput(error_message=err_msg)<EOL><DEDENT>net_subnets = get_subnets(context,<EOL>filters=dict(network_id=net_id))<EOL>if not context.is_admin:<EOL><INDENT>v4_count, v6_count = <NUM_LIT:0>, <NUM_LIT:0><EOL>for subnet in net_subnets:<EOL><INDENT>if netaddr.IPNetwork(subnet['<STR_LIT>']).version == <NUM_LIT:6>:<EOL><INDENT>v6_count += <NUM_LIT:1><EOL><DEDENT>else:<EOL><INDENT>v4_count += <NUM_LIT:1><EOL><DEDENT><DEDENT>if cidr.version == <NUM_LIT:6>:<EOL><INDENT>tenant_quota_v6 = context.session.query(qdv.Quota).filter_by(<EOL>tenant_id=context.tenant_id,<EOL>resource='<STR_LIT>').first()<EOL>if tenant_quota_v6 != -<NUM_LIT:1>:<EOL><INDENT>quota.QUOTAS.limit_check(<EOL>context, context.tenant_id,<EOL>v6_subnets_per_network=v6_count + <NUM_LIT:1>)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>tenant_quota_v4 = context.session.query(qdv.Quota).filter_by(<EOL>tenant_id=context.tenant_id,<EOL>resource='<STR_LIT>').first()<EOL>if tenant_quota_v4 != -<NUM_LIT:1>:<EOL><INDENT>quota.QUOTAS.limit_check(<EOL>context, context.tenant_id,<EOL>v4_subnets_per_network=v4_count + <NUM_LIT:1>)<EOL><DEDENT><DEDENT><DEDENT>gateway_ip = utils.pop_param(sub_attrs, "<STR_LIT>")<EOL>dns_ips = utils.pop_param(sub_attrs, "<STR_LIT>", [])<EOL>host_routes = utils.pop_param(sub_attrs, "<STR_LIT>", [])<EOL>allocation_pools = utils.pop_param(sub_attrs, "<STR_LIT>", None)<EOL>sub_attrs["<STR_LIT>"] = net<EOL>new_subnet = db_api.subnet_create(context, **sub_attrs)<EOL>cidrs = []<EOL>alloc_pools = allocation_pool.AllocationPools(sub_attrs["<STR_LIT>"],<EOL>allocation_pools)<EOL>if isinstance(allocation_pools, list):<EOL><INDENT>cidrs = alloc_pools.get_policy_cidrs()<EOL><DEDENT>quota.QUOTAS.limit_check(<EOL>context,<EOL>context.tenant_id,<EOL>alloc_pools_per_subnet=len(alloc_pools))<EOL>ip_policies.ensure_default_policy(cidrs, [new_subnet])<EOL>new_subnet["<STR_LIT>"] = db_api.ip_policy_create(context,<EOL>exclude=cidrs)<EOL>quota.QUOTAS.limit_check(context, context.tenant_id,<EOL>routes_per_subnet=len(host_routes))<EOL>default_route = None<EOL>for route in host_routes:<EOL><INDENT>netaddr_route = netaddr.IPNetwork(route["<STR_LIT>"])<EOL>if netaddr_route.value == routes.DEFAULT_ROUTE.value:<EOL><INDENT>if default_route:<EOL><INDENT>raise q_exc.DuplicateRouteConflict(<EOL>subnet_id=new_subnet["<STR_LIT:id>"])<EOL><DEDENT>default_route = route<EOL>gateway_ip = default_route["<STR_LIT>"]<EOL>alloc_pools.validate_gateway_excluded(gateway_ip)<EOL><DEDENT>new_subnet["<STR_LIT>"].append(db_api.route_create(<EOL>context, cidr=route["<STR_LIT>"], gateway=route["<STR_LIT>"]))<EOL><DEDENT>quota.QUOTAS.limit_check(context, context.tenant_id,<EOL>dns_nameservers_per_subnet=len(dns_ips))<EOL>for dns_ip in dns_ips:<EOL><INDENT>new_subnet["<STR_LIT>"].append(db_api.dns_create(<EOL>context, ip=netaddr.IPAddress(dns_ip)))<EOL><DEDENT>if gateway_ip and default_route is None:<EOL><INDENT>alloc_pools.validate_gateway_excluded(gateway_ip)<EOL>new_subnet["<STR_LIT>"].append(db_api.route_create(<EOL>context, cidr=str(routes.DEFAULT_ROUTE), gateway=gateway_ip))<EOL><DEDENT><DEDENT>subnet_dict = v._make_subnet_dict(new_subnet)<EOL>subnet_dict["<STR_LIT>"] = gateway_ip<EOL>return subnet_dict<EOL>

Create a subnet.

    Create a subnet which represents a range of IP addresses
    that can be allocated to devices

    : param context: neutron api request context
    : param subnet: dictionary describing the subnet, with keys
        as listed in the RESOURCE_ATTRIBUTE_MAP object in
        neutron/api/v2/attributes.py.  All keys will be populated.


LOG.info("<STR_LIT>" %<EOL>(id, context.tenant_id))<EOL>with context.session.begin():<EOL><INDENT>subnet_db = db_api.subnet_find(context=context, limit=None,<EOL>page_reverse=False, sorts=['<STR_LIT:id>'],<EOL>marker_obj=None, fields=None,<EOL>id=id, scope=db_api.ONE)<EOL>if not subnet_db:<EOL><INDENT>raise n_exc.SubnetNotFound(subnet_id=id)<EOL><DEDENT>s = subnet["<STR_LIT>"]<EOL>always_pop = ["<STR_LIT>", "<STR_LIT>", "<STR_LIT>", "<STR_LIT>", "<STR_LIT>",<EOL>"<STR_LIT>", "<STR_LIT>"]<EOL>admin_only = ["<STR_LIT>", "<STR_LIT>", "<STR_LIT>",<EOL>"<STR_LIT>", "<STR_LIT>"]<EOL>utils.filter_body(context, s, admin_only, always_pop)<EOL>dns_ips = utils.pop_param(s, "<STR_LIT>", [])<EOL>host_routes = utils.pop_param(s, "<STR_LIT>", [])<EOL>gateway_ip = utils.pop_param(s, "<STR_LIT>", None)<EOL>allocation_pools = utils.pop_param(s, "<STR_LIT>", None)<EOL>if not CONF.QUARK.allow_allocation_pool_update:<EOL><INDENT>if allocation_pools:<EOL><INDENT>raise n_exc.BadRequest(<EOL>resource="<STR_LIT>",<EOL>msg="<STR_LIT>")<EOL><DEDENT>if subnet_db["<STR_LIT>"] is not None:<EOL><INDENT>ip_policy_cidrs = subnet_db["<STR_LIT>"].get_cidrs_ip_set()<EOL><DEDENT>else:<EOL><INDENT>ip_policy_cidrs = netaddr.IPSet([])<EOL><DEDENT>alloc_pools = allocation_pool.AllocationPools(<EOL>subnet_db["<STR_LIT>"],<EOL>policies=ip_policy_cidrs)<EOL><DEDENT>else:<EOL><INDENT>alloc_pools = allocation_pool.AllocationPools(subnet_db["<STR_LIT>"],<EOL>allocation_pools)<EOL>original_pools = subnet_db.allocation_pools<EOL>ori_pools = allocation_pool.AllocationPools(subnet_db["<STR_LIT>"],<EOL>original_pools)<EOL>is_growing = _pool_is_growing(ori_pools, alloc_pools)<EOL>if not CONF.QUARK.allow_allocation_pool_growth and is_growing:<EOL><INDENT>raise n_exc.BadRequest(<EOL>resource="<STR_LIT>",<EOL>msg="<STR_LIT>"<EOL>"<STR_LIT>")<EOL><DEDENT><DEDENT>quota.QUOTAS.limit_check(<EOL>context,<EOL>context.tenant_id,<EOL>alloc_pools_per_subnet=len(alloc_pools))<EOL>if gateway_ip:<EOL><INDENT>alloc_pools.validate_gateway_excluded(gateway_ip)<EOL>default_route = None<EOL>for route in host_routes:<EOL><INDENT>netaddr_route = netaddr.IPNetwork(route["<STR_LIT>"])<EOL>if netaddr_route.value == routes.DEFAULT_ROUTE.value:<EOL><INDENT>default_route = route<EOL>break<EOL><DEDENT><DEDENT>if default_route is None:<EOL><INDENT>route_model = db_api.route_find(<EOL>context, cidr=str(routes.DEFAULT_ROUTE), subnet_id=id,<EOL>scope=db_api.ONE)<EOL>if route_model:<EOL><INDENT>db_api.route_update(context, route_model,<EOL>gateway=gateway_ip)<EOL><DEDENT>else:<EOL><INDENT>db_api.route_create(context,<EOL>cidr=str(routes.DEFAULT_ROUTE),<EOL>gateway=gateway_ip, subnet_id=id)<EOL><DEDENT><DEDENT><DEDENT>if dns_ips:<EOL><INDENT>subnet_db["<STR_LIT>"] = []<EOL>quota.QUOTAS.limit_check(context, context.tenant_id,<EOL>dns_nameservers_per_subnet=len(dns_ips))<EOL><DEDENT>for dns_ip in dns_ips:<EOL><INDENT>subnet_db["<STR_LIT>"].append(db_api.dns_create(<EOL>context,<EOL>ip=netaddr.IPAddress(dns_ip)))<EOL><DEDENT>if host_routes:<EOL><INDENT>subnet_db["<STR_LIT>"] = []<EOL>quota.QUOTAS.limit_check(context, context.tenant_id,<EOL>routes_per_subnet=len(host_routes))<EOL><DEDENT>for route in host_routes:<EOL><INDENT>subnet_db["<STR_LIT>"].append(db_api.route_create(<EOL>context, cidr=route["<STR_LIT>"], gateway=route["<STR_LIT>"]))<EOL><DEDENT>if CONF.QUARK.allow_allocation_pool_update:<EOL><INDENT>if isinstance(allocation_pools, list):<EOL><INDENT>cidrs = alloc_pools.get_policy_cidrs()<EOL>ip_policies.ensure_default_policy(cidrs, [subnet_db])<EOL>subnet_db["<STR_LIT>"] = db_api.ip_policy_update(<EOL>context, subnet_db["<STR_LIT>"], exclude=cidrs)<EOL>db_api.subnet_update_set_alloc_pool_cache(context, subnet_db)<EOL><DEDENT><DEDENT>subnet = db_api.subnet_update(context, subnet_db, **s)<EOL><DEDENT>return v._make_subnet_dict(subnet)<EOL>

Update values of a subnet.

    : param context: neutron api request context
    : param id: UUID representing the subnet to update.
    : param subnet: dictionary with keys indicating fields to update.
        valid keys are those that have a value of True for 'allow_put'
        as listed in the RESOURCE_ATTRIBUTE_MAP object in
        neutron/api/v2/attributes.py.


def get_subnet(context, id, fields=None):

LOG.info("<STR_LIT>" %<EOL>(id, context.tenant_id, fields))<EOL>subnet = db_api.subnet_find(context=context, limit=None,<EOL>page_reverse=False, sorts=['<STR_LIT:id>'],<EOL>marker_obj=None, fields=None, id=id,<EOL>join_dns=True, join_routes=True,<EOL>scope=db_api.ONE)<EOL>if not subnet:<EOL><INDENT>raise n_exc.SubnetNotFound(subnet_id=id)<EOL><DEDENT>cache = subnet.get("<STR_LIT>")<EOL>if not cache:<EOL><INDENT>new_cache = subnet.allocation_pools<EOL>db_api.subnet_update_set_alloc_pool_cache(context, subnet, new_cache)<EOL><DEDENT>return v._make_subnet_dict(subnet)<EOL>

Retrieve a subnet.

    : param context: neutron api request context
    : param id: UUID representing the subnet to fetch.
    : param fields: a list of strings that are valid keys in a
        subnet dictionary as listed in the RESOURCE_ATTRIBUTE_MAP
        object in neutron/api/v2/attributes.py. Only these fields
        will be returned.