diff --git a/.github/buildomat/jobs/linux.sh b/.github/buildomat/jobs/linux.sh index 12e98ed..0fd5a44 100755 --- a/.github/buildomat/jobs/linux.sh +++ b/.github/buildomat/jobs/linux.sh @@ -5,18 +5,43 @@ #: target = "ubuntu-22.04" #: rust_toolchain = true #: output_rules = [ -#: "/out/*", +#: "=/out/lldp-0.1.0.deb", +#: "=/out/lldp-0.1.0.deb.sha256.txt", +#: "=/out/lldpd", +#: "=/out/lldpd.sha256.txt", +#: "=/out/lldpadm", +#: "=/out/lldpadm.sha256.txt", #: ] #: #: [[publish]] #: series = "linux" #: name = "lldp-0.1.0.deb" -#: from_output = "lldp-0.1.0.deb" +#: from_output = "/out/lldp-0.1.0.deb" #: #: [[publish]] #: series = "linux" #: name = "lldp-0.1.0.deb.sha256.txt" -#: from_output = "lldp-0.1.0.deb.sha256.txt" +#: from_output = "/out/lldp-0.1.0.deb.sha256.txt" +#: +#: [[publish]] +#: series = "linux" +#: name = "lldpd" +#: from_output = "/out/lldpd" +#: +#: [[publish]] +#: series = "linux" +#: name = "lldpd.sha256.txt" +#: from_output = "/out/lldpd.sha256.txt" +#: +#: [[publish]] +#: series = "linux" +#: name = "lldpadm" +#: from_output = "/out/lldpadm" +#: +#: [[publish]] +#: series = "linux" +#: name = "lldpadm.sha256.txt" +#: from_output = "/out/lldpadm.sha256.txt" #: set -o errexit @@ -37,11 +62,17 @@ sudo apt update -y sudo apt install -y libpcap-dev libclang-dev libssl-dev pkg-config banner "Build" -cargo build --release +cargo build --release --verbose --features "dendrite" banner "Artifacts" pfexec mkdir -p /out pfexec chown "$UID" /out + +cp target/release/lldpadm /out/ +digest /out/lldpadm > /out/lldpadm.sha256.txt +cp target/release/lldpd /out/ +digest /out/lldpd > /out/lldpd.sha256.txt + cargo xtask dist --release cp lldp-0.1.0.deb /out/ -sha256sum lldp-0.1.0.deb | sed "s/ .*//" > /out/lldp-0.1.0.deb.sha256.txt +digest lldp-0.1.0.deb > /out/lldp-0.1.0.deb.sha256.txt diff --git a/Cargo.lock b/Cargo.lock index 2f85186..5d5d1af 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -100,7 +100,7 @@ checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100" [[package]] name = "api_identity" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/omicron?branch=main#362c4f76bbfad42f8de1e4b70a84acc898d1bdcf" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#5552f18cad0b50d5ce8d99a688a5fd23c2d5f030" dependencies = [ "omicron-workspace-hack", "proc-macro2", @@ -252,9 +252,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.9.3" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34efbcccd345379ca2868b2b2c9d3782e9cc58ba87bc7d79d5b53d9c9ae6f25d" +checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" [[package]] name = "blake3" @@ -477,6 +477,15 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" +[[package]] +name = "colored" +version = "3.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faf9468729b8cbcea668e36183cb69d317348c2e08e994829fb56ebfdfbaac34" +dependencies = [ + "windows-sys 0.61.2", +] + [[package]] name = "common" version = "0.1.0" @@ -675,17 +684,6 @@ dependencies = [ "syn 2.0.111", ] -[[package]] -name = "derive-where" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef941ded77d15ca19b40374869ac6000af1c9f2a4c0f3d4c70926287e6364a8f" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.111", -] - [[package]] name = "digest" version = "0.10.7" @@ -746,7 +744,7 @@ dependencies = [ "futures", "http 1.4.0", "oxnet", - "progenitor", + "progenitor 0.11.1", "regress", "reqwest", "schemars", @@ -928,6 +926,20 @@ dependencies = [ "serde", ] +[[package]] +name = "ereport-types" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#5552f18cad0b50d5ce8d99a688a5fd23c2d5f030" +dependencies = [ + "dropshot", + "omicron-uuid-kinds", + "omicron-workspace-hack", + "schemars", + "serde", + "serde_json", + "thiserror 2.0.17", +] + [[package]] name = "errno" version = "0.3.13" @@ -1112,6 +1124,75 @@ dependencies = [ "slab", ] +[[package]] +name = "gateway-client" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#5552f18cad0b50d5ce8d99a688a5fd23c2d5f030" +dependencies = [ + "base64", + "chrono", + "daft", + "ereport-types", + "gateway-messages", + "gateway-types", + "omicron-uuid-kinds", + "omicron-workspace-hack", + "progenitor 0.10.0", + "rand 0.9.2", + "reqwest", + "schemars", + "serde", + "serde_json", + "slog", + "thiserror 2.0.17", + "tokio", + "uuid", +] + +[[package]] +name = "gateway-messages" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=ea2f39ccdea124b5affcad0ca17bc5dacf65823a#ea2f39ccdea124b5affcad0ca17bc5dacf65823a" +dependencies = [ + "bitflags 2.11.0", + "hubpack", + "serde", + "serde-big-array", + "serde_repr", + "static_assertions", + "strum 0.27.2", + "strum_macros 0.27.2", + "uuid", + "zerocopy", +] + +[[package]] +name = "gateway-types" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#5552f18cad0b50d5ce8d99a688a5fd23c2d5f030" +dependencies = [ + "gateway-types-versions", + "omicron-workspace-hack", +] + +[[package]] +name = "gateway-types-versions" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#5552f18cad0b50d5ce8d99a688a5fd23c2d5f030" +dependencies = [ + "daft", + "dropshot", + "gateway-messages", + "hex", + "omicron-uuid-kinds", + "omicron-workspace-hack", + "schemars", + "serde", + "thiserror 2.0.17", + "tufaceous-artifact", + "uuid", +] + [[package]] name = "generic-array" version = "0.14.7" @@ -1155,7 +1236,7 @@ version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b903b73e45dc0c6c596f2d37eccece7c1c8bb6e4407b001096387c63d0d93724" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.11.0", "libc", "libgit2-sys", "log", @@ -1253,9 +1334,6 @@ name = "hex" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" -dependencies = [ - "serde", -] [[package]] name = "home" @@ -1558,23 +1636,11 @@ dependencies = [ "zerovec", ] -[[package]] -name = "id-map" -version = "0.1.0" -source = "git+https://github.com/oxidecomputer/omicron?branch=main#362c4f76bbfad42f8de1e4b70a84acc898d1bdcf" -dependencies = [ - "daft", - "derive-where", - "omicron-workspace-hack", - "schemars", - "serde", -] - [[package]] name = "iddqd" -version = "0.3.14" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bac5efd33e0c5eb0ac45cbd210541a214dac576896ca97ba08e16e3b1079cdd8" +checksum = "6b215e67ed1d1a4b1702acd787c487d16e4c977c5dcbcc4587bdb5ea26b6ce06" dependencies = [ "allocator-api2", "daft", @@ -1783,7 +1849,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "391290121bad3d37fbddad76d8f5d1c1c314cfc646d143d7e07a3086ddff0ce3" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.11.0", "libc", "redox_syscall", ] @@ -1866,6 +1932,7 @@ dependencies = [ "dlpi", "dpd-client", "dropshot", + "gateway-client", "http 0.2.12", "lldpd-api", "lldpd-common", @@ -1903,7 +1970,7 @@ dependencies = [ "chrono", "futures", "lldpd-common", - "progenitor", + "progenitor 0.11.1", "protocol 0.1.0", "reqwest", "schemars", @@ -2004,17 +2071,19 @@ dependencies = [ [[package]] name = "mg-admin-client" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/maghemite?rev=08f2a34d487658e87545ffbba3add632a82baf0d#08f2a34d487658e87545ffbba3add632a82baf0d" +source = "git+https://github.com/oxidecomputer/maghemite?rev=8f5527da3c53398c95c50b1af088637e7b6c5718#8f5527da3c53398c95c50b1af088637e7b6c5718" dependencies = [ - "anyhow", "chrono", - "percent-encoding", - "progenitor", + "colored", + "progenitor 0.11.1", + "rdb-types", "reqwest", "schemars", "serde", "serde_json", "slog", + "tabwriter", + "uuid", ] [[package]] @@ -2085,9 +2154,9 @@ dependencies = [ [[package]] name = "newtype-uuid" -version = "1.3.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d1216f62e63be5fb25a9ecd1e2b37b1556a9b8c02f4831770f5d01df85c226" +checksum = "5c012d14ef788ab066a347d19e3dda699916c92293b05b85ba2c76b8c82d2830" dependencies = [ "schemars", "serde", @@ -2124,7 +2193,7 @@ version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.11.0", "cfg-if", "cfg_aliases", "libc", @@ -2254,7 +2323,7 @@ dependencies = [ [[package]] name = "omicron-common" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/omicron?branch=main#362c4f76bbfad42f8de1e4b70a84acc898d1bdcf" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#5552f18cad0b50d5ce8d99a688a5fd23c2d5f030" dependencies = [ "anyhow", "api_identity", @@ -2267,9 +2336,9 @@ dependencies = [ "futures", "hex", "http 1.4.0", - "id-map", "iddqd", "ipnetwork", + "itertools", "macaddr", "mg-admin-client", "omicron-uuid-kinds", @@ -2299,7 +2368,7 @@ dependencies = [ [[package]] name = "omicron-uuid-kinds" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/omicron?branch=main#362c4f76bbfad42f8de1e4b70a84acc898d1bdcf" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#5552f18cad0b50d5ce8d99a688a5fd23c2d5f030" dependencies = [ "daft", "newtype-uuid", @@ -2375,7 +2444,7 @@ version = "0.10.73" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.11.0", "cfg-if", "foreign-types", "libc", @@ -2422,7 +2491,7 @@ checksum = "9c6901729fa79e91a0913333229e9ca5dc725089d1c363b2f4b4760709dc4a52" [[package]] name = "oximeter" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/omicron?branch=main#362c4f76bbfad42f8de1e4b70a84acc898d1bdcf" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#5552f18cad0b50d5ce8d99a688a5fd23c2d5f030" dependencies = [ "anyhow", "chrono", @@ -2441,7 +2510,7 @@ dependencies = [ [[package]] name = "oximeter-macro-impl" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/omicron?branch=main#362c4f76bbfad42f8de1e4b70a84acc898d1bdcf" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#5552f18cad0b50d5ce8d99a688a5fd23c2d5f030" dependencies = [ "omicron-workspace-hack", "proc-macro2", @@ -2452,7 +2521,7 @@ dependencies = [ [[package]] name = "oximeter-schema" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/omicron?branch=main#362c4f76bbfad42f8de1e4b70a84acc898d1bdcf" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#5552f18cad0b50d5ce8d99a688a5fd23c2d5f030" dependencies = [ "anyhow", "chrono", @@ -2473,7 +2542,7 @@ dependencies = [ [[package]] name = "oximeter-timeseries-macro" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/omicron?branch=main#362c4f76bbfad42f8de1e4b70a84acc898d1bdcf" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#5552f18cad0b50d5ce8d99a688a5fd23c2d5f030" dependencies = [ "omicron-workspace-hack", "oximeter-schema", @@ -2486,7 +2555,7 @@ dependencies = [ [[package]] name = "oximeter-types" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/omicron?branch=main#362c4f76bbfad42f8de1e4b70a84acc898d1bdcf" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#5552f18cad0b50d5ce8d99a688a5fd23c2d5f030" dependencies = [ "bytes", "chrono", @@ -2494,6 +2563,7 @@ dependencies = [ "num", "omicron-common", "omicron-workspace-hack", + "oximeter-types-versions", "parse-display", "regex", "schemars", @@ -2503,11 +2573,24 @@ dependencies = [ "uuid", ] +[[package]] +name = "oximeter-types-versions" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#5552f18cad0b50d5ce8d99a688a5fd23c2d5f030" +dependencies = [ + "chrono", + "omicron-common", + "omicron-workspace-hack", + "schemars", + "serde", + "uuid", +] + [[package]] name = "oxnet" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8200429754152e6379fbb1dd06eea90156c3b67591f6e31d08e787d010ef0168" +checksum = "5dc6fb07ecd6d2a17ff1431bc5b3ce11036c0b6dd93a3c4904db5b910817b162" dependencies = [ "ipnetwork", "schemars", @@ -2764,6 +2847,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "progenitor" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced2eadb9776a201d0585b4b072fd44d7d2104e0f3452d967b5a78966f4855cf" +dependencies = [ + "progenitor-client 0.10.0", + "progenitor-impl 0.10.0", + "progenitor-macro 0.10.0", +] + [[package]] name = "progenitor" version = "0.11.1" @@ -2771,8 +2865,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "135a23fcb9ad36a46ef4be323d006e195ad5121779c9da64ef95cf0600771b77" dependencies = [ "progenitor-client 0.11.1", - "progenitor-impl", - "progenitor-macro", + "progenitor-impl 0.11.1", + "progenitor-macro 0.11.1", ] [[package]] @@ -2805,6 +2899,28 @@ dependencies = [ "serde_urlencoded", ] +[[package]] +name = "progenitor-impl" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b17e5363daa50bf1cccfade6b0fb970d2278758fd5cfa9ab69f25028e4b1afa3" +dependencies = [ + "heck 0.5.0", + "http 1.4.0", + "indexmap", + "openapiv3", + "proc-macro2", + "quote", + "regex", + "schemars", + "serde", + "serde_json", + "syn 2.0.111", + "thiserror 2.0.17", + "typify", + "unicode-ident", +] + [[package]] name = "progenitor-impl" version = "0.11.1" @@ -2827,6 +2943,24 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "progenitor-macro" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4972aec926d1e06d6abc11ab3f063d2f7063be3dd46fd2839442c14d8e48f3ed" +dependencies = [ + "openapiv3", + "proc-macro2", + "progenitor-impl 0.10.0", + "quote", + "schemars", + "serde", + "serde_json", + "serde_tokenstream", + "serde_yaml", + "syn 2.0.111", +] + [[package]] name = "progenitor-macro" version = "0.11.1" @@ -2835,7 +2969,7 @@ checksum = "5dd79317ec8ab905738484d2744d368beee6e357fc043944d985f85a0174f1f7" dependencies = [ "openapiv3", "proc-macro2", - "progenitor-impl", + "progenitor-impl 0.11.1", "quote", "schemars", "serde", @@ -2853,7 +2987,7 @@ checksum = "6fcdab19deb5195a31cf7726a210015ff1496ba1464fd42cb4f537b8b01b471f" dependencies = [ "bit-set", "bit-vec", - "bitflags 2.9.3", + "bitflags 2.11.0", "lazy_static", "num-traits", "rand 0.9.2", @@ -2878,7 +3012,7 @@ dependencies = [ [[package]] name = "protocol" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/lldp#b12d9c04ecafbb30b2c3c2d3fc03d32a14a9f6be" +source = "git+https://github.com/oxidecomputer/lldp#4c9df170cdfdeead0896e35f20a560f2102ed907" dependencies = [ "anyhow", "schemars", @@ -3040,13 +3174,23 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "rdb-types" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/maghemite?rev=8f5527da3c53398c95c50b1af088637e7b6c5718#8f5527da3c53398c95c50b1af088637e7b6c5718" +dependencies = [ + "oxnet", + "schemars", + "serde", +] + [[package]] name = "redox_syscall" version = "0.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.11.0", ] [[package]] @@ -3220,7 +3364,7 @@ version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.11.0", "errno", "libc", "linux-raw-sys 0.4.15", @@ -3233,7 +3377,7 @@ version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.11.0", "errno", "libc", "linux-raw-sys 0.9.4", @@ -3411,7 +3555,7 @@ version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.11.0", "core-foundation", "core-foundation-sys", "libc", @@ -3454,6 +3598,15 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde-big-array" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11fc7cc2c76d73e0f27ee52abbd64eec84d46f370c88371120433196934e4b7f" +dependencies = [ + "serde", +] + [[package]] name = "serde_core" version = "1.0.228" @@ -3488,23 +3641,24 @@ dependencies = [ [[package]] name = "serde_human_bytes" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/serde_human_bytes?branch=main#0a09794501b6208120528c3b457d5f3a8cb17424" +source = "git+https://github.com/oxidecomputer/serde_human_bytes?branch=main#8f60acdfe7c6d9e2a01f59be920c1c2b19129322" dependencies = [ + "base64", "hex", - "serde", + "serde_core", ] [[package]] name = "serde_json" -version = "1.0.145" +version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" dependencies = [ "itoa", "memchr", - "ryu", "serde", "serde_core", + "zmij", ] [[package]] @@ -3518,6 +3672,17 @@ dependencies = [ "serde_core", ] +[[package]] +name = "serde_repr" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + [[package]] name = "serde_spanned" version = "0.6.9" @@ -3987,7 +4152,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.11.0", "core-foundation", "system-configuration-sys", ] @@ -4026,6 +4191,15 @@ dependencies = [ "syn 2.0.111", ] +[[package]] +name = "tabwriter" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fce91f2f0ec87dff7e6bcbbeb267439aa1188703003c6055193c821487400432" +dependencies = [ + "unicode-width 0.2.1", +] + [[package]] name = "take_mut" version = "0.2.2" @@ -4439,7 +4613,7 @@ version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.11.0", "bytes", "futures-util", "http 1.4.0", @@ -4523,7 +4697,7 @@ name = "transceiver-messages" version = "0.1.1" source = "git+https://github.com/oxidecomputer/transceiver-control?branch=main#be885b28778b5efeb85c428bec9663c8c9b6a787" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.11.0", "clap 4.5.45", "hubpack", "schemars", @@ -4540,7 +4714,7 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "tufaceous-artifact" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/tufaceous?branch=main#db072743d0cfde918dcf981a064f225b0003b98d" +source = "git+https://github.com/oxidecomputer/tufaceous?branch=main#1eacfcf0cade44f77d433f31744dbee4abb96465" dependencies = [ "daft", "hex", @@ -5271,7 +5445,7 @@ version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.11.0", ] [[package]] @@ -5328,18 +5502,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.26" +version = "0.8.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" +checksum = "db6d35d663eadb6c932438e763b262fe1a70987f9ae936e60158176d710cae4a" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.26" +version = "0.8.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" +checksum = "4122cd3169e94605190e77839c9a40d40ed048d305bfdc146e7df40ab0f3e517" dependencies = [ "proc-macro2", "quote", @@ -5405,3 +5579,9 @@ dependencies = [ "quote", "syn 2.0.111", ] + +[[package]] +name = "zmij" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" diff --git a/Cargo.toml b/Cargo.toml index 746fc31..8e82554 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,6 +26,7 @@ protocol = { path = "protocol" } # oxide dependencies from github dpd-client = { git = "https://github.com/oxidecomputer/dendrite", branch = "main" } omicron-common = { git = "https://github.com/oxidecomputer/omicron", branch = "main" } +gateway-client = { git = "https://github.com/oxidecomputer/omicron", branch = "main" } # public dependencies from crates.io anyhow = "1.0" diff --git a/lldpd-api/src/lib.rs b/lldpd-api/src/lib.rs index b13884a..6bf9ddf 100644 --- a/lldpd-api/src/lib.rs +++ b/lldpd-api/src/lib.rs @@ -33,6 +33,7 @@ api_versions!([ // | example for the next person. // v // (next_int, IDENT), + (2, SWITCH_IDENTIFIERS), (1, INITIAL), ]); @@ -385,6 +386,24 @@ pub trait LldpdApi { async fn build_info( _rqctx: RequestContext, ) -> Result, HttpError>; + + #[endpoint { + method = GET, + path = "/switch/identifiers", + versions = VERSION_SWITCH_IDENTIFIERS.., + }] + async fn switch_identifiers( + ctx: RequestContext, + ) -> Result, HttpError>; +} + +/// Identifiers for a switch. +#[derive(Clone, Debug, JsonSchema, Serialize)] +pub struct SwitchIdentifiers { + /// The slot number of the switch being managed. + /// + /// MGS uses u16 for this internally. + pub slot: Option, } #[derive(Deserialize, Serialize, JsonSchema)] diff --git a/lldpd/Cargo.toml b/lldpd/Cargo.toml index 7406498..9c9a6ab 100644 --- a/lldpd/Cargo.toml +++ b/lldpd/Cargo.toml @@ -27,6 +27,7 @@ structopt.workspace = true thiserror.workspace = true tokio.workspace = true uuid.workspace = true +gateway-client.workspace = true [target.'cfg(target_os = "illumos")'.dependencies] dlpi = { git = "https://github.com/oxidecomputer/dlpi-sys" } diff --git a/lldpd/src/api_server.rs b/lldpd/src/api_server.rs index f0c3d13..d9dd3ca 100644 --- a/lldpd/src/api_server.rs +++ b/lldpd/src/api_server.rs @@ -7,8 +7,6 @@ //! LLDP HTTP API types and endpoint functions. use std::collections::HashMap; -use std::net::IpAddr; -use std::net::Ipv4Addr; use std::net::SocketAddr; use std::sync::Arc; @@ -553,6 +551,22 @@ impl LldpdApi for LldpdApiImpl { ) -> Result, HttpError> { Ok(HttpResponseOk(build_info())) } + + async fn switch_identifiers( + rqctx: RequestContext, + ) -> Result, HttpError> { + let identifiers = match rqctx.context().switch_identifiers.lock() { + Ok(v) => v, + Err(e) => { + error!(rqctx.log, "unable to read switch identifiers"; "error" => %e); + return Err(HttpError::for_internal_error( + "unable to read switch identifiers".into(), + )); + } + }; + let slot = identifiers.slot; + Ok(HttpResponseOk(SwitchIdentifiers { slot })) + } } /// The API server manager is a task that is responsible for launching and @@ -600,6 +614,7 @@ fn launch_server( // smf_rx channel, which tells us to re-evaluate the set of api_server // addresses. pub async fn api_server_manager( + listen_addr: SocketAddr, global: Arc, mut smf_rx: tokio::sync::watch::Receiver<()>, ) { @@ -612,10 +627,7 @@ pub async fn api_server_manager( let active_addrs = active.keys().cloned().collect::>(); let mut config_addrs = global.listen_addresses.lock().unwrap().to_vec(); // We always listen on localhost - config_addrs.push(SocketAddr::new( - IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), - lldpd_common::DEFAULT_LLDPD_PORT, - )); + config_addrs.push(listen_addr); // Get the list of all the addresses we should be listening on, // and compare it to the list we currently are listening on. let (add, remove) = diff --git a/lldpd/src/dendrite.rs b/lldpd/src/dendrite.rs index f5ac064..8e9377e 100644 --- a/lldpd/src/dendrite.rs +++ b/lldpd/src/dendrite.rs @@ -191,7 +191,7 @@ pub async fn dpd_init( if opts.no_dpd { None } else { - let host = opts.host.unwrap_or_else(|| "localhost".to_string()); + let host = opts.host.unwrap_or_else(|| "[::1]".to_string()); let port = opts.port.unwrap_or(dpd_client::default_port()); info!(log, "connecting to dpd at {host}:{port}"); let client_state = ClientState { diff --git a/lldpd/src/main.rs b/lldpd/src/main.rs index 664af18..585cb7e 100644 --- a/lldpd/src/main.rs +++ b/lldpd/src/main.rs @@ -7,10 +7,12 @@ use std::collections::BTreeMap; use std::collections::BTreeSet; use std::net::IpAddr; +use std::net::Ipv6Addr; use std::net::SocketAddr; use std::sync::Arc; use std::sync::Mutex; +use lldpd_api::SwitchIdentifiers; use signal_hook::consts::signal::*; use signal_hook::iterator::Signals; use slog::debug; @@ -24,6 +26,7 @@ pub use types::LldpdResult; mod api_server; mod errors; mod interfaces; +mod mgs; mod types; #[cfg(feature = "dendrite")] @@ -56,6 +59,8 @@ pub struct Global { pub listen_addresses: Mutex>, /// List of interfaces we are managing pub interfaces: Mutex>>>, + /// Switch slot we are managing + pub switch_identifiers: Mutex, } unsafe impl Send for Global {} @@ -74,6 +79,7 @@ impl Global { switchinfo: Mutex::new(switchinfo), listen_addresses: Mutex::new(Vec::new()), interfaces: Mutex::new(BTreeMap::new()), + switch_identifiers: Mutex::new(SwitchIdentifiers { slot: None }), } } } @@ -94,7 +100,7 @@ enum Args { Run(Opt), } -#[derive(Debug, StructOpt)] +#[derive(Clone, Debug, StructOpt)] pub(crate) struct Opt { #[structopt(long, about = "log file")] log_file: Option, @@ -138,6 +144,21 @@ pub(crate) struct Opt { about = "String to use as the SystemDescription" )] system_description: Option, + + #[structopt( + long = "mgs-addr", + short = "m", + about = "SocketAddr the MGS service is listening on.", + default_value = "[::1]:12225" + )] + mgs_addr: SocketAddr, + + #[structopt( + long = "listen-addr", + short = "a", + about = "SocketAddr LLDPD should listening on. (default locahost:12230)" + )] + listen_addr: Option, } #[allow(unused_variables)] @@ -211,7 +232,7 @@ async fn run_lldpd(opts: Opt) -> LldpdResult<()> { &log, switchinfo.clone(), #[cfg(feature = "dendrite")] - dendrite::dpd_init(&log, opts).await, + dendrite::dpd_init(&log, opts.clone()).await, )); #[cfg(feature = "smf")] @@ -225,10 +246,20 @@ async fn run_lldpd(opts: Opt) -> LldpdResult<()> { _ = tokio::task::spawn(async move { dendrite::link_monitor(g).await }) } + let mgs_global = global.clone(); + _ = tokio::task::spawn(async move { + mgs::detect_switch_slot(mgs_global, opts.mgs_addr).await + }); + + let listen_addr = opts.listen_addr.unwrap_or(SocketAddr::new( + IpAddr::V6(Ipv6Addr::LOCALHOST), + lldpd_common::DEFAULT_LLDPD_PORT, + )); + let (api_tx, api_rx) = tokio::sync::watch::channel(()); let api_global = global.clone(); let api_server_manager = tokio::task::spawn(async move { - api_server::api_server_manager(api_global, api_rx).await + api_server::api_server_manager(listen_addr, api_global, api_rx).await }); signal_handler(global.clone(), api_tx).await; diff --git a/lldpd/src/mgs.rs b/lldpd/src/mgs.rs new file mode 100644 index 0000000..5c74d47 --- /dev/null +++ b/lldpd/src/mgs.rs @@ -0,0 +1,39 @@ +use std::net::SocketAddr; + +pub async fn detect_switch_slot( + global: std::sync::Arc, + mgs_socket_addr: SocketAddr, +) { + let url = format!("http://{mgs_socket_addr}"); + let client_log = global.log.new(slog::o!("unit" => "gateway-client")); + let client = gateway_client::Client::new(&url, client_log); + let g = global.clone(); + + loop { + // check in with gateway + let gateway_client::types::SpIdentifier { slot, .. } = match client + .sp_local_switch_id() + .await + { + Ok(v) => *v, + Err(e) => { + slog::error!(g.log, "failed to resolve switch slot"; "error" => %e); + tokio::time::sleep(tokio::time::Duration::from_secs(10)).await; + continue; + } + }; + + slog::info!(g.log, "we are in switch slot {slot}"); + + if let Ok(mut ids) = g.switch_identifiers.lock() { + ids.slot = Some(slot); + } else { + slog::error!( + g.log, + "failed to obtain lock for updating switch slot" + ); + continue; + } + break; + } +} diff --git a/openapi/lldpd/lldpd-2.0.0-c1be66.json b/openapi/lldpd/lldpd-2.0.0-c1be66.json new file mode 100644 index 0000000..b615685 --- /dev/null +++ b/openapi/lldpd/lldpd-2.0.0-c1be66.json @@ -0,0 +1,1707 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "Oxide LLDP Daemon", + "description": "API for managing the LLDP daemon", + "contact": { + "url": "https://oxide.computer", + "email": "api@oxide.computer" + }, + "version": "2.0.0" + }, + "paths": { + "/build-info": { + "get": { + "summary": "Return detailed build information about the `dpd` server itself.", + "operationId": "build_info", + "responses": { + "200": { + "description": "successful operation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BuildInfo" + } + } + } + }, + "4XX": { + "$ref": "#/components/responses/Error" + }, + "5XX": { + "$ref": "#/components/responses/Error" + } + } + } + }, + "/interface": { + "get": { + "operationId": "interface_list", + "responses": { + "200": { + "description": "successful operation", + "content": { + "application/json": { + "schema": { + "title": "Array_of_Interface", + "type": "array", + "items": { + "$ref": "#/components/schemas/Interface" + } + } + } + } + }, + "4XX": { + "$ref": "#/components/responses/Error" + }, + "5XX": { + "$ref": "#/components/responses/Error" + } + } + } + }, + "/interface/{iface}": { + "get": { + "operationId": "interface_get", + "parameters": [ + { + "in": "path", + "name": "iface", + "description": "The switch port on which to operate.", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Interface" + } + } + } + }, + "4XX": { + "$ref": "#/components/responses/Error" + }, + "5XX": { + "$ref": "#/components/responses/Error" + } + } + }, + "put": { + "operationId": "interface_add", + "parameters": [ + { + "in": "path", + "name": "iface", + "description": "The switch port on which to operate.", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InterfaceAdd" + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "successful creation", + "content": { + "application/json": { + "schema": { + "title": "Null", + "type": "string", + "enum": [ + null + ] + } + } + } + }, + "4XX": { + "$ref": "#/components/responses/Error" + }, + "5XX": { + "$ref": "#/components/responses/Error" + } + } + }, + "delete": { + "operationId": "interface_del", + "parameters": [ + { + "in": "path", + "name": "iface", + "description": "The switch port on which to operate.", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "successful deletion" + }, + "4XX": { + "$ref": "#/components/responses/Error" + }, + "5XX": { + "$ref": "#/components/responses/Error" + } + } + } + }, + "/interface/{iface}/chassis_id": { + "post": { + "operationId": "interface_set_chassis_id", + "parameters": [ + { + "in": "path", + "name": "iface", + "description": "The switch port on which to operate.", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ChassisId" + } + } + }, + "required": true + }, + "responses": { + "204": { + "description": "resource updated" + }, + "4XX": { + "$ref": "#/components/responses/Error" + }, + "5XX": { + "$ref": "#/components/responses/Error" + } + } + }, + "delete": { + "operationId": "interface_del_chassis_id", + "parameters": [ + { + "in": "path", + "name": "iface", + "description": "The switch port on which to operate.", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "successful deletion" + }, + "4XX": { + "$ref": "#/components/responses/Error" + }, + "5XX": { + "$ref": "#/components/responses/Error" + } + } + } + }, + "/interface/{iface}/disabled": { + "post": { + "operationId": "interface_set_disabled", + "parameters": [ + { + "in": "path", + "name": "iface", + "description": "The switch port on which to operate.", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "title": "Boolean", + "type": "boolean" + } + } + }, + "required": true + }, + "responses": { + "204": { + "description": "resource updated" + }, + "4XX": { + "$ref": "#/components/responses/Error" + }, + "5XX": { + "$ref": "#/components/responses/Error" + } + } + } + }, + "/interface/{iface}/enabled_capability/{capability}": { + "post": { + "operationId": "interface_enable_system_capability", + "parameters": [ + { + "in": "path", + "name": "capability", + "required": true, + "schema": { + "$ref": "#/components/schemas/SystemCapabilities" + } + }, + { + "in": "path", + "name": "iface", + "description": "The switch port on which to operate.", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "resource updated" + }, + "4XX": { + "$ref": "#/components/responses/Error" + }, + "5XX": { + "$ref": "#/components/responses/Error" + } + } + }, + "delete": { + "operationId": "interface_disable_system_capability", + "parameters": [ + { + "in": "path", + "name": "capability", + "required": true, + "schema": { + "$ref": "#/components/schemas/SystemCapabilities" + } + }, + { + "in": "path", + "name": "iface", + "description": "The switch port on which to operate.", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "successful deletion" + }, + "4XX": { + "$ref": "#/components/responses/Error" + }, + "5XX": { + "$ref": "#/components/responses/Error" + } + } + } + }, + "/interface/{iface}/management_address": { + "delete": { + "operationId": "interface_clear_management_addr", + "parameters": [ + { + "in": "path", + "name": "iface", + "description": "The switch port on which to operate.", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "successful deletion" + }, + "4XX": { + "$ref": "#/components/responses/Error" + }, + "5XX": { + "$ref": "#/components/responses/Error" + } + } + } + }, + "/interface/{iface}/management_address/{address}": { + "post": { + "operationId": "interface_add_management_addr", + "parameters": [ + { + "in": "path", + "name": "address", + "description": "Management Address to advertise on this port", + "required": true, + "schema": { + "type": "string", + "format": "ip" + } + }, + { + "in": "path", + "name": "iface", + "description": "The switch port on which to operate.", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "resource updated" + }, + "4XX": { + "$ref": "#/components/responses/Error" + }, + "5XX": { + "$ref": "#/components/responses/Error" + } + } + }, + "delete": { + "operationId": "interface_del_management_addr", + "parameters": [ + { + "in": "path", + "name": "address", + "description": "Management Address to advertise on this port", + "required": true, + "schema": { + "type": "string", + "format": "ip" + } + }, + { + "in": "path", + "name": "iface", + "description": "The switch port on which to operate.", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "successful deletion" + }, + "4XX": { + "$ref": "#/components/responses/Error" + }, + "5XX": { + "$ref": "#/components/responses/Error" + } + } + } + }, + "/interface/{iface}/neighbors": { + "get": { + "summary": "Return a list of the active neighbors", + "operationId": "get_neighbors", + "parameters": [ + { + "in": "path", + "name": "iface", + "description": "The switch port on which to operate.", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "limit", + "description": "Maximum number of items returned by a single call", + "schema": { + "nullable": true, + "type": "integer", + "format": "uint32", + "minimum": 1 + } + }, + { + "in": "query", + "name": "page_token", + "description": "Token returned by previous call to retrieve the subsequent page", + "schema": { + "nullable": true, + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NeighborResultsPage" + } + } + } + }, + "4XX": { + "$ref": "#/components/responses/Error" + }, + "5XX": { + "$ref": "#/components/responses/Error" + } + }, + "x-dropshot-pagination": { + "required": [] + } + } + }, + "/interface/{iface}/port_description": { + "post": { + "operationId": "interface_set_port_description", + "parameters": [ + { + "in": "path", + "name": "iface", + "description": "The switch port on which to operate.", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "title": "String", + "type": "string" + } + } + }, + "required": true + }, + "responses": { + "204": { + "description": "resource updated" + }, + "4XX": { + "$ref": "#/components/responses/Error" + }, + "5XX": { + "$ref": "#/components/responses/Error" + } + } + }, + "delete": { + "operationId": "interface_del_port_description", + "parameters": [ + { + "in": "path", + "name": "iface", + "description": "The switch port on which to operate.", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "successful deletion" + }, + "4XX": { + "$ref": "#/components/responses/Error" + }, + "5XX": { + "$ref": "#/components/responses/Error" + } + } + } + }, + "/interface/{iface}/port_id": { + "post": { + "operationId": "interface_set_port_id", + "parameters": [ + { + "in": "path", + "name": "iface", + "description": "The switch port on which to operate.", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PortId" + } + } + }, + "required": true + }, + "responses": { + "204": { + "description": "resource updated" + }, + "4XX": { + "$ref": "#/components/responses/Error" + }, + "5XX": { + "$ref": "#/components/responses/Error" + } + } + } + }, + "/interface/{iface}/system_capability/{capability}": { + "post": { + "operationId": "interface_add_system_capability", + "parameters": [ + { + "in": "path", + "name": "capability", + "required": true, + "schema": { + "$ref": "#/components/schemas/SystemCapabilities" + } + }, + { + "in": "path", + "name": "iface", + "description": "The switch port on which to operate.", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "resource updated" + }, + "4XX": { + "$ref": "#/components/responses/Error" + }, + "5XX": { + "$ref": "#/components/responses/Error" + } + } + }, + "delete": { + "operationId": "interface_del_system_capability", + "parameters": [ + { + "in": "path", + "name": "capability", + "required": true, + "schema": { + "$ref": "#/components/schemas/SystemCapabilities" + } + }, + { + "in": "path", + "name": "iface", + "description": "The switch port on which to operate.", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "successful deletion" + }, + "4XX": { + "$ref": "#/components/responses/Error" + }, + "5XX": { + "$ref": "#/components/responses/Error" + } + } + } + }, + "/interface/{iface}/system_description": { + "post": { + "operationId": "interface_set_system_description", + "parameters": [ + { + "in": "path", + "name": "iface", + "description": "The switch port on which to operate.", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "title": "String", + "type": "string" + } + } + }, + "required": true + }, + "responses": { + "204": { + "description": "resource updated" + }, + "4XX": { + "$ref": "#/components/responses/Error" + }, + "5XX": { + "$ref": "#/components/responses/Error" + } + } + }, + "delete": { + "operationId": "interface_del_system_description", + "parameters": [ + { + "in": "path", + "name": "iface", + "description": "The switch port on which to operate.", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "successful deletion" + }, + "4XX": { + "$ref": "#/components/responses/Error" + }, + "5XX": { + "$ref": "#/components/responses/Error" + } + } + } + }, + "/interface/{iface}/system_name": { + "post": { + "operationId": "interface_set_system_name", + "parameters": [ + { + "in": "path", + "name": "iface", + "description": "The switch port on which to operate.", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "title": "String", + "type": "string" + } + } + }, + "required": true + }, + "responses": { + "204": { + "description": "resource updated" + }, + "4XX": { + "$ref": "#/components/responses/Error" + }, + "5XX": { + "$ref": "#/components/responses/Error" + } + } + }, + "delete": { + "operationId": "interface_del_system_name", + "parameters": [ + { + "in": "path", + "name": "iface", + "description": "The switch port on which to operate.", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "successful deletion" + }, + "4XX": { + "$ref": "#/components/responses/Error" + }, + "5XX": { + "$ref": "#/components/responses/Error" + } + } + } + }, + "/switch/identifiers": { + "get": { + "operationId": "switch_identifiers", + "responses": { + "200": { + "description": "successful operation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SwitchIdentifiers" + } + } + } + }, + "4XX": { + "$ref": "#/components/responses/Error" + }, + "5XX": { + "$ref": "#/components/responses/Error" + } + } + } + }, + "/system/chassis_id": { + "post": { + "summary": "Set the default chassis ID advertised on all ports", + "operationId": "sys_set_chassis_id", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ChassisId" + } + } + }, + "required": true + }, + "responses": { + "204": { + "description": "resource updated" + }, + "4XX": { + "$ref": "#/components/responses/Error" + }, + "5XX": { + "$ref": "#/components/responses/Error" + } + } + } + }, + "/system/enabled_capability/{capability}": { + "post": { + "summary": "Add a capability to the set of those advertised as enabled on all interfaces", + "operationId": "sys_enable_system_capability", + "parameters": [ + { + "in": "path", + "name": "capability", + "required": true, + "schema": { + "$ref": "#/components/schemas/SystemCapabilities" + } + } + ], + "responses": { + "204": { + "description": "resource updated" + }, + "4XX": { + "$ref": "#/components/responses/Error" + }, + "5XX": { + "$ref": "#/components/responses/Error" + } + } + }, + "delete": { + "summary": "Remove a capability from the set of those advertised as enabled on all interfaces", + "operationId": "sys_disable_system_capability", + "parameters": [ + { + "in": "path", + "name": "capability", + "required": true, + "schema": { + "$ref": "#/components/schemas/SystemCapabilities" + } + } + ], + "responses": { + "204": { + "description": "successful deletion" + }, + "4XX": { + "$ref": "#/components/responses/Error" + }, + "5XX": { + "$ref": "#/components/responses/Error" + } + } + } + }, + "/system/management_address": { + "delete": { + "summary": "Remove all management addresses from the set of those advertised on all", + "description": "interfaces", + "operationId": "sys_clear_management_addr", + "responses": { + "204": { + "description": "successful deletion" + }, + "4XX": { + "$ref": "#/components/responses/Error" + }, + "5XX": { + "$ref": "#/components/responses/Error" + } + } + } + }, + "/system/management_address/{address}": { + "post": { + "summary": "Add a management address to the set of those advertised on all interfaces", + "operationId": "sys_add_management_addr", + "parameters": [ + { + "in": "path", + "name": "address", + "required": true, + "schema": { + "type": "string", + "format": "ip" + } + } + ], + "responses": { + "204": { + "description": "resource updated" + }, + "4XX": { + "$ref": "#/components/responses/Error" + }, + "5XX": { + "$ref": "#/components/responses/Error" + } + } + }, + "delete": { + "summary": "Remove a management address from the set of those advertised on all interfaces", + "operationId": "sys_del_management_addr", + "parameters": [ + { + "in": "path", + "name": "address", + "required": true, + "schema": { + "type": "string", + "format": "ip" + } + } + ], + "responses": { + "204": { + "description": "successful deletion" + }, + "4XX": { + "$ref": "#/components/responses/Error" + }, + "5XX": { + "$ref": "#/components/responses/Error" + } + } + } + }, + "/system/system_capability/{capability}": { + "post": { + "summary": "Add a capability to the set of those advertised on all interfaces", + "operationId": "sys_add_system_capability", + "parameters": [ + { + "in": "path", + "name": "capability", + "required": true, + "schema": { + "$ref": "#/components/schemas/SystemCapabilities" + } + } + ], + "responses": { + "204": { + "description": "resource updated" + }, + "4XX": { + "$ref": "#/components/responses/Error" + }, + "5XX": { + "$ref": "#/components/responses/Error" + } + } + }, + "delete": { + "summary": "Remove a capability from the set of those advertised on all interfaces", + "operationId": "sys_del_system_capability", + "parameters": [ + { + "in": "path", + "name": "capability", + "required": true, + "schema": { + "$ref": "#/components/schemas/SystemCapabilities" + } + } + ], + "responses": { + "204": { + "description": "successful deletion" + }, + "4XX": { + "$ref": "#/components/responses/Error" + }, + "5XX": { + "$ref": "#/components/responses/Error" + } + } + } + }, + "/system/system_description": { + "post": { + "summary": "Set the default system description advertised on all interfaces", + "operationId": "sys_set_system_description", + "requestBody": { + "content": { + "application/json": { + "schema": { + "title": "String", + "type": "string" + } + } + }, + "required": true + }, + "responses": { + "204": { + "description": "resource updated" + }, + "4XX": { + "$ref": "#/components/responses/Error" + }, + "5XX": { + "$ref": "#/components/responses/Error" + } + } + }, + "delete": { + "summary": "Delete default system description advertised on all interfaces. A system name will", + "description": "only be advertised on those interfaces with a locally set system description.", + "operationId": "sys_del_system_description", + "responses": { + "204": { + "description": "successful deletion" + }, + "4XX": { + "$ref": "#/components/responses/Error" + }, + "5XX": { + "$ref": "#/components/responses/Error" + } + } + } + }, + "/system/system_name": { + "post": { + "summary": "Set the default system name advertised on all ports", + "operationId": "sys_set_system_name", + "requestBody": { + "content": { + "application/json": { + "schema": { + "title": "String", + "type": "string" + } + } + }, + "required": true + }, + "responses": { + "204": { + "description": "resource updated" + }, + "4XX": { + "$ref": "#/components/responses/Error" + }, + "5XX": { + "$ref": "#/components/responses/Error" + } + } + }, + "delete": { + "summary": "Delete default system name advertised on all ports. A system name will", + "description": "only be advertised on those interfaces with a locally set system name.", + "operationId": "sys_del_system_name", + "responses": { + "204": { + "description": "successful deletion" + }, + "4XX": { + "$ref": "#/components/responses/Error" + }, + "5XX": { + "$ref": "#/components/responses/Error" + } + } + } + } + }, + "components": { + "schemas": { + "BuildInfo": { + "description": "Detailed build information about `lldpd`.", + "type": "object", + "properties": { + "cargo_triple": { + "type": "string" + }, + "debug": { + "type": "boolean" + }, + "git_branch": { + "type": "string" + }, + "git_commit_timestamp": { + "type": "string" + }, + "git_sha": { + "type": "string" + }, + "opt_level": { + "type": "integer", + "format": "uint8", + "minimum": 0 + }, + "rustc_channel": { + "type": "string" + }, + "rustc_commit_sha": { + "type": "string" + }, + "rustc_host_triple": { + "type": "string" + }, + "rustc_semver": { + "type": "string" + }, + "version": { + "type": "string" + } + }, + "required": [ + "cargo_triple", + "debug", + "git_branch", + "git_commit_timestamp", + "git_sha", + "opt_level", + "rustc_channel", + "rustc_commit_sha", + "rustc_host_triple", + "rustc_semver", + "version" + ] + }, + "ChassisId": { + "oneOf": [ + { + "type": "object", + "properties": { + "ChassisComponent": { + "type": "string" + } + }, + "required": [ + "ChassisComponent" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "InterfaceAlias": { + "type": "string" + } + }, + "required": [ + "InterfaceAlias" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "PortComponent": { + "type": "string" + } + }, + "required": [ + "PortComponent" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "MacAddress": { + "$ref": "#/components/schemas/MacAddr" + } + }, + "required": [ + "MacAddress" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "NetworkAddress": { + "$ref": "#/components/schemas/NetworkAddress" + } + }, + "required": [ + "NetworkAddress" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "InterfaceName": { + "type": "string" + } + }, + "required": [ + "InterfaceName" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "LocallyAssigned": { + "type": "string" + } + }, + "required": [ + "LocallyAssigned" + ], + "additionalProperties": false + } + ] + }, + "Error": { + "description": "Error information from a response.", + "type": "object", + "properties": { + "error_code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "request_id": { + "type": "string" + } + }, + "required": [ + "message", + "request_id" + ] + }, + "Interface": { + "description": "A local interface on which we are listening for, and dispatching, LLDPDUs", + "type": "object", + "properties": { + "disabled": { + "type": "boolean" + }, + "iface": { + "type": "string" + }, + "port": { + "type": "string" + }, + "system_info": { + "$ref": "#/components/schemas/SystemInfo" + } + }, + "required": [ + "disabled", + "iface", + "port", + "system_info" + ] + }, + "InterfaceAdd": { + "description": "Optional arguments when adding an interface to LLDPD. Any argument left unspecified will be assigned the default values for this system.", + "type": "object", + "properties": { + "chassis_id": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/ChassisId" + } + ] + }, + "port_description": { + "nullable": true, + "type": "string" + }, + "port_id": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/PortId" + } + ] + }, + "system_description": { + "nullable": true, + "type": "string" + }, + "system_name": { + "nullable": true, + "type": "string" + } + } + }, + "InterfaceNum": { + "oneOf": [ + { + "type": "object", + "properties": { + "unknown": { + "type": "integer", + "format": "uint32", + "minimum": 0 + } + }, + "required": [ + "unknown" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "if_index": { + "type": "integer", + "format": "uint32", + "minimum": 0 + } + }, + "required": [ + "if_index" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "port_number": { + "type": "integer", + "format": "uint32", + "minimum": 0 + } + }, + "required": [ + "port_number" + ], + "additionalProperties": false + } + ] + }, + "MacAddr": { + "description": "An EUI-48 MAC address, used for layer-2 addressing.", + "type": "object", + "properties": { + "a": { + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0 + }, + "minItems": 6, + "maxItems": 6 + } + }, + "required": [ + "a" + ] + }, + "ManagementAddress": { + "type": "object", + "properties": { + "addr": { + "$ref": "#/components/schemas/NetworkAddress" + }, + "interface_num": { + "$ref": "#/components/schemas/InterfaceNum" + }, + "oid": { + "nullable": true, + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0 + } + } + }, + "required": [ + "addr", + "interface_num" + ] + }, + "Neighbor": { + "description": "A remote system that has been discovered on one of our configured interfaces", + "type": "object", + "properties": { + "first_seen": { + "description": "When was the first beacon received from this neighbor.", + "type": "string", + "format": "date-time" + }, + "id": { + "description": "An ID that uniquely identifies the neighbor. Note: this ID is assigned when we first see a neighbor we are currently tracking. If a neighbor goes offline long enough to be forgotten, it will be assigned a new ID if and when it comes back online.", + "type": "string", + "format": "uuid" + }, + "last_changed": { + "description": "When was the last time this neighbor's beaconed LLDPDU contents changed.", + "type": "string", + "format": "date-time" + }, + "last_seen": { + "description": "When was the latest beacon received from this neighbor.", + "type": "string", + "format": "date-time" + }, + "port": { + "description": "The port on which the neighbor was seen", + "type": "string" + }, + "system_info": { + "description": "Contents of the neighbor's LLDPDU beacon.", + "allOf": [ + { + "$ref": "#/components/schemas/SystemInfo" + } + ] + } + }, + "required": [ + "first_seen", + "id", + "last_changed", + "last_seen", + "port", + "system_info" + ] + }, + "NeighborResultsPage": { + "description": "A single page of results", + "type": "object", + "properties": { + "items": { + "description": "list of items on this page of results", + "type": "array", + "items": { + "$ref": "#/components/schemas/Neighbor" + } + }, + "next_page": { + "nullable": true, + "description": "token used to fetch the next page of results (if any)", + "type": "string" + } + }, + "required": [ + "items" + ] + }, + "NetworkAddress": { + "oneOf": [ + { + "type": "object", + "properties": { + "ip_addr": { + "type": "string", + "format": "ip" + } + }, + "required": [ + "ip_addr" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "i_e_e_e802": { + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0 + } + } + }, + "required": [ + "i_e_e_e802" + ], + "additionalProperties": false + } + ] + }, + "PortId": { + "oneOf": [ + { + "type": "object", + "properties": { + "InterfaceAlias": { + "type": "string" + } + }, + "required": [ + "InterfaceAlias" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "PortComponent": { + "type": "string" + } + }, + "required": [ + "PortComponent" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "MacAddress": { + "$ref": "#/components/schemas/MacAddr" + } + }, + "required": [ + "MacAddress" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "NetworkAddress": { + "$ref": "#/components/schemas/NetworkAddress" + } + }, + "required": [ + "NetworkAddress" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "InterfaceName": { + "type": "string" + } + }, + "required": [ + "InterfaceName" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "AgentCircuitId": { + "type": "string" + } + }, + "required": [ + "AgentCircuitId" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "LocallyAssigned": { + "type": "string" + } + }, + "required": [ + "LocallyAssigned" + ], + "additionalProperties": false + } + ] + }, + "SwitchIdentifiers": { + "description": "Identifiers for a switch.", + "type": "object", + "properties": { + "slot": { + "nullable": true, + "description": "The slot number of the switch being managed.\n\nMGS uses u16 for this internally.", + "type": "integer", + "format": "uint16", + "minimum": 0 + } + } + }, + "SystemCapabilities": { + "description": "System Capabilities are defined by table 8-4. In an LLDPDU a system's available and enabled capabilities are represented by bitmasks, with the value below acting as the index into that bitmask.", + "type": "string", + "enum": [ + "Other", + "Repeater", + "MacBridgeComponent", + "AccessPoint", + "Router", + "Telephone", + "Docsis", + "StationOnly", + "CVlanComponent", + "SVlanComponent", + "MacRelayComponent" + ] + }, + "SystemInfo": { + "type": "object", + "properties": { + "capabilities_available": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SystemCapabilities" + } + }, + "capabilities_enabled": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SystemCapabilities" + } + }, + "chassis_id": { + "$ref": "#/components/schemas/ChassisId" + }, + "management_addresses": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ManagementAddress" + } + }, + "organizationally_specific": { + "type": "array", + "items": { + "type": "string" + } + }, + "port_description": { + "nullable": true, + "type": "string" + }, + "port_id": { + "$ref": "#/components/schemas/PortId" + }, + "system_description": { + "nullable": true, + "type": "string" + }, + "system_name": { + "nullable": true, + "type": "string" + }, + "ttl": { + "type": "integer", + "format": "uint16", + "minimum": 0 + } + }, + "required": [ + "capabilities_available", + "capabilities_enabled", + "chassis_id", + "management_addresses", + "organizationally_specific", + "port_id", + "ttl" + ] + } + }, + "responses": { + "Error": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } +} diff --git a/openapi/lldpd/lldpd-latest.json b/openapi/lldpd/lldpd-latest.json index 8dd1c55..bc4ee5c 120000 --- a/openapi/lldpd/lldpd-latest.json +++ b/openapi/lldpd/lldpd-latest.json @@ -1 +1 @@ -lldpd-1.0.0-c4e95f.json \ No newline at end of file +lldpd-2.0.0-c1be66.json \ No newline at end of file