diff --git a/.gitignore b/.gitignore index 3c9f657..67d0277 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ __pycache__ /result /.venv /zig-cache +/.zig-cache /zig-out diff --git a/build.zig b/build.zig index 12c6cae..9356c78 100644 --- a/build.zig +++ b/build.zig @@ -5,7 +5,7 @@ pub fn build(b: *std.Build) void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); - const ssh_path = b.option( + const ssh_command = b.option( []const u8, "ssh", "path to ssh binary", @@ -18,7 +18,7 @@ pub fn build(b: *std.Build) void { break :ssh p; }; - const telnet_path = b.option( + const telnet_command = b.option( []const u8, "telnet", "path to telnet binary", @@ -32,58 +32,18 @@ pub fn build(b: *std.Build) void { }; const exe = b.addExecutable(.{ - .name = "hostapps", - .root_source_file = .{ .path = "src/main.zig" }, + .name = "hostapps-connect", + .root_source_file = b.path("src/main.zig"), .target = target, .optimize = optimize, }); const build_options = b.addOptions(); - build_options.addOption([]const u8, "ssh_path", ssh_path); - build_options.addOption([]const u8, "telnet_path", telnet_path); + build_options.addOption([]const u8, "ssh_command", ssh_command); + build_options.addOption([]const u8, "telnet_command", telnet_command); exe.root_module.addOptions("build_options", build_options); - const anzi = b.dependency( - "anzi", - .{ - .target = target, - .optimize = optimize, - }, - ); - - exe.root_module.addImport("anzi", anzi.module("anzi")); - - // const netboxz = b.dependency( - // "netboxz", - // .{ - // .target = target, - // .optimize = optimize, - // }, - // ); - - // exe.root_module.addImport("netboxz", netboxz.module("netboxz")); - - const logz = b.dependency( - "logz", - .{ - .target = target, - .optimize = optimize, - }, - ); - - exe.root_module.addImport("logz", logz.module("logz")); - - const @"zig-cli" = b.dependency( - "zig-cli", - .{ - .target = target, - .optimize = optimize, - }, - ); - - exe.root_module.addImport("zig-cli", @"zig-cli".module("zig-cli")); - b.installArtifact(exe); const run_cmd = b.addRunArtifact(exe); @@ -98,7 +58,7 @@ pub fn build(b: *std.Build) void { run_step.dependOn(&run_cmd.step); const exe_unit_tests = b.addTest(.{ - .root_source_file = .{ .path = "src/main.zig" }, + .root_source_file = b.path("src/main.zig"), .target = target, .optimize = optimize, }); diff --git a/build.zig.zon b/build.zig.zon index b8258cb..9a17af1 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -1,27 +1,20 @@ .{ .name = "hostapps", .version = "0.1.0", - .minimum_zig_version = "0.12.0", + .minimum_zig_version = "0.13.0", .dependencies = .{ - .logz = .{ - .url = "https://github.com/karlseguin/log.zig/archive/2f17be4b6bbd32884df562a8d0501c15ec3bb928.tar.gz", - // .hash = "1220b6cf56de826aead943a6db2a62ed40d81a150c24dcb019b3eb88673c82a6e7b7", - .hash = "1220347c287af8b265e36cffaf1c29e22da887e8fdcf38310e7b7d3c65ce64acf4f0", - }, - .anzi = .{ - .url = "https://git.ocjtech.us/jeff/anzi/archive/0e9d395a55b16da1d5bf7bfb59e2cfa59a7f2630.tar.gz", - .hash = "12203f0ed986047bcd860b00496979a7734c2f462da4e56a72add4b17a1a7981f8ec", - }, - // .netboxz = .{ - // // .url = "https://github.com/jcollie/netboxz/archive/354caea69a1e033cf34da6c5e514dc4eb755af06.tar.gz", - // // .hash = "1220374f4587ec4d1e820a45039cd4bedd7cd560a3a668fdae2db0b5a6609f97c793", - // .path = "../netboxz", + // .logz = .{ + // .url = "https://github.com/karlseguin/log.zig/archive/5d5bbaeb98ad30cda30c60ab0f2d1a7fb4890676.tar.gz", + // .hash = "122030cda8b80a813ed2d1c460b9d1138bbb0c325f4ccda74785810e7395d6154670", + // }, + // .anzi = .{ + // .url = "https://git.ocjtech.us/jeff/anzi/archive/0e9d395a55b16da1d5bf7bfb59e2cfa59a7f2630.tar.gz", + // .hash = "12203f0ed986047bcd860b00496979a7734c2f462da4e56a72add4b17a1a7981f8ec", + // }, + // .@"zig-cli" = .{ + // .url = "https://github.com/sam701/zig-cli/archive/ac82640e750efb3b89c609032bdec0898739a790.tar.gz", + // .hash = "1220203f73d7a17299a5d1a2f7902bc1c8ad9d20c8f7c40b4852dfd77bdb6ff7ec5e", // }, - .@"zig-cli" = .{ - .url = "https://github.com/sam701/zig-cli/archive/9a94c4803a52e54c26b198096d63fb5bde752da2.tar.gz", - // .hash = "12208a4377c7699927605e5a797bad5ae2ba8be4b49f68b9f522b3a755597a21f1cf", - .hash = "1220ab73fb7cc11b2308edc3364988e05efcddbcac31b707f55e6216d1b9c0da13f1", - }, }, .paths = .{ "build.zig", diff --git a/flake.lock b/flake.lock index 6abd721..32a2837 100644 --- a/flake.lock +++ b/flake.lock @@ -5,11 +5,11 @@ "systems": "systems" }, "locked": { - "lastModified": 1726560853, - "narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=", + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", "owner": "numtide", "repo": "flake-utils", - "rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", "type": "github" }, "original": { @@ -33,34 +33,13 @@ "type": "github" } }, - "nix-github-actions": { - "inputs": { - "nixpkgs": [ - "poetry2nix", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1703863825, - "narHash": "sha256-rXwqjtwiGKJheXB43ybM8NwWB8rO2dSRrEqes0S7F5Y=", - "owner": "nix-community", - "repo": "nix-github-actions", - "rev": "5163432afc817cf8bd1f031418d1869e4c9d5547", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "nix-github-actions", - "type": "github" - } - }, "nixpkgs": { "locked": { - "lastModified": 1726755586, - "narHash": "sha256-PmUr/2GQGvFTIJ6/Tvsins7Q43KTMvMFhvG6oaYK+Wk=", + "lastModified": 1733940404, + "narHash": "sha256-Pj39hSoUA86ZePPF/UXiYHHM7hMIkios8TYG29kQT4g=", "owner": "nixos", "repo": "nixpkgs", - "rev": "c04d5652cfa9742b1d519688f65d1bbccea9eb7e", + "rev": "5d67ea6b4b63378b9c13be21e2ec9d1afc921713", "type": "github" }, "original": { @@ -70,38 +49,11 @@ "type": "github" } }, - "poetry2nix": { - "inputs": { - "flake-utils": [ - "flake-utils" - ], - "nix-github-actions": "nix-github-actions", - "nixpkgs": [ - "nixpkgs" - ], - "systems": "systems_2", - "treefmt-nix": "treefmt-nix" - }, - "locked": { - "lastModified": 1726715047, - "narHash": "sha256-OUpbkEbpkRh91WX8XYq5rugIHhzJUS84qwvCd+HBer8=", - "owner": "nix-community", - "repo": "poetry2nix", - "rev": "1f4d4dcab3ee4b6a674e9d9ca9c8d125c7811634", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "poetry2nix", - "type": "github" - } - }, "root": { "inputs": { "flake-utils": "flake-utils", "make-shell": "make-shell", - "nixpkgs": "nixpkgs", - "poetry2nix": "poetry2nix" + "nixpkgs": "nixpkgs" } }, "systems": { @@ -118,41 +70,6 @@ "repo": "default", "type": "github" } - }, - "systems_2": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "id": "systems", - "type": "indirect" - } - }, - "treefmt-nix": { - "inputs": { - "nixpkgs": [ - "poetry2nix", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1719749022, - "narHash": "sha256-ddPKHcqaKCIFSFc/cvxS14goUhCOAwsM1PbMr0ZtHMg=", - "owner": "numtide", - "repo": "treefmt-nix", - "rev": "8df5ff62195d4e67e2264df0b7f5e8c9995fd0bd", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "treefmt-nix", - "type": "github" - } } }, "root": "root", diff --git a/flake.nix b/flake.nix index f8dd8b3..ccd05f8 100644 --- a/flake.nix +++ b/flake.nix @@ -7,17 +7,13 @@ flake-utils = { url = "github:numtide/flake-utils"; }; - poetry2nix = { - url = "github:nix-community/poetry2nix"; - inputs.nixpkgs.follows = "nixpkgs"; - inputs.flake-utils.follows = "flake-utils"; - }; make-shell = { url = "github:ursi/nix-make-shell"; }; # zig = { # url = "github:mitchellh/zig-overlay"; # inputs.nixpkgs.follows = "nixpkgs"; + # inputs.flake-utils.follows = "flake-utils"; # }; # zls = { # url = "github:zigtools/zls"; @@ -36,12 +32,11 @@ flake-utils.lib.eachDefaultSystem ( system: let - # version = self.lastModifiedDate; pkgs = import nixpkgs { inherit system; config.permittedInsecurePackages = []; }; - zig_hook = pkgs.zig_0_12.hook.overrideAttrs { + zig_hook = pkgs.zig_0_13.hook.overrideAttrs { zig_default_flags = "-Dcpu=baseline -Doptimize=ReleaseFast"; }; make-shell = import inputs.make-shell { @@ -50,7 +45,7 @@ # inherit (poetry2nix.lib.mkPoetry2Nix {inherit pkgs;}) mkPoetryApplication overrides; in { packages = { - hostapps = pkgs.python3.pkgs.buildPythonPackage { + hostapps-python = pkgs.python3.pkgs.buildPythonPackage { pname = "hostapps"; version = "0.1.0"; pyproject = true; @@ -63,54 +58,18 @@ ]; doCheck = false; }; - # hostapps = mkPoetryApplication { - # python = pkgs.python3; - # projectDir = ./.; - # propagatedBuildInputs = [ - # pkgs.git - # pkgs.inetutils - # pkgs.openssh - # pkgs.sshpass - # ]; - # overrides = overrides.withDefaults ( - # self: super: { - # pyansi = super.pyansi.overridePythonAttrs ( - # old: { - # buildInputs = old.buildInputs ++ [self.poetry]; - # } - # ); - # # annotated-types = super.annotated-types.overridePythonAttrs ( - # # old: { - # # buildInputs = old.buildInputs ++ [self.hatchling]; - # # } - # # ); - # # pydantic-core = super.pydantic-core.overridePythonAttrs ( - # # old: { - # # buildInputs = old.buildInputs ++ [self.maturin]; - # # } - # # ); - # } - # ); - # }; hostapps-zig = let cache = src: pkgs.stdenv.mkDerivation { inherit src; name = "hostapps-zig-cache"; nativeBuildInputs = [pkgs.git zig_hook]; - # buildInputs = [ - # pkgs.zig_0_12 - # ]; dontConfigure = true; dontUseZigBuild = true; dontUseZigInstall = true; dontFixup = true; - # preBuild = '' - # export ZIG_GLOBAL_CACHE_DIR=$(mktemp -d) - # ''; - buildPhase = '' runHook preBuild zig build --fetch @@ -123,7 +82,7 @@ runHook postInstall ''; # outputHash = pkgs.lib.fakeHash; - outputHash = "sha256-DilCltrfYt7XpHbNNyylBwhantmhNkhHxILjhdmUqOA="; + outputHash = "sha256-OOBbn07bYUxYEudlone34/jJd4Aw1pEtEQVIrnZdqHY="; outputHashMode = "recursive"; }; in @@ -136,13 +95,11 @@ nativeBuildInputs = [ pkgs.git + pkgs.inetutils + pkgs.openssh zig_hook ]; - # buildInputs = [ - # pkgs.zig_0_12 - # ]; - preBuild = '' rm -rf $ZIG_GLOBAL_CACHE_DIR cp -r --reflink=auto ${cache attrs.src} $ZIG_GLOBAL_CACHE_DIR @@ -181,8 +138,7 @@ pkgs.openssh pkgs.poetry pkgs.sshpass - pkgs.zig_0_12 - pkgs.zls + pkgs.zig_0_13 ]; env = { name = project; diff --git a/hostapps/run.py b/hostapps/run.py deleted file mode 100644 index ab1c60b..0000000 --- a/hostapps/run.py +++ /dev/null @@ -1,125 +0,0 @@ -import os -import pathlib -import socket -import sys - -import click -import pyansi -from pydantic import BaseModel -from pydantic import TypeAdapter - -kex_algorithms = [ - "diffie-hellman-group14-sha1", - "diffie-hellman-group1-sha1", - "diffie-hellman-group-exchange-sha1", - "diffie-hellman-group-exchange-sha256", - "ecdh-sha2-nistp256", -] - -ciphers = [ - "aes256-cbc", - "aes192-cbc", - "3des-cbc", - "aes128-cbc", - "aes256-ctr", - "aes192-ctr", - "aes128-ctr", -] - -macs = [ - "hmac-md5", - "hmac-sha1", - "hmac-sha2-256-etm@openssh.com", - "hmac-sha2-512-etm@openssh.com", - "hmac-sha2-256", - "hmac-sha2-512", -] - -options = [ - ("Ciphers", f"{','.join(ciphers)}"), - ("ControlMaster", "no"), - ("ControlPath", "none"), - ("ForwardX11", "no"), - ("ForwardX11Trusted", "no"), - ("HostKeyAlgorithms", "+ssh-rsa"), - ("KexAlgorithms", f"{','.join(kex_algorithms)}"), - ("MACs", f"{','.join(macs)}"), - ("PubkeyAcceptedKeyTypes", "+ssh-rsa"), -] - - -class Entry(BaseModel): - name: str - type: str - comment: str - address: str - port: int - username: str - manufacturer: str - model: str - part_number: str - - -Config = TypeAdapter(dict[str, Entry]) - - -@click.command() -@click.option("--ssh-command", default="ssh") -@click.option("--telnet-command", default="telnet") -@click.option("--config", type=click.Path(exists=True, path_type=pathlib.Path)) -def main( - ssh_command: str, - telnet_command: str, - config: pathlib.Path, -): - entry = Entry.model_validate_json(config.read_bytes()) - - a = pyansi.ANSI() - sys.stdout.write(a.Title(text=f"{entry.name} - {entry.address}")) - sys.stdout.flush() - - # if 'SSH_AUTH_SOCK' in os.environ: - # journal.send('Removing SSH_AUTH_SOCK from environment') - # del os.environ['SSH_AUTH_SOCK'] - - command = [] - - match entry.type: - case "ssh": - command = [ - ssh_command, - "ssh", - # "-v", - "-y", - ] - - if socket.gethostname() != "pc60929": - command += ["-o", "ProxyJump=jcollie@pc60929"] - - command += [ - "-i", - "~/.ssh/id_dmacc_rsa", - ] - - for k, v in options: - command += ["-o", f"{k}={v}"] - - command += [ - "-o", - f"User={entry.username}", - entry.address, - ] - - case "telnet": - command = [telnet_command, "telnet"] - - if socket.gethostname() != "pc60929": - command = [ssh_command, "ssh", "-t", "ssh://jcollie@pc60929", "telnet"] - - command += [entry.address] - - os.execlp(*command) - - -if __name__ == "__main__": - main() diff --git a/poetry.lock b/poetry.lock index 4c39377..5d19bc4 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.5 and should not be changed by hand. [[package]] name = "annotated-types" @@ -173,18 +173,18 @@ files = [ [[package]] name = "pydantic" -version = "2.8.2" +version = "2.9.2" description = "Data validation using Python type hints" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic-2.8.2-py3-none-any.whl", hash = "sha256:73ee9fddd406dc318b885c7a2eab8a6472b68b8fb5ba8150949fc3db939f23c8"}, - {file = "pydantic-2.8.2.tar.gz", hash = "sha256:6f62c13d067b0755ad1c21a34bdd06c0c12625a22b0fc09c6b149816604f7c2a"}, + {file = "pydantic-2.9.2-py3-none-any.whl", hash = "sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12"}, + {file = "pydantic-2.9.2.tar.gz", hash = "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f"}, ] [package.dependencies] -annotated-types = ">=0.4.0" -pydantic-core = "2.20.1" +annotated-types = ">=0.6.0" +pydantic-core = "2.23.4" typing-extensions = [ {version = ">=4.12.2", markers = "python_version >= \"3.13\""}, {version = ">=4.6.1", markers = "python_version < \"3.13\""}, @@ -192,103 +192,104 @@ typing-extensions = [ [package.extras] email = ["email-validator (>=2.0.0)"] +timezone = ["tzdata"] [[package]] name = "pydantic-core" -version = "2.20.1" +version = "2.23.4" description = "Core functionality for Pydantic validation and serialization" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic_core-2.20.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3acae97ffd19bf091c72df4d726d552c473f3576409b2a7ca36b2f535ffff4a3"}, - {file = "pydantic_core-2.20.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:41f4c96227a67a013e7de5ff8f20fb496ce573893b7f4f2707d065907bffdbd6"}, - {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f239eb799a2081495ea659d8d4a43a8f42cd1fe9ff2e7e436295c38a10c286a"}, - {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:53e431da3fc53360db73eedf6f7124d1076e1b4ee4276b36fb25514544ceb4a3"}, - {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f1f62b2413c3a0e846c3b838b2ecd6c7a19ec6793b2a522745b0869e37ab5bc1"}, - {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5d41e6daee2813ecceea8eda38062d69e280b39df793f5a942fa515b8ed67953"}, - {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d482efec8b7dc6bfaedc0f166b2ce349df0011f5d2f1f25537ced4cfc34fd98"}, - {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e93e1a4b4b33daed65d781a57a522ff153dcf748dee70b40c7258c5861e1768a"}, - {file = "pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e7c4ea22b6739b162c9ecaaa41d718dfad48a244909fe7ef4b54c0b530effc5a"}, - {file = "pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4f2790949cf385d985a31984907fecb3896999329103df4e4983a4a41e13e840"}, - {file = "pydantic_core-2.20.1-cp310-none-win32.whl", hash = "sha256:5e999ba8dd90e93d57410c5e67ebb67ffcaadcea0ad973240fdfd3a135506250"}, - {file = "pydantic_core-2.20.1-cp310-none-win_amd64.whl", hash = "sha256:512ecfbefef6dac7bc5eaaf46177b2de58cdf7acac8793fe033b24ece0b9566c"}, - {file = "pydantic_core-2.20.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d2a8fa9d6d6f891f3deec72f5cc668e6f66b188ab14bb1ab52422fe8e644f312"}, - {file = "pydantic_core-2.20.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:175873691124f3d0da55aeea1d90660a6ea7a3cfea137c38afa0a5ffabe37b88"}, - {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37eee5b638f0e0dcd18d21f59b679686bbd18917b87db0193ae36f9c23c355fc"}, - {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:25e9185e2d06c16ee438ed39bf62935ec436474a6ac4f9358524220f1b236e43"}, - {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:150906b40ff188a3260cbee25380e7494ee85048584998c1e66df0c7a11c17a6"}, - {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ad4aeb3e9a97286573c03df758fc7627aecdd02f1da04516a86dc159bf70121"}, - {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3f3ed29cd9f978c604708511a1f9c2fdcb6c38b9aae36a51905b8811ee5cbf1"}, - {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b0dae11d8f5ded51699c74d9548dcc5938e0804cc8298ec0aa0da95c21fff57b"}, - {file = "pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:faa6b09ee09433b87992fb5a2859efd1c264ddc37280d2dd5db502126d0e7f27"}, - {file = "pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9dc1b507c12eb0481d071f3c1808f0529ad41dc415d0ca11f7ebfc666e66a18b"}, - {file = "pydantic_core-2.20.1-cp311-none-win32.whl", hash = "sha256:fa2fddcb7107e0d1808086ca306dcade7df60a13a6c347a7acf1ec139aa6789a"}, - {file = "pydantic_core-2.20.1-cp311-none-win_amd64.whl", hash = "sha256:40a783fb7ee353c50bd3853e626f15677ea527ae556429453685ae32280c19c2"}, - {file = "pydantic_core-2.20.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:595ba5be69b35777474fa07f80fc260ea71255656191adb22a8c53aba4479231"}, - {file = "pydantic_core-2.20.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a4f55095ad087474999ee28d3398bae183a66be4823f753cd7d67dd0153427c9"}, - {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f9aa05d09ecf4c75157197f27cdc9cfaeb7c5f15021c6373932bf3e124af029f"}, - {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e97fdf088d4b31ff4ba35db26d9cc472ac7ef4a2ff2badeabf8d727b3377fc52"}, - {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bc633a9fe1eb87e250b5c57d389cf28998e4292336926b0b6cdaee353f89a237"}, - {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d573faf8eb7e6b1cbbcb4f5b247c60ca8be39fe2c674495df0eb4318303137fe"}, - {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26dc97754b57d2fd00ac2b24dfa341abffc380b823211994c4efac7f13b9e90e"}, - {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:33499e85e739a4b60c9dac710c20a08dc73cb3240c9a0e22325e671b27b70d24"}, - {file = "pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:bebb4d6715c814597f85297c332297c6ce81e29436125ca59d1159b07f423eb1"}, - {file = "pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:516d9227919612425c8ef1c9b869bbbee249bc91912c8aaffb66116c0b447ebd"}, - {file = "pydantic_core-2.20.1-cp312-none-win32.whl", hash = "sha256:469f29f9093c9d834432034d33f5fe45699e664f12a13bf38c04967ce233d688"}, - {file = "pydantic_core-2.20.1-cp312-none-win_amd64.whl", hash = "sha256:035ede2e16da7281041f0e626459bcae33ed998cca6a0a007a5ebb73414ac72d"}, - {file = "pydantic_core-2.20.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:0827505a5c87e8aa285dc31e9ec7f4a17c81a813d45f70b1d9164e03a813a686"}, - {file = "pydantic_core-2.20.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:19c0fa39fa154e7e0b7f82f88ef85faa2a4c23cc65aae2f5aea625e3c13c735a"}, - {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa223cd1e36b642092c326d694d8bf59b71ddddc94cdb752bbbb1c5c91d833b"}, - {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c336a6d235522a62fef872c6295a42ecb0c4e1d0f1a3e500fe949415761b8a19"}, - {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7eb6a0587eded33aeefea9f916899d42b1799b7b14b8f8ff2753c0ac1741edac"}, - {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:70c8daf4faca8da5a6d655f9af86faf6ec2e1768f4b8b9d0226c02f3d6209703"}, - {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9fa4c9bf273ca41f940bceb86922a7667cd5bf90e95dbb157cbb8441008482c"}, - {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:11b71d67b4725e7e2a9f6e9c0ac1239bbc0c48cce3dc59f98635efc57d6dac83"}, - {file = "pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:270755f15174fb983890c49881e93f8f1b80f0b5e3a3cc1394a255706cabd203"}, - {file = "pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c81131869240e3e568916ef4c307f8b99583efaa60a8112ef27a366eefba8ef0"}, - {file = "pydantic_core-2.20.1-cp313-none-win32.whl", hash = "sha256:b91ced227c41aa29c672814f50dbb05ec93536abf8f43cd14ec9521ea09afe4e"}, - {file = "pydantic_core-2.20.1-cp313-none-win_amd64.whl", hash = "sha256:65db0f2eefcaad1a3950f498aabb4875c8890438bc80b19362cf633b87a8ab20"}, - {file = "pydantic_core-2.20.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:4745f4ac52cc6686390c40eaa01d48b18997cb130833154801a442323cc78f91"}, - {file = "pydantic_core-2.20.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a8ad4c766d3f33ba8fd692f9aa297c9058970530a32c728a2c4bfd2616d3358b"}, - {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41e81317dd6a0127cabce83c0c9c3fbecceae981c8391e6f1dec88a77c8a569a"}, - {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:04024d270cf63f586ad41fff13fde4311c4fc13ea74676962c876d9577bcc78f"}, - {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eaad4ff2de1c3823fddf82f41121bdf453d922e9a238642b1dedb33c4e4f98ad"}, - {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:26ab812fa0c845df815e506be30337e2df27e88399b985d0bb4e3ecfe72df31c"}, - {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c5ebac750d9d5f2706654c638c041635c385596caf68f81342011ddfa1e5598"}, - {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2aafc5a503855ea5885559eae883978c9b6d8c8993d67766ee73d82e841300dd"}, - {file = "pydantic_core-2.20.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:4868f6bd7c9d98904b748a2653031fc9c2f85b6237009d475b1008bfaeb0a5aa"}, - {file = "pydantic_core-2.20.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:aa2f457b4af386254372dfa78a2eda2563680d982422641a85f271c859df1987"}, - {file = "pydantic_core-2.20.1-cp38-none-win32.whl", hash = "sha256:225b67a1f6d602de0ce7f6c1c3ae89a4aa25d3de9be857999e9124f15dab486a"}, - {file = "pydantic_core-2.20.1-cp38-none-win_amd64.whl", hash = "sha256:6b507132dcfc0dea440cce23ee2182c0ce7aba7054576efc65634f080dbe9434"}, - {file = "pydantic_core-2.20.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:b03f7941783b4c4a26051846dea594628b38f6940a2fdc0df00b221aed39314c"}, - {file = "pydantic_core-2.20.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1eedfeb6089ed3fad42e81a67755846ad4dcc14d73698c120a82e4ccf0f1f9f6"}, - {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:635fee4e041ab9c479e31edda27fcf966ea9614fff1317e280d99eb3e5ab6fe2"}, - {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:77bf3ac639c1ff567ae3b47f8d4cc3dc20f9966a2a6dd2311dcc055d3d04fb8a"}, - {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ed1b0132f24beeec5a78b67d9388656d03e6a7c837394f99257e2d55b461611"}, - {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c6514f963b023aeee506678a1cf821fe31159b925c4b76fe2afa94cc70b3222b"}, - {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10d4204d8ca33146e761c79f83cc861df20e7ae9f6487ca290a97702daf56006"}, - {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2d036c7187b9422ae5b262badb87a20a49eb6c5238b2004e96d4da1231badef1"}, - {file = "pydantic_core-2.20.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9ebfef07dbe1d93efb94b4700f2d278494e9162565a54f124c404a5656d7ff09"}, - {file = "pydantic_core-2.20.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6b9d9bb600328a1ce523ab4f454859e9d439150abb0906c5a1983c146580ebab"}, - {file = "pydantic_core-2.20.1-cp39-none-win32.whl", hash = "sha256:784c1214cb6dd1e3b15dd8b91b9a53852aed16671cc3fbe4786f4f1db07089e2"}, - {file = "pydantic_core-2.20.1-cp39-none-win_amd64.whl", hash = "sha256:d2fe69c5434391727efa54b47a1e7986bb0186e72a41b203df8f5b0a19a4f669"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a45f84b09ac9c3d35dfcf6a27fd0634d30d183205230a0ebe8373a0e8cfa0906"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d02a72df14dfdbaf228424573a07af10637bd490f0901cee872c4f434a735b94"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2b27e6af28f07e2f195552b37d7d66b150adbaa39a6d327766ffd695799780f"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:084659fac3c83fd674596612aeff6041a18402f1e1bc19ca39e417d554468482"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:242b8feb3c493ab78be289c034a1f659e8826e2233786e36f2893a950a719bb6"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:38cf1c40a921d05c5edc61a785c0ddb4bed67827069f535d794ce6bcded919fc"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e0bbdd76ce9aa5d4209d65f2b27fc6e5ef1312ae6c5333c26db3f5ade53a1e99"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:254ec27fdb5b1ee60684f91683be95e5133c994cc54e86a0b0963afa25c8f8a6"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:407653af5617f0757261ae249d3fba09504d7a71ab36ac057c938572d1bc9331"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:c693e916709c2465b02ca0ad7b387c4f8423d1db7b4649c551f27a529181c5ad"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b5ff4911aea936a47d9376fd3ab17e970cc543d1b68921886e7f64bd28308d1"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:177f55a886d74f1808763976ac4efd29b7ed15c69f4d838bbd74d9d09cf6fa86"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:964faa8a861d2664f0c7ab0c181af0bea66098b1919439815ca8803ef136fc4e"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:4dd484681c15e6b9a977c785a345d3e378d72678fd5f1f3c0509608da24f2ac0"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f6d6cff3538391e8486a431569b77921adfcdef14eb18fbf19b7c0a5294d4e6a"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a6d511cc297ff0883bc3708b465ff82d7560193169a8b93260f74ecb0a5e08a7"}, - {file = "pydantic_core-2.20.1.tar.gz", hash = "sha256:26ca695eeee5f9f1aeeb211ffc12f10bcb6f71e2989988fda61dabd65db878d4"}, + {file = "pydantic_core-2.23.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:b10bd51f823d891193d4717448fab065733958bdb6a6b351967bd349d48d5c9b"}, + {file = "pydantic_core-2.23.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4fc714bdbfb534f94034efaa6eadd74e5b93c8fa6315565a222f7b6f42ca1166"}, + {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63e46b3169866bd62849936de036f901a9356e36376079b05efa83caeaa02ceb"}, + {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed1a53de42fbe34853ba90513cea21673481cd81ed1be739f7f2efb931b24916"}, + {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cfdd16ab5e59fc31b5e906d1a3f666571abc367598e3e02c83403acabc092e07"}, + {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255a8ef062cbf6674450e668482456abac99a5583bbafb73f9ad469540a3a232"}, + {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a7cd62e831afe623fbb7aabbb4fe583212115b3ef38a9f6b71869ba644624a2"}, + {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f09e2ff1f17c2b51f2bc76d1cc33da96298f0a036a137f5440ab3ec5360b624f"}, + {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e38e63e6f3d1cec5a27e0afe90a085af8b6806ee208b33030e65b6516353f1a3"}, + {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0dbd8dbed2085ed23b5c04afa29d8fd2771674223135dc9bc937f3c09284d071"}, + {file = "pydantic_core-2.23.4-cp310-none-win32.whl", hash = "sha256:6531b7ca5f951d663c339002e91aaebda765ec7d61b7d1e3991051906ddde119"}, + {file = "pydantic_core-2.23.4-cp310-none-win_amd64.whl", hash = "sha256:7c9129eb40958b3d4500fa2467e6a83356b3b61bfff1b414c7361d9220f9ae8f"}, + {file = "pydantic_core-2.23.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:77733e3892bb0a7fa797826361ce8a9184d25c8dffaec60b7ffe928153680ba8"}, + {file = "pydantic_core-2.23.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b84d168f6c48fabd1f2027a3d1bdfe62f92cade1fb273a5d68e621da0e44e6d"}, + {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df49e7a0861a8c36d089c1ed57d308623d60416dab2647a4a17fe050ba85de0e"}, + {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ff02b6d461a6de369f07ec15e465a88895f3223eb75073ffea56b84d9331f607"}, + {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:996a38a83508c54c78a5f41456b0103c30508fed9abcad0a59b876d7398f25fd"}, + {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d97683ddee4723ae8c95d1eddac7c192e8c552da0c73a925a89fa8649bf13eea"}, + {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:216f9b2d7713eb98cb83c80b9c794de1f6b7e3145eef40400c62e86cee5f4e1e"}, + {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6f783e0ec4803c787bcea93e13e9932edab72068f68ecffdf86a99fd5918878b"}, + {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d0776dea117cf5272382634bd2a5c1b6eb16767c223c6a5317cd3e2a757c61a0"}, + {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d5f7a395a8cf1621939692dba2a6b6a830efa6b3cee787d82c7de1ad2930de64"}, + {file = "pydantic_core-2.23.4-cp311-none-win32.whl", hash = "sha256:74b9127ffea03643e998e0c5ad9bd3811d3dac8c676e47db17b0ee7c3c3bf35f"}, + {file = "pydantic_core-2.23.4-cp311-none-win_amd64.whl", hash = "sha256:98d134c954828488b153d88ba1f34e14259284f256180ce659e8d83e9c05eaa3"}, + {file = "pydantic_core-2.23.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231"}, + {file = "pydantic_core-2.23.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee"}, + {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87"}, + {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8"}, + {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327"}, + {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2"}, + {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36"}, + {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126"}, + {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e"}, + {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24"}, + {file = "pydantic_core-2.23.4-cp312-none-win32.whl", hash = "sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84"}, + {file = "pydantic_core-2.23.4-cp312-none-win_amd64.whl", hash = "sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9"}, + {file = "pydantic_core-2.23.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7530e201d10d7d14abce4fb54cfe5b94a0aefc87da539d0346a484ead376c3cc"}, + {file = "pydantic_core-2.23.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:df933278128ea1cd77772673c73954e53a1c95a4fdf41eef97c2b779271bd0bd"}, + {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cb3da3fd1b6a5d0279a01877713dbda118a2a4fc6f0d821a57da2e464793f05"}, + {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c6dcb030aefb668a2b7009c85b27f90e51e6a3b4d5c9bc4c57631292015b0d"}, + {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:696dd8d674d6ce621ab9d45b205df149399e4bb9aa34102c970b721554828510"}, + {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2971bb5ffe72cc0f555c13e19b23c85b654dd2a8f7ab493c262071377bfce9f6"}, + {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8394d940e5d400d04cad4f75c0598665cbb81aecefaca82ca85bd28264af7f9b"}, + {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0dff76e0602ca7d4cdaacc1ac4c005e0ce0dcfe095d5b5259163a80d3a10d327"}, + {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7d32706badfe136888bdea71c0def994644e09fff0bfe47441deaed8e96fdbc6"}, + {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ed541d70698978a20eb63d8c5d72f2cc6d7079d9d90f6b50bad07826f1320f5f"}, + {file = "pydantic_core-2.23.4-cp313-none-win32.whl", hash = "sha256:3d5639516376dce1940ea36edf408c554475369f5da2abd45d44621cb616f769"}, + {file = "pydantic_core-2.23.4-cp313-none-win_amd64.whl", hash = "sha256:5a1504ad17ba4210df3a045132a7baeeba5a200e930f57512ee02909fc5c4cb5"}, + {file = "pydantic_core-2.23.4-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d4488a93b071c04dc20f5cecc3631fc78b9789dd72483ba15d423b5b3689b555"}, + {file = "pydantic_core-2.23.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:81965a16b675b35e1d09dd14df53f190f9129c0202356ed44ab2728b1c905658"}, + {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ffa2ebd4c8530079140dd2d7f794a9d9a73cbb8e9d59ffe24c63436efa8f271"}, + {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:61817945f2fe7d166e75fbfb28004034b48e44878177fc54d81688e7b85a3665"}, + {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:29d2c342c4bc01b88402d60189f3df065fb0dda3654744d5a165a5288a657368"}, + {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5e11661ce0fd30a6790e8bcdf263b9ec5988e95e63cf901972107efc49218b13"}, + {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d18368b137c6295db49ce7218b1a9ba15c5bc254c96d7c9f9e924a9bc7825ad"}, + {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ec4e55f79b1c4ffb2eecd8a0cfba9955a2588497d96851f4c8f99aa4a1d39b12"}, + {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:374a5e5049eda9e0a44c696c7ade3ff355f06b1fe0bb945ea3cac2bc336478a2"}, + {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5c364564d17da23db1106787675fc7af45f2f7b58b4173bfdd105564e132e6fb"}, + {file = "pydantic_core-2.23.4-cp38-none-win32.whl", hash = "sha256:d7a80d21d613eec45e3d41eb22f8f94ddc758a6c4720842dc74c0581f54993d6"}, + {file = "pydantic_core-2.23.4-cp38-none-win_amd64.whl", hash = "sha256:5f5ff8d839f4566a474a969508fe1c5e59c31c80d9e140566f9a37bba7b8d556"}, + {file = "pydantic_core-2.23.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a4fa4fc04dff799089689f4fd502ce7d59de529fc2f40a2c8836886c03e0175a"}, + {file = "pydantic_core-2.23.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0a7df63886be5e270da67e0966cf4afbae86069501d35c8c1b3b6c168f42cb36"}, + {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcedcd19a557e182628afa1d553c3895a9f825b936415d0dbd3cd0bbcfd29b4b"}, + {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f54b118ce5de9ac21c363d9b3caa6c800341e8c47a508787e5868c6b79c9323"}, + {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86d2f57d3e1379a9525c5ab067b27dbb8a0642fb5d454e17a9ac434f9ce523e3"}, + {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de6d1d1b9e5101508cb37ab0d972357cac5235f5c6533d1071964c47139257df"}, + {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1278e0d324f6908e872730c9102b0112477a7f7cf88b308e4fc36ce1bdb6d58c"}, + {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9a6b5099eeec78827553827f4c6b8615978bb4b6a88e5d9b93eddf8bb6790f55"}, + {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e55541f756f9b3ee346b840103f32779c695a19826a4c442b7954550a0972040"}, + {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a5c7ba8ffb6d6f8f2ab08743be203654bb1aaa8c9dcb09f82ddd34eadb695605"}, + {file = "pydantic_core-2.23.4-cp39-none-win32.whl", hash = "sha256:37b0fe330e4a58d3c58b24d91d1eb102aeec675a3db4c292ec3928ecd892a9a6"}, + {file = "pydantic_core-2.23.4-cp39-none-win_amd64.whl", hash = "sha256:1498bec4c05c9c787bde9125cfdcc63a41004ff167f495063191b863399b1a29"}, + {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f455ee30a9d61d3e1a15abd5068827773d6e4dc513e795f380cdd59932c782d5"}, + {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1e90d2e3bd2c3863d48525d297cd143fe541be8bbf6f579504b9712cb6b643ec"}, + {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e203fdf807ac7e12ab59ca2bfcabb38c7cf0b33c41efeb00f8e5da1d86af480"}, + {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e08277a400de01bc72436a0ccd02bdf596631411f592ad985dcee21445bd0068"}, + {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f220b0eea5965dec25480b6333c788fb72ce5f9129e8759ef876a1d805d00801"}, + {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d06b0c8da4f16d1d1e352134427cb194a0a6e19ad5db9161bf32b2113409e728"}, + {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ba1a0996f6c2773bd83e63f18914c1de3c9dd26d55f4ac302a7efe93fb8e7433"}, + {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:9a5bce9d23aac8f0cf0836ecfc033896aa8443b501c58d0602dbfd5bd5b37753"}, + {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:78ddaaa81421a29574a682b3179d4cf9e6d405a09b99d93ddcf7e5239c742e21"}, + {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:883a91b5dd7d26492ff2f04f40fbb652de40fcc0afe07e8129e8ae779c2110eb"}, + {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88ad334a15b32a791ea935af224b9de1bf99bcd62fabf745d5f3442199d86d59"}, + {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:233710f069d251feb12a56da21e14cca67994eab08362207785cf8c598e74577"}, + {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:19442362866a753485ba5e4be408964644dd6a09123d9416c54cd49171f50744"}, + {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:624e278a7d29b6445e4e813af92af37820fafb6dcc55c012c834f9e26f9aaaef"}, + {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f5ef8f42bec47f21d07668a043f077d507e5bf4e668d5c6dfe6aaba89de1a5b8"}, + {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:aea443fffa9fbe3af1a9ba721a87f926fe548d32cab71d188a6ede77d0ff244e"}, + {file = "pydantic_core-2.23.4.tar.gz", hash = "sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863"}, ] [package.dependencies] @@ -296,13 +297,13 @@ typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" [[package]] name = "pynetbox" -version = "7.4.0" +version = "7.4.1" description = "NetBox API client library" optional = false python-versions = "*" files = [ - {file = "pynetbox-7.4.0-py3-none-any.whl", hash = "sha256:974d93da77ad404e813bc7b3948d9664e0653262f0fb1e97715217aee062a648"}, - {file = "pynetbox-7.4.0.tar.gz", hash = "sha256:fd0b1f197b3880048408ff5ed84422dd599bcd9389e32cb06a09b9b0d55c1636"}, + {file = "pynetbox-7.4.1-py3-none-any.whl", hash = "sha256:f42ce4df6ce97765df91bb4cc0c0e315683d15135265270d78f595114dd20e2b"}, + {file = "pynetbox-7.4.1.tar.gz", hash = "sha256:3f82b5964ca77a608aef6cc2fc48a3961f7667fbbdbb60646655373e3dae00c3"}, ] [package.dependencies] @@ -361,4 +362,4 @@ zstd = ["zstandard (>=0.18.0)"] [metadata] lock-version = "2.0" python-versions = "^3.12" -content-hash = "b41c31c5b2b41d72ccd61a0809d09f4a2691f1e36f9035b544a101b14120902c" +content-hash = "4a07feb2e94cac5ebfa63a833c2d17eeab50ff77a1e1225eddb5ec9987ab6512" diff --git a/pyproject.toml b/pyproject.toml index d58957c..29b973b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,25 +6,12 @@ authors = ["Jeffrey C. Ollie "] [tool.poetry.dependencies] python = "^3.12" -pynetbox = "^7.4.0" +pynetbox = "^7.4.1" click = "^8.1.7" -pydantic = "2.8.2" -# pyansi = { git = "https://git.ocjtech.us/jeff/pyansi" } -#pyansi = { path = "/home/jeff/dev/pyansi", develop = true } +pydantic = "2.9.2" [tool.poetry.scripts] hostapps-update = "hostapps.update:main" -hostapps-run = "hostapps.run:main" - -[tool.black] -max-line-length = 120 - -[tool.isort] -profile = "black" -line_length = 120 -force_single_line = true -from_first = false -force_sort_within_sections = true [build-system] requires = ["poetry-core>=1.0.0"] diff --git a/src/config.zig b/src/config.zig index e35dd5c..2226cf7 100644 --- a/src/config.zig +++ b/src/config.zig @@ -5,46 +5,52 @@ pub const ConnectionType = enum { telnet, }; -pub const Config = struct { - name: []const u8, - type: ConnectionType, - comment: []const u8, - address: []const u8, - port: u16, - username: []const u8, - manufacturer: []const u8, - model: []const u8, - part_number: []const u8, - class: []const u8, +name: []const u8, +type: ConnectionType, +comment: []const u8, +address: []const u8, +port: u16, +username: []const u8, +manufacturer: []const u8, +model: []const u8, +part_number: []const u8, +class: []const u8, - const Self = @This(); +const Self = @This(); - pub fn read(alloc: std.mem.Allocator, path: []const u8) !Self { - const data = try std.fs.cwd().readFileAlloc(alloc, path, 2048); - const parsed = try std.json.parseFromSlice(Self, alloc, data, .{}); - defer parsed.deinit(); - return try parsed.value.clone(alloc); - } +pub fn read(alloc: std.mem.Allocator, path: []const u8) !*Self { + const data = try std.fs.cwd().readFileAlloc(alloc, path, 2048); + const parsed = try std.json.parseFromSlice(Self, alloc, data, .{}); + defer parsed.deinit(); + return try parsed.value.clone(alloc); +} - pub fn clone(self: Self, alloc: std.mem.Allocator) !Self { - return .{ - .name = try alloc.dupe(u8, self.name), - .type = self.type, - .comment = try alloc.dupe(u8, self.comment), - .address = try alloc.dupe(u8, self.address), - // .addresses = addr: { - // var addrs = try alloc.alloc([]const u8, self.addresses.len); - // for (self.addresses, 0..) |a, i| { - // addrs[i] = try alloc.dupe(u8, a); - // } - // break :addr addrs; - // }, - .port = self.port, - .username = try alloc.dupe(u8, self.username), - .manufacturer = try alloc.dupe(u8, self.manufacturer), - .model = try alloc.dupe(u8, self.model), - .part_number = try alloc.dupe(u8, self.part_number), - .class = try alloc.dupe(u8, self.class), - }; - } -}; +pub fn clone(self: Self, alloc: std.mem.Allocator) !*Self { + const other = try alloc.create(Self); + errdefer alloc.destroy(other); + other.* = .{ + .name = try alloc.dupe(u8, self.name), + .type = self.type, + .comment = try alloc.dupe(u8, self.comment), + .address = try alloc.dupe(u8, self.address), + .port = self.port, + .username = try alloc.dupe(u8, self.username), + .manufacturer = try alloc.dupe(u8, self.manufacturer), + .model = try alloc.dupe(u8, self.model), + .part_number = try alloc.dupe(u8, self.part_number), + .class = try alloc.dupe(u8, self.class), + }; + return other; +} + +pub fn deinit(self: *Self, alloc: std.mem.Allocator) void { + alloc.free(self.name); + alloc.free(self.comment); + alloc.free(self.address); + alloc.free(self.username); + alloc.free(self.manufacturer); + alloc.free(self.model); + alloc.free(self.part_number); + alloc.free(self.class); + alloc.destroy(self); +} diff --git a/src/connect.zig b/src/connect.zig index a7a15a7..2de70ca 100644 --- a/src/connect.zig +++ b/src/connect.zig @@ -1,8 +1,7 @@ const std = @import("std"); const builtin = @import("builtin"); -const Config = @import("config.zig").Config; -const options = @import("options.zig"); -const ansi = @import("anzi").ANSI(.{}); +const Config = @import("config.zig"); +const Options = @import("options.zig"); const kex_algorithms = [_][]const u8{ "diffie-hellman-group14-sha1", @@ -34,119 +33,97 @@ const macs = [_][]const u8{ const ssh_options = [_]struct { key: []const u8, value: []const u8 }{ .{ .key = "ControlMaster", .value = "no" }, .{ .key = "ControlPath", .value = "none" }, + .{ .key = "ForwardAgent", .value = "no" }, .{ .key = "ForwardX11", .value = "no" }, .{ .key = "ForwardX11Trusted", .value = "no" }, .{ .key = "HostKeyAlgorithms", .value = "+ssh-rsa" }, .{ .key = "PubkeyAcceptedKeyTypes", .value = "+ssh-rsa" }, }; -pub fn connect() !void { - var arena = std.heap.ArenaAllocator.init(options.options.alloc); - const alloc = arena.allocator(); - defer arena.deinit(); - - std.log.info("config: {}", .{options.options}); - - const config = try Config.read(options.options.alloc, options.options.config); - +pub fn connect(arena_alloc: std.mem.Allocator, options: *const Options, config: *const Config) !void { var path: []const u8 = undefined; - var args = std.ArrayList([]const u8).init(alloc); - - // std.log.info("name: {s}", .{config.name}); - // std.log.info("class {s}", .{config.class}); - // std.log.info("type: {}", .{config.type}); - // std.log.info("comment: {s}", .{config.comment}); - // std.log.info("address: {s}", .{config.address}); - // std.log.info("port: {d}", .{config.port}); - // std.log.info("username: {s}", .{config.username}); - // std.log.info("manufacturer: {s}", .{config.manufacturer}); - // std.log.info("model: {s}", .{config.model}); - // std.log.info("part number: {s}", .{config.part_number}); + var args = std.ArrayList([]const u8).init(arena_alloc); switch (config.type) { .ssh => { - path = options.options.ssh_path; + path = options.ssh_command; try args.append("ssh"); try args.append("-y"); - for (options.options.identities) |identity| { - try args.append("-i"); - try args.append(identity); + if (options.agent) |agent| { + try args.append("-o"); + try args.append(try std.fmt.allocPrint(arena_alloc, "IdentityAgent={s}", .{agent})); } - if (options.options.proxy_jump) |p| { + if (options.identities) |identities| { + for (identities) |identity| { + try args.append("-o"); + try args.append(try std.fmt.allocPrint(arena_alloc, "IdentityFile={s}", .{identity})); + } + } + + if (options.proxy_jump) |proxy_jump| { try args.append("-o"); - try args.append(try std.fmt.allocPrint(alloc, "ProxyJump={s}", .{p})); + try args.append(try std.fmt.allocPrint(arena_alloc, "ProxyJump={s}", .{proxy_jump})); } for (ssh_options) |option| { try args.append("-o"); - try args.append(try std.fmt.allocPrint(alloc, "{s}={s}", .{ option.key, option.value })); + try args.append(try std.fmt.allocPrint(arena_alloc, "{s}={s}", .{ option.key, option.value })); } try args.append("-o"); - try args.append(try std.fmt.allocPrint(alloc, "Ciphers={s}", .{try std.mem.join(alloc, ",", &ciphers)})); + try args.append(try std.fmt.allocPrint(arena_alloc, "Ciphers={s}", .{try std.mem.join(arena_alloc, ",", &ciphers)})); try args.append("-o"); - try args.append(try std.fmt.allocPrint(alloc, "KexAlgorithms={s}", .{try std.mem.join(alloc, ",", &kex_algorithms)})); + try args.append(try std.fmt.allocPrint(arena_alloc, "KexAlgorithms={s}", .{try std.mem.join(arena_alloc, ",", &kex_algorithms)})); try args.append("-o"); - try args.append(try std.fmt.allocPrint(alloc, "MACs={s}", .{try std.mem.join(alloc, ",", &macs)})); + try args.append(try std.fmt.allocPrint(arena_alloc, "MACs={s}", .{try std.mem.join(arena_alloc, ",", &macs)})); - try args.append("-l"); - try args.append(config.username); + try args.append("-o"); + try args.append(try std.fmt.allocPrint(arena_alloc, "User={s}", .{config.username})); if (config.port != 22) { - try args.append("-p"); - try args.append(try std.fmt.allocPrint(alloc, "{d}", .{config.port})); + try args.append("-o"); + try args.append(try std.fmt.allocPrint(arena_alloc, "Port={d}", .{config.port})); } try args.append(config.address); }, .telnet => { - if (options.options.proxy_jump) |p| { - path = options.options.ssh_path; + if (options.proxy_jump) |p| { + path = options.ssh_command; try args.append("ssh"); try args.append("-t"); - try args.append(try std.fmt.allocPrint(alloc, "ssh://{s}", .{p})); + try args.append(try std.fmt.allocPrint(arena_alloc, "ssh://{s}", .{p})); try args.append("telnet"); } else { - path = options.options.telnet_path; + path = options.telnet_command; try args.append("telnet"); } try args.append(config.address); if (config.port != 23) { - try args.append(try std.fmt.allocPrint(alloc, "{d}", .{config.port})); + try args.append(try std.fmt.allocPrint(arena_alloc, "{d}", .{config.port})); } }, } - const pathZ = try alloc.dupeZ(u8, path); - const argsZ = try alloc.allocSentinel(?[*:0]const u8, args.items.len, null); - for (args.items, 0..) |arg, i| argsZ[i] = (try alloc.dupeZ(u8, arg)).ptr; + const pathZ = try arena_alloc.dupeZ(u8, path); + const argsZ = try arena_alloc.allocSentinel(?[*:0]const u8, args.items.len, null); + for (args.items, 0..) |arg, i| argsZ[i] = (try arena_alloc.dupeZ(u8, arg)).ptr; - // for (argsZ, 0..) |arg, i| { - // if (arg) |a| std.log.info("{d} {s}", .{ i, a }); - // } - - if (builtin.output_mode == .Exe) { - const stdout_file = std.io.getStdOut().writer(); - var bw = std.io.bufferedWriter(stdout_file); - const stdout = bw.writer(); - try stdout.print( - "{}", - .{ - ansi.IconNameAndWindowTitle{ - .icon_name = config.name, - .window_title = try std.fmt.allocPrint(alloc, "{s} \u{2013} {s}", .{ config.name, config.address }), - }, - }, - ); - try bw.flush(); - const envp = @as([*:null]const ?[*:0]const u8, @ptrCast(std.os.environ.ptr)); - return std.posix.execveZ(pathZ, argsZ, envp); - } + const stdout_file = std.io.getStdOut().writer(); + var bw = std.io.bufferedWriter(stdout_file); + const stdout = bw.writer(); + try stdout.print( + "\x1b]0;{s} \u{2013} {s}\x1b\\", + .{ config.name, config.address }, + ); + try bw.flush(); + const envp = @as([*:null]const ?[*:0]const u8, @ptrCast(std.os.environ.ptr)); + return std.posix.execveZ(pathZ, argsZ, envp); } diff --git a/src/main.zig b/src/main.zig index d31cd1d..1b2f81c 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1,84 +1,83 @@ const std = @import("std"); const builtin = @import("builtin"); const build_options = @import("build_options"); -const cli = @import("zig-cli"); -const options = @import("options.zig"); -const connect = @import("connect.zig"); -const update = @import("update.zig"); +const Options = @import("options.zig"); +const Config = @import("config.zig"); +const connect = @import("connect.zig").connect; pub fn main() !void { var gpa = std.heap.GeneralPurposeAllocator(.{}){}; - const alloc = gpa.allocator(); + const gpa_alloc = gpa.allocator(); + var arena = std.heap.ArenaAllocator.init(gpa_alloc); + const arena_alloc = arena.allocator(); + defer arena.deinit(); - options.options.alloc = alloc; + var config: ?*Config = null; + var options: Options = .{}; + var identities = std.ArrayList([]const u8).init(arena_alloc); + errdefer identities.deinit(); - var r = try cli.AppRunner.init(alloc); + { + const OptionNames = enum { + config, + identity, + agent, + @"proxy-jump", + @"ssh-command", + @"telnet-command", + }; - const app = cli.App{ - .command = cli.Command{ - .name = "hostapps", - .description = cli.Description{ - .one_line = "hostapps", - }, - .target = cli.CommandTarget{ - .subcommands = &.{ - cli.Command{ - .name = "connect", - .description = cli.Description{ - .one_line = "connect", - }, - .options = &.{ - cli.Option{ - .long_name = "config", - .help = "config file", - .value_ref = r.mkRef(&options.options.config), - .required = true, - }, - cli.Option{ - .long_name = "identity", - .help = "ssh identity", - .value_ref = r.mkRef(&options.options.identities), - }, - cli.Option{ - .long_name = "proxy-jump", - .help = "proxy jump", - .value_ref = r.mkRef(&options.options.proxy_jump), - }, - cli.Option{ - .long_name = "ssh-command", - .help = "ssh command", - .value_ref = r.mkRef(&options.options.ssh_path), - }, - cli.Option{ - .long_name = "telnet-command", - .help = "telnet command", - .value_ref = r.mkRef(&options.options.telnet_path), - }, - }, - .target = cli.CommandTarget{ - .action = cli.CommandAction{ - .exec = connect.connect, - }, - }, + const args = try std.process.argsAlloc(arena_alloc); + defer std.process.argsFree(arena_alloc, args); + + var index: usize = 1; + while (index < args.len) { + if (std.mem.startsWith(u8, args[index], "--")) { + const key, const value = kv: { + if (std.mem.indexOfScalarPos(u8, args[index], 2, '=')) |end| { + break :kv .{ args[index][2..end], args[index][end + 1 .. args.len] }; + } else { + const key = args[index][2..]; + index += 1; + const value = args[index]; + break :kv .{ key, value }; + } + }; + + if (std.meta.stringToEnum(OptionNames, key)) |option| switch (option) { + .config => { + config = try Config.read(arena_alloc, value); }, - cli.Command{ - .name = "update", - .description = cli.Description{ - .one_line = "update", - }, - .options = &.{}, - .target = cli.CommandTarget{ - .action = cli.CommandAction{ - .exec = update.update, - }, - }, + .agent => { + options.agent = try arena_alloc.dupe(u8, value); }, - }, - }, - }, - .version = "0.1.0", - .author = "Jeffrey C. Ollie ", - }; + .identity => { + try identities.append(try arena_alloc.dupe(u8, value)); + }, + .@"proxy-jump" => { + options.proxy_jump = try arena_alloc.dupe(u8, value); + }, + .@"ssh-command" => { + options.ssh_command = try arena_alloc.dupe(u8, value); + }, + .@"telnet-command" => { + options.telnet_command = try arena_alloc.dupe(u8, value); + }, + } else { + std.log.err("unknown option: {s}", .{key}); + return; + } + } + index += 1; + } - return r.run(&app); + if (identities.items.len > 0) { + options.identities = identities.items; + } + } + + try connect(arena_alloc, &options, config orelse { + std.log.err("no configuration!", .{}); + return; + }); } diff --git a/src/options.zig b/src/options.zig index 78a5ae4..41b8410 100644 --- a/src/options.zig +++ b/src/options.zig @@ -2,16 +2,8 @@ const std = @import("std"); const cli = @import("zig-cli"); const build_options = @import("build_options"); -pub const Options = struct { - alloc: std.mem.Allocator = undefined, - config: []const u8 = undefined, - identities: []const []const u8 = undefined, - proxy_jump: ?[]const u8 = null, - ssh_path: []const u8, - telnet_path: []const u8, -}; - -pub var options: Options = .{ - .ssh_path = build_options.ssh_path, - .telnet_path = build_options.telnet_path, -}; +identities: ?[]const []const u8 = null, +agent: ?[]const u8 = null, +proxy_jump: ?[]const u8 = null, +ssh_command: []const u8 = build_options.ssh_command, +telnet_command: []const u8 = build_options.telnet_command, diff --git a/src/update.zig b/src/update.zig deleted file mode 100644 index 6aae0d9..0000000 --- a/src/update.zig +++ /dev/null @@ -1,248 +0,0 @@ -const std = @import("std"); -const builtin = @import("builtin"); -const Config = @import("config.zig").Config; -const ConnectionType = @import("config.zig").ConnectionType; -const options = @import("options.zig"); -const ansi = @import("anzi").ANSI(.{}); -// const netboxz = @import("netboxz"); -const HashMap = @import("hashmap"); - -const log = std.log.scoped(.update); - -pub fn update() !void { - // var arena = std.heap.ArenaAllocator.init(options.options.alloc); - // const alloc = arena.allocator(); - // defer arena.deinit(); - - // const nb = try netboxz.init(alloc, "https://", ""); - - // const mfg_cisco_id = id: { - // var one = try nb.dcim().manufacturers().one( - // &[_]netboxz.FilterOperation{ - // .{ - // .string = .{ - // .key = "name", - // .value = "Cisco", - // .comparison = .eq, - // }, - // }, - // }, - // ); - // defer one.deinit(); - // log.info("one: {any}", .{one.ok.value.name}); - // switch (one) { - // .ok => |r| { - // log.info("found manufacturer {d} {s}", .{ r.value.id, r.value.name }); - // break :id r.value.id; - // }, - // .notfound => { - // log.err("could not find Cisco", .{}); - // return; - // }, - // .toomany => |r| { - // log.err("{} is too many", .{r.count}); - // return; - // }, - // .err => |r| { - // log.err("error from netbox: {s}", .{r.detail}); - // return; - // }, - // } - // }; - - // log.info("found mfg id {}", .{mfg_cisco_id}); - - // const network_role_id = id: { - // var one = try nb.dcim().device_roles().one( - // &[_]netboxz.FilterOperation{ - // .{ - // .string = .{ - // .key = "name", - // .value = "Network", - // .comparison = .eq, - // }, - // }, - // }, - // ); - // defer one.deinit(); - // switch (one) { - // .ok => |r| { - // break :id r.value.id; - // }, - // .notfound => { - // log.err("could not find Network", .{}); - // return; - // }, - // .toomany => |r| { - // log.err("{} is too many", .{r.count}); - // return; - // }, - // .err => |r| { - // log.err("error from netbox: {s}", .{r.detail}); - // return; - // }, - // } - // }; - - // log.info("found role id {}", .{network_role_id}); - - // { - // var iter = try nb.dcim().devices().list( - // .{ - // .filters = &[_]netboxz.FilterOperation{ - // .{ - // .fk = .{ - // .key = "manufacturer_id", - // .value = mfg_cisco_id, - // }, - // }, - // .{ - // .fk = .{ - // .key = "role_id", - // .value = network_role_id, - // }, - // }, - // .{ - // .choice = .{ - // .key = "status", - // .value = "active", - // }, - // }, - // .{ - // .boolean = .{ - // .key = "has_primary_ip", - // .value = true, - // }, - // }, - // }, - // }, - // ); - - // var part_number_map = HashMap.init(alloc); - - // while (try iter.next()) |device_result| { - // defer device_result.deinit(); - - // switch (device_result) { - // .ok => |devices| { - // for (devices.items) |device| { - // const name = name: { - // if (device.virtual_chassis) |vc| break :name vc.name; - // if (device.name) |name| break :name name; - // break :name device.display; - // }; - // log.info("found device {d} '{s}' '{s}'", .{ device.id, name, device.display }); - // const part_number = pn: { - // if (part_number_map.get(device.device_type.id)) |pn| break :pn pn; - // const pn_result = try device.device_type.full(nb); - // switch (pn_result) { - // .ok => |r| { - // part_number_map.put(r.item.id, r.item.part_number); - // break :pn r.item.part_number; - // }, - // .err => |r| { - // log.err("error: {}", .{r.detail}); - // return; - // }, - // } - // }; - - // var service_iter = try nb.ipam().services().list( - // .{ - // .filters = &[_]netboxz.FilterOperation{ - // .{ - // .fk = .{ - // .key = "device_id", - // .value = device.id, - // }, - // }, - // .{ - // .string = .{ - // .key = "name", - // .value = "ssh", - // .comparison = .ie, - // }, - // }, - // .{ - // .string = .{ - // .key = "name", - // .value = "telnet", - // .comparison = .ie, - // }, - // }, - // }, - // }, - // ); - // defer service_iter.deinit(); - - // while (try service_iter.next()) |service_result| { - // defer service_result.deinit(); - - // switch (service_result) { - // .ok => |services| { - // for (services.items) |service| { - // for (service.ports) |port| { - // var addresses = std.ArrayList([]const u8); - // errdefer addresses.deinit(); - // if (device.primary_ip6) |ip| { - // log.info("found service {d} {s} {s} {s} {d}", .{ device.id, name, ip.ip(), service.name, port }); - // try addresses.append(ip.ip()); - // } - // if (device.primary_ip4) |ip| { - // log.info("found service {d} {s} {s} {s} {d}", .{ device.id, name, ip.ip(), service.name, port }); - // try addresses.append(ip.ip()); - // } - // const config: Config = .{ - // .name = name, - // .type = t: { - // var output: [32]u8 = undefined; - // std.ascii.lowerString(&output, service.name); - // break :t try std.meta.stringToEnum(ConnectionType, std.ascii.lowerString(output, service.name)); - // }, - // .comment = c: { - // const c = try alloc.dupe(u8, name); - // std.mem.replaceScalar(u8, c, '-', ' '); - // break :c c; - // }, - // .addresses = addresses.toOwnedSlice(), - // .port = port, - // .username = try alloc.dupe(u8, "jcollie"), - // .manufacturer = try alloc.dupe(u8, device.device_type.manufacturer.name), - // .model = try alloc.dupe(u8, device.device_type.model), - // .part_number = try alloc.dupe(u8, part_number), - // .class = c: { - // const c = try alloc.dupe(u8, name); - // for (c, 0..) |b, i| { - // switch (b) { - // 'a'...'z' => {}, - // 'A'...'Z' => {}, - // '0'...'9' => {}, - // '_' => {}, - // else => c[i] = '_', - // } - // } - // break :c c; - // }, - // }; - // { - // var buf = std.ArrayList(u8).init(alloc); - // try std.json.stringify(config, .{}, buf.writer()); - // } - // } - // } - // }, - // .err => |err| { - // log.err("error from netbox: {s}", .{err.detail}); - // }, - // } - // } - // } - // }, - // .err => |err| { - // log.err("error from netbox: {s}", .{err.detail}); - // return; - // }, - // } - // } - // } -}