def main(): """Main code.""" # Process any command-line arguments args = processcli() log = ConsolePrinter(args) validateargs(args, log) search_values = True search_keys = False include_key_aliases = False include_value_aliases = False if args.onlykeynames: search_values = False search_keys = True elif args.keynames: search_keys = True if args.include_aliases is IncludeAliases.INCLUDE_ALL_ALIASES: include_key_aliases = True include_value_aliases = True elif args.include_aliases is IncludeAliases.INCLUDE_KEY_ALIASES: include_key_aliases = True elif args.include_aliases is IncludeAliases.INCLUDE_VALUE_ALIASES: include_value_aliases = True # Prepare the YAML processor yaml = get_yaml_editor() processor = EYAMLProcessor(log, None, binary=args.eyaml, publickey=args.publickey, privatekey=args.privatekey) # Process the input file(s) exit_state = 0 # pylint: disable=too-many-nested-blocks for yaml_file in args.yaml_files: # Try to open the file yaml_data = get_yaml_data(yaml, log, yaml_file) if yaml_data is None: # An error message has already been logged exit_state = 3 continue # Process all searches processor.data = yaml_data yaml_paths = [] for expression in args.search: exterm = get_search_term(log, expression) log.debug(("yaml_paths::main:" + "converting search expression '{}' into '{}'").format( expression, exterm)) if exterm is None: exit_state = 1 continue for result in search_for_paths( log, processor, yaml_data, exterm, args.pathsep, search_values=search_values, search_keys=search_keys, search_anchors=args.refnames, include_key_aliases=include_key_aliases, include_value_aliases=include_value_aliases, decrypt_eyaml=args.decrypt, expand_children=args.expand): # Record only unique results add_entry = True for entry in yaml_paths: if str(result) == str(entry[1]): add_entry = False break if add_entry: yaml_paths.append((expression, result)) if not yaml_paths: # Nothing further to do when there are no results continue if args.except_expression: for expression in args.except_expression: exterm = get_search_term(log, expression) log.debug( ("yaml_paths::main:" + "converted except expression '{}' into '{}'").format( expression, exterm)) if exterm is None: exit_state = 1 continue for result in search_for_paths( log, processor, yaml_data, exterm, args.pathsep, search_values=search_values, search_keys=search_keys, search_anchors=args.refnames, include_key_aliases=include_key_aliases, include_value_aliases=include_value_aliases, decrypt_eyaml=args.decrypt, expand_children=args.expand): for entry in yaml_paths: if str(result) == str(entry[1]): yaml_paths.remove(entry) break # Entries are already unique print_results(args, processor, yaml_file, yaml_paths) exit(exit_state)
def main(): """Main code.""" # Process any command-line arguments args = processcli() log = ConsolePrinter(args) validateargs(args, log) processor = EYAMLProcessor(log, None, binary=args.eyaml) # Prep the YAML parser yaml = Parsers.get_yaml_editor() # Process the input file(s) in_file_count = len(args.yaml_files) exit_state = 0 for yaml_file in args.yaml_files: file_changed = False backup_file = yaml_file + ".bak" seen_anchors = [] # Each YAML_FILE must actually be a file if not isfile(yaml_file): log.error("Not a file: {}".format(yaml_file)) exit_state = 2 continue # Don't bother with the file change update when there's only one input # file. if in_file_count > 1: log.info("Processing {}...".format(yaml_file)) # Try to open the file (yaml_data, doc_loaded) = Parsers.get_yaml_data(yaml, log, yaml_file) if not doc_loaded: # An error message has already been logged exit_state = 3 continue # Process all EYAML values processor.data = yaml_data for yaml_path in processor.find_eyaml_paths(): # Use ::get_nodes() instead of ::get_eyaml_values() here in order # to ignore values that have already been rotated via their # Anchors. for node_coordinate in processor.get_nodes(yaml_path, mustexist=True): # Ignore values which are Aliases for those already decrypted node = node_coordinate.node anchor_name = Anchors.get_node_anchor(node) if anchor_name is not None: if anchor_name in seen_anchors: continue seen_anchors.append(anchor_name) log.verbose("Decrypting value(s) at {}.".format(yaml_path)) processor.publickey = args.oldpublickey processor.privatekey = args.oldprivatekey try: txtval = processor.decrypt_eyaml(node) except EYAMLCommandException as ex: log.error(ex) exit_state = 3 continue # Prefer block (folded) values unless the original YAML value # was already a massivly long (string) line. output = EYAMLOutputFormats.BLOCK if not isinstance(node, FoldedScalarString): output = EYAMLOutputFormats.STRING # Re-encrypt the value with new EYAML keys processor.publickey = args.newpublickey processor.privatekey = args.newprivatekey try: processor.set_eyaml_value(yaml_path, txtval, output=output) except EYAMLCommandException as ex: log.error(ex) exit_state = 3 continue file_changed = True # Save the changes if file_changed: if args.backup: log.verbose("Saving a backup of {} to {}.".format( yaml_file, backup_file)) if exists(backup_file): remove(backup_file) copy2(yaml_file, backup_file) log.verbose("Writing changed data to {}.".format(yaml_file)) with open(yaml_file, 'w', encoding='utf-8') as yaml_dump: yaml.dump(yaml_data, yaml_dump) sys.exit(exit_state)