From 2e68db33aa684fd8f0a28b89d2f6207473ea2f14 Mon Sep 17 00:00:00 2001 From: "Jeffrey C. Ollie" Date: Tue, 14 May 2024 15:23:31 -0500 Subject: [PATCH] update --- build.zig | 16 +- build.zig.zon | 20 ++- src/config.zig | 17 +- src/connect.zig | 2 +- src/main.zig | 73 +++++++- src/options.zig | 80 --------- src/path.zig | 2 +- src/update.zig | 448 ++++++++++++++++++++++++------------------------ 8 files changed, 325 insertions(+), 333 deletions(-) diff --git a/build.zig b/build.zig index 8589922..12c6cae 100644 --- a/build.zig +++ b/build.zig @@ -54,15 +54,15 @@ pub fn build(b: *std.Build) void { exe.root_module.addImport("anzi", anzi.module("anzi")); - const netboxz = b.dependency( - "netboxz", - .{ - .target = target, - .optimize = optimize, - }, - ); + // const netboxz = b.dependency( + // "netboxz", + // .{ + // .target = target, + // .optimize = optimize, + // }, + // ); - exe.root_module.addImport("netboxz", netboxz.module("netboxz")); + // exe.root_module.addImport("netboxz", netboxz.module("netboxz")); const logz = b.dependency( "logz", diff --git a/build.zig.zon b/build.zig.zon index 640f16e..b8258cb 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -4,21 +4,23 @@ .minimum_zig_version = "0.12.0", .dependencies = .{ .logz = .{ - .url = "https://github.com/karlseguin/log.zig/archive/eb86766b91cf2ca0a6e87dd8568fab80695cf2e8.tar.gz", - .hash = "1220b6cf56de826aead943a6db2a62ed40d81a150c24dcb019b3eb88673c82a6e7b7", + .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", - }, + // .netboxz = .{ + // // .url = "https://github.com/jcollie/netboxz/archive/354caea69a1e033cf34da6c5e514dc4eb755af06.tar.gz", + // // .hash = "1220374f4587ec4d1e820a45039cd4bedd7cd560a3a668fdae2db0b5a6609f97c793", + // .path = "../netboxz", + // }, .@"zig-cli" = .{ - .url = "https://github.com/sam701/zig-cli/archive/50201f0086da689cd104c2fef350f3dbe894eea7.tar.gz", - .hash = "12208a4377c7699927605e5a797bad5ae2ba8be4b49f68b9f522b3a755597a21f1cf", + .url = "https://github.com/sam701/zig-cli/archive/9a94c4803a52e54c26b198096d63fb5bde752da2.tar.gz", + // .hash = "12208a4377c7699927605e5a797bad5ae2ba8be4b49f68b9f522b3a755597a21f1cf", + .hash = "1220ab73fb7cc11b2308edc3364988e05efcddbcac31b707f55e6216d1b9c0da13f1", }, }, .paths = .{ diff --git a/src/config.zig b/src/config.zig index a37e881..e35dd5c 100644 --- a/src/config.zig +++ b/src/config.zig @@ -9,7 +9,7 @@ pub const Config = struct { name: []const u8, type: ConnectionType, comment: []const u8, - addresses: [][]const u8, + address: []const u8, port: u16, username: []const u8, manufacturer: []const u8, @@ -31,13 +31,14 @@ pub const Config = struct { .name = try alloc.dupe(u8, self.name), .type = self.type, .comment = try alloc.dupe(u8, self.comment), - .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; - }, + .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), diff --git a/src/connect.zig b/src/connect.zig index 9ecb709..a7a15a7 100644 --- a/src/connect.zig +++ b/src/connect.zig @@ -147,6 +147,6 @@ pub fn connect() !void { ); try bw.flush(); const envp = @as([*:null]const ?[*:0]const u8, @ptrCast(std.os.environ.ptr)); - return std.os.execveZ(pathZ, argsZ, envp); + return std.posix.execveZ(pathZ, argsZ, envp); } } diff --git a/src/main.zig b/src/main.zig index ca7e86b..d31cd1d 100644 --- a/src/main.zig +++ b/src/main.zig @@ -2,8 +2,9 @@ const std = @import("std"); const builtin = @import("builtin"); const build_options = @import("build_options"); const cli = @import("zig-cli"); -const connect = @import("connect.zig"); const options = @import("options.zig"); +const connect = @import("connect.zig"); +const update = @import("update.zig"); pub fn main() !void { var gpa = std.heap.GeneralPurposeAllocator(.{}){}; @@ -11,5 +12,73 @@ pub fn main() !void { options.options.alloc = alloc; - return cli.run(options.app, alloc); + var r = try cli.AppRunner.init(alloc); + + 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, + }, + }, + }, + cli.Command{ + .name = "update", + .description = cli.Description{ + .one_line = "update", + }, + .options = &.{}, + .target = cli.CommandTarget{ + .action = cli.CommandAction{ + .exec = update.update, + }, + }, + }, + }, + }, + }, + .version = "0.1.0", + .author = "Jeffrey C. Ollie ", + }; + + return r.run(&app); } diff --git a/src/options.zig b/src/options.zig index d8cf637..f54cb7f 100644 --- a/src/options.zig +++ b/src/options.zig @@ -17,83 +17,3 @@ pub var options: Options = .{ .ssh_path = build_options.ssh_path, .telnet_path = build_options.telnet_path, }; - -var config_option = cli.Option{ - .long_name = "config", - .help = "config file", - .value_ref = cli.mkRef(&options.config), - .required = true, -}; - -var identity_option = cli.Option{ - .long_name = "identity", - .help = "ssh identity", - .value_ref = cli.mkRef(&options.identities), -}; - -var proxy_jump_option = cli.Option{ - .long_name = "proxy-jump", - .help = "proxy jump", - .value_ref = cli.mkRef(&options.proxy_jump), -}; - -var ssh_command_option = cli.Option{ - .long_name = "ssh-command", - .help = "ssh command", - .value_ref = cli.mkRef(&options.ssh_path), -}; - -var telnet_command_option = cli.Option{ - .long_name = "telnet-command", - .help = "telnet command", - .value_ref = cli.mkRef(&options.telnet_path), -}; - -var connect_command = cli.Command{ - .name = "connect", - .description = cli.Description{ - .one_line = "connect", - }, - .options = &.{ - &config_option, - &identity_option, - &proxy_jump_option, - &ssh_command_option, - &telnet_command_option, - }, - .target = cli.CommandTarget{ - .action = cli.CommandAction{ - .exec = connect.connect, - }, - }, -}; - -var update_command = cli.Command{ - .name = "update", - .description = cli.Description{ - .one_line = "update", - }, - .options = &.{}, - .target = cli.CommandTarget{ - .action = cli.CommandAction{ - .exec = update.update, - }, - }, -}; - -pub const app = &cli.App{ - .command = cli.Command{ - .name = "hostapps", - .description = cli.Description{ - .one_line = "hostapps", - }, - .target = cli.CommandTarget{ - .subcommands = &.{ - &connect_command, - &update_command, - }, - }, - }, - .version = "0.1.0", - .author = "Jeffrey C. Ollie ", -}; diff --git a/src/path.zig b/src/path.zig index 40eda38..7a390ac 100644 --- a/src/path.zig +++ b/src/path.zig @@ -8,7 +8,7 @@ pub fn expandPath(alloc: std.mem.Allocator, cmd: []const u8) !?[]u8 { const path = try std.unicode.utf16leToUtf8Alloc(alloc, win_path); break :blk path; }, - else => std.os.getenvZ("PATH") orelse return null, + else => std.posix.getenvZ("PATH") orelse return null, }; defer if (builtin.os.tag == .windows) alloc.free(PATH); diff --git a/src/update.zig b/src/update.zig index ae42e9e..6aae0d9 100644 --- a/src/update.zig +++ b/src/update.zig @@ -4,245 +4,245 @@ 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 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(); + // var arena = std.heap.ArenaAllocator.init(options.options.alloc); + // const alloc = arena.allocator(); + // defer arena.deinit(); - const nb = try netboxz.init(alloc, "https://netbox.dmacc.net", "814e66254d019e7ef37de53bacc8e88e411da855"); + // 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; - }, - } - }; + // 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}); + // 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; - }, - } - }; + // 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}); + // 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 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); + // var part_number_map = HashMap.init(alloc); - while (try iter.next()) |device_result| { - defer device_result.deinit(); + // 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; - }, - } - }; + // 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(); + // 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(); + // 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; - }, - } - } - } + // 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; + // }, + // } + // } + // } }