def search(filepaths, path_exp): """ Search an item or items from JSON file generated previously by 'parse' sub command. FILEPATHS is a list of file paths or a glob pattern gives that. Examples: \b $ # List ip addresses of system interfaces. $ fortios_xutils search \\ > -P "configs[?config=='system interface'].edits[].ip" \\ > tests/res/parsed/fortigate-01/all.json [ [ "192.168.122.10", "255.255.255.0" ], [ "192.168.1.10", "255.255.255.0" ] ] $ \f :param filepaths: A list of the JSON input file paths. Each JSON file contains parsed results :param path_exp: JMESPath expression to search for """ res = fortios_xutils.query_json_files(filepaths, path_exp) if len(res) == 1: print(anyconfig.dumps(res[0]["results"], ac_parser="json", indent=2)) else: print(anyconfig.dumps(res, ac_parser="json", indent=2))
def context( silent: bool = False, copy: bool = typer.Option(False, "--copy", "-c"), format: str = typer.Option("json", "--format"), pretty: bool = typer.Option(True, "--pretty"), save: bool = typer.Option(False, "--save"), filter: str = typer.Option(None, "--filter", "-f", autocompletion=arc_search), ): config = arc config["arco"]["cli_context"] = "" if filter: try: filtered_data = benedict() filtered_data[filter] = config[filter] config = filtered_data except KeyError as e: message = str(e).replace("\\", "") logger.warning(f"Cannot locate key {message} in context") config = {} if print: config.clean(strings=True, collections=True) if format == "json": if pretty: typer.echo(anyconfig.dumps(config, ac_parser=format, indent=2)) else: typer.echo(anyconfig.dumps(config, format)) elif format == "env": if isinstance(config, dict): dict2Environment(config, print=True) elif format == "yaml": print(config.to_yaml()) # typer.echo(anyconfig.dumps(config, ac_parser=format)) else: logger.error(f"Format {format} not supported") sys.exit(1) return arc if copy: pyperclip.copy(anyconfig.dumps(config, format)) pyperclip.paste() return None
def main(): p = option_parser() (options, args) = p.parse_args() RU.init_log(DEBUG if options.verbose else INFO) if not args: p.print_usage() sys.exit(1) # host_prof_specs = args[0] root = os.path.abspath(options.root) all_rpms = [x["name"] for x in RR.list_installed_rpms(root)] (excludes, removes) = make_excl_packages_list(options.ppaths, options.gpaths) remove_candidates = RU.select_from_list(removes, all_rpms) if options.use_dnf: (excludes, xs) = RED.compute_removed(remove_candidates, root, excludes) else: xs = RR.compute_removed(remove_candidates, root, excludes=excludes) data = dict(removed=xs, excludes=excludes) if options.output: anyconfig.dump(dict(data=data, ), options.output, forced_type="yaml") else: res = anyconfig.dumps(dict(data=data, ), forced_type="yaml") print(res)
def write(self, custom_config: dict = None): # Note: this is only dealing with user config if not os.path.exists(self.config_path): # Create an empty config with open(self.config_path, "a"): os.utime(self.config_path, None) try: if not custom_config: backplane_config = anyconfig.loads( json.dumps(self.toDict()), ac_parser="json" ) else: # Only write user config, not the whole thing user_config = anyconfig.load([str(self.config_path)]) anyconfig.merge(user_config, self.toDict(custom_config)) backplane_config = user_config # anyconfig.merge(backplane_config, config) # if os.path.exists(config_path): # Open ~/.backplane/contexts/default/backplane.yml # Save config as yml with open(self.config_path, "w+") as writer: writer.write(anyconfig.dumps(backplane_config, ac_parser="yaml")) return backplane_config except OSError as e: raise ConfigNotFound(e)
def start(self, deployment): id = deployment["id"] assert (len(deployment["containers"]) == 1 ), "Only one-container pods are supported for now" entity, container = list(deployment["containers"].items())[0] params = { "entity": entity, "deployment_id": id, "image": container["image"] } config = cast_dict_or_list( os.path.join(BASE_DIR, "example/docker-compose.yml.template")) config = fill_template(config, **params) for k, v in container["command_line_arguments"].items(): config["services"][entity]["command"].append(f"--{k}") config["services"][entity]["command"].append(cast_js(v)) makedirs(f"data/docker-compose/{id}/") fn = f"data/docker-compose/{id}/docker-compose.yml" with open(fn, "w") as f: f.write(anyconfig.dumps(config, "yaml")) execute(f'docker-compose -f "{fn}" up -d --no-build')
def start(self, deployment): id = deployment["id"] assert ( len(deployment["containers"]) == 1 ), "Only one-container pods are supported for now" # create docker-compose file and run it without building entity, container = list(deployment["containers"].items())[0] params = {"entity": entity, "deployment_id": id, "image": container["image"]} configs = cast_dict_or_list( os.path.join(BASE_DIR, "example/kubernetes.deployment.yml.template") ) configs = [fill_template(config, **params) for config in configs] for config in configs: if config["kind"] == "ConfigMap": for k, v in container["command_line_arguments"].items(): config["data"][k.upper()] = cast_js(v) config_str = "---\n".join( [anyconfig.dumps(config, "yaml") for config in configs] ) makedirs(f"data/kubernetes/{id}/") fn = f"data/kubernetes/{id}/kubernetes.yml" with open(fn, "w") as f: f.write(config_str) execute(f'kubectl apply -f "{fn}"')
def main(): params_file = None if len(sys.argv) < 4: print('Usage: python test.py TEST_PARAMS_FILE DEFAULT_CONFIG_FILE NUM_ROUNDS') sys.exit(1) else: params_file = str(sys.argv[1]) default_config = str(sys.argv[2]) num_rounds = int(sys.argv[3]) variable_params = anyconfig.load(params_file) default_config = anyconfig.load(default_config) configs = [] for k, v in variable_params.items(): if v is not None: options = v for option in options: new_config = copy.deepcopy(default_config) new_config[k] = option str_option = str(option) new_config['results_file'] = 'results_{}_{}.txt'.format(k, str_option.replace('.', '_')) new_config['num_rounds'] = num_rounds cs = anyconfig.dumps(new_config, ac_parser='yaml') configs.append(cs) pool = mp.Pool(processes=48) for config_str in configs: pool.apply_async(run_param_test, (config_str,)) pool.join()
def get(self, param=None): # pylint: disable=W0221 """ GET handler Gets data, dumps to json and send with proper json mime. """ action = getattr(self, 'get_{}_data'.format(self.ACTION)) res = yield action(param) json = anyconfig.dumps(res, 'json') self.set_header('Content-Type', 'application/json') self.write(json) self.finish()
def firewall_policy_search(filepath, ip_s): """ Search firewall policy table generated by 'firewall-policy-save' command, by ip address. FILEPATH is a file path to the pandas dataframe file generated by 'firewall-policy-save' command. Examples: \b $ fortios_xutils firewall-policy-search \\ > --ip 192.168.122.3 /tmp/0/test.json.gz [ { "edit": "20", "name": "Monitor_Servers_02", "uuid": "3da73baa-dacb-48cb-852c-c4be245b4609", "srcintf": "port1", "dstintf": "", "srcaddr": "host_192.168.122.1", "dstaddr": "network_192.168.122.0/24", "action": "accept", "schedule": "always", "service": [ "HTTPS", "HTTP" ], "inspection-mode": "", "nat": "", "srcaddrs": [ "192.168.122.1/32" ], "dstaddrs": [ "192.168.122.0/24" ], "comments": "" } ] \f :param filepath: Path to a pandas.DataFrame data file contains firewall policy table :param ip_s: IP address string to search """ rdf = fortios_xutils.load_firewall_policy_table(filepath) res = fortios_xutils.search_firewall_policy_table_by_addr(ip_s, rdf) print(anyconfig.dumps(res, ac_parser="json", indent=2))
def writeConfig(config_path: str, config): try: backplane_config = anyconfig.loads(json.dumps(config), ac_parser="json") # anyconfig.merge(backplane_config, config) # if os.path.exists(config_path): # Open ~/.backplane/contexts/default/backplane.yml # Save config as yml with open(config_path, "w+") as writer: writer.write(anyconfig.dumps(backplane_config, ac_parser="yaml")) return backplane_config except OSError as e: typer.secho( f"Couldn't write backplane config at {config_path}: {e}", err=True, fg=typer.colors.RED, ) sys.exit(1)
def main(cmd_map=_ARGS_CMD_MAP): p = option_parser() (options, args) = p.parse_args() RU.init_log(DEBUG if options.verbose else INFO) if not args: p.print_usage() sys.exit(1) (cmd, rpms) = (args[0], args[1:]) cmd = cmd_map.get(cmd[0], cmd_map.get(cmd[:3], False)) if not cmd: print("Error: Invalid command: " + cmd) p.print_usage() sys.exit(1) root = os.path.abspath(options.root) all_rpms = [x["name"] for x in RR.list_installed_rpms(root)] if options.excludes: if is_file(options.excludes): excludes = load_list_from_file(options.excludes) else: excludes = options.excludes.split(',') excludes = RU.select_from_list(excludes, all_rpms) logging.info("%d RPMs found in given excludes list" % len(excludes)) else: excludes = [] if cmd == CMD_REMOVE: if not rpms: print("remove (erase) command requires RPMs: list of RPM names or " "glob/regex patterns, or a file contains RPM names or " "glob/regex patterns line by line") sys.exit(1) if len(rpms) == 1 and is_file(rpms[0]): rpms = load_list_from_file(rpms[0]) rpms = RU.select_from_list(rpms, all_rpms) if options.use_dnf: (excludes, xs) = RED.compute_removed(rpms, root, excludes) else: xs = RR.compute_removed(rpms, root, excludes=excludes) data = dict(removed=xs, ) elif cmd == CMD_STANDALONES: xs = sorted(RR.list_standalones(root, options.st_nrpms, excludes)) data = dict(standalones=xs, ) elif cmd == CMD_UPDATES: xs = [dict(name=x.name, version=x.version, release=x.release, arch=x.arch, epoch=int(x.epoch)) for x in RED.compute_updates(root, options.repos, True)] if options.latest: xs = RR.find_latests(xs) if options.format == 'simple': xfmt = "%(name)s-%(epoch)s:%(version)s-%(release)s.%(arch)s" xs = sorted(xfmt % x for x in xs) data = dict(updates=xs, ) else: xs = sorted(RR.get_leaves(root)) data = dict(leaves=xs, ) output = open(options.output, 'w') if options.output else sys.stdout if options.format != "simple": if options.output: anyconfig.dump(dict(data=data, ), options.output, forced_type=options.format) else: res = anyconfig.dumps(dict(data=data, ), forced_type=options.format) print(res) else: if options.output: ext = os.path.splitext(options.output)[1][1:] if ext in _FMT_CHOICES: anyconfig.dump(dict(data=data, ), options.output, forced_type=ext) else: with open(options.output, 'w') as out: for x in xs: out.write(x + '\n') else: for x in xs: print(x) output.close()
def network_find_paths(filepath, src_ip, dst_ip, ntype=None): """ Search paths from the source `src_ip` to the destination `dst_ip`. Examples: \b $ fortios_xutils/cli.py network-find-paths \\ > tests/res/networks/graph.yml 192.168.122.2 192.168.5.10 [ [ { "id": "fortigate-01", "name": "fortigate-01", "type": "firewall", "addrs": [ "192.168.122.10/24", "192.168.1.10/24" ], "type_id": 5, "class": "node firewall", "label": "fortigate-01 firewall" }, { "id": "192.168.122.0/24", "name": "192.168.122.0/24", "type": "network", "addrs": [ "192.168.122.0/24" ], "type_id": 1, "class": "node network", "label": "192.168.122.0/24 network" }, ... (snip) ... { "id": "192.168.5.0/24", "name": "192.168.5.0/24", "type": "network", "addrs": [ "192.168.5.0/24" ], "type_id": 1, "class": "node network", "label": "192.168.5.0/24 network" } ], ... (snip) ... $ \f :param filepath: Path of the json or yaml file contains netowrk nodes and links information. :param src_ip: IP address of the source :param dst_ip: IP address of the destination """ res = fortios_xutils.find_network_paths(filepath, src_ip, dst_ip) aopts = dict(ac_parser="json", indent=2) print(anyconfig.dumps(res, **aopts))
def main(cmd_map=_ARGS_CMD_MAP): p = option_parser() (options, args) = p.parse_args() RU.init_log(DEBUG if options.verbose else INFO) if not args: p.print_usage() sys.exit(1) (cmd, rpms) = (args[0], args[1:]) cmd = cmd_map.get(cmd[0], cmd_map.get(cmd[:3], False)) if not cmd: print("Error: Invalid command: " + cmd) p.print_usage() sys.exit(1) root = os.path.abspath(options.root) all_rpms = [x["name"] for x in RR.list_installed_rpms(root)] if options.excludes: if is_file(options.excludes): excludes = load_list_from_file(options.excludes) else: excludes = options.excludes.split(',') excludes = RU.select_from_list(excludes, all_rpms) logging.info("%d RPMs found in given excludes list" % len(excludes)) else: excludes = [] if cmd == CMD_REMOVE: if not rpms: print("remove (erase) command requires RPMs: list of RPM names or " "glob/regex patterns, or a file contains RPM names or " "glob/regex patterns line by line") sys.exit(1) if len(rpms) == 1 and is_file(rpms[0]): rpms = load_list_from_file(rpms[0]) rpms = RU.select_from_list(rpms, all_rpms) if options.use_dnf: (excludes, xs) = RED.compute_removed(rpms, root, excludes) else: xs = RR.compute_removed(rpms, root, excludes=excludes) data = dict(removed=xs, ) elif cmd == CMD_STANDALONES: xs = sorted(RR.list_standalones(root, options.st_nrpms, excludes)) data = dict(standalones=xs, ) elif cmd == CMD_UPDATES: xs = [ dict(name=x.name, version=x.version, release=x.release, arch=x.arch, epoch=int(x.epoch)) for x in RED.compute_updates(root, options.repos, True) ] if options.latest: xs = RR.find_latests(xs) if options.format == 'simple': xfmt = "%(name)s-%(epoch)s:%(version)s-%(release)s.%(arch)s" xs = sorted(xfmt % x for x in xs) data = dict(updates=xs, ) else: xs = sorted(RR.get_leaves(root)) data = dict(leaves=xs, ) output = open(options.output, 'w') if options.output else sys.stdout if options.format != "simple": if options.output: anyconfig.dump(dict(data=data, ), options.output, forced_type=options.format) else: res = anyconfig.dumps(dict(data=data, ), forced_type=options.format) print(res) else: if options.output: ext = os.path.splitext(options.output)[1][1:] if ext in _FMT_CHOICES: anyconfig.dump(dict(data=data, ), options.output, forced_type=ext) else: with open(options.output, 'w') as out: for x in xs: out.write(x + '\n') else: for x in xs: print(x) output.close()