def get_profiles(self): """ Gets information about every profile in etcd. Returns a generator of ``Profile`` objects. """ LOG.info("Scanning etcd for all profiles") try: result = self.client.read( PROFILE_DIR, recursive=True, timeout=ETCD_TIMEOUT ) except etcd.EtcdKeyNotFound: # No key yet, which is totally fine: just exit. LOG.info("No profiles key present") return nodes = result.children tag_indices = {} rules_indices = {} for node in nodes: # All groups have both tags and rules, and we need the # modifiedIndex for both. tags_match = TAGS_KEY_RE.match(node.key) rules_match = RULES_KEY_RE.match(node.key) if tags_match: profile_id = tags_match.group('profile_id') tag_indices[profile_id] = node.modifiedIndex elif rules_match: profile_id = rules_match.group('profile_id') rules_indices[profile_id] = node.modifiedIndex else: continue # Check whether we have a complete set. If we do, remove them and # yield. if profile_id in tag_indices and profile_id in rules_indices: tag_modified = tag_indices.pop(profile_id) rules_modified = rules_indices.pop(profile_id) LOG.debug("Found profile id %s", profile_id) yield Profile( id=profile_id, tags_modified_index=tag_modified, rules_modified_index=rules_modified, tags_data=None, rules_data=None, ) # Quickly confirm that the tag and rule indices are empty (they should # be). if tag_indices or rules_indices: LOG.warning( "Imbalanced profile tags and rules! " "Extra tags %s, extra rules %s", tag_indices, rules_indices )
def parse_if_rules(etcd_node): m = RULES_KEY_RE.match(etcd_node.key) if m: # Got some rules. profile_id = m.group("profile_id") if etcd_node.action == "delete": rules = None else: rules = parse_rules(profile_id, etcd_node.value) return intern(profile_id.encode("utf8")), rules return None, None
def parse_if_rules(etcd_node): m = RULES_KEY_RE.match(etcd_node.key) if m: # Got some rules. profile_id = m.group("profile_id") if etcd_node.action == "delete": rules = None else: rules = json_decoder.decode(etcd_node.value) rules["id"] = profile_id try: validate_rules(rules) except ValidationFailed: _log.exception("Validation failed for profile %s rules: %s", profile_id, rules) return profile_id, None _log.debug("Found rules for profile %s : %s", profile_id, rules) return profile_id, rules return None, None