feat(harmony_macros): add yaml macro to validate YAML input

- Introduced a new `yaml` macro in `harmony_macros` that validates if the provided YAML string is valid by attempting to deserialize it using `serde_yaml`.
- Added dependencies on `serde`, `serde_yaml` for handling YAML deserialization.
- Included dev dependencies with features enabled for deriving types from `serde`.
This commit is contained in:
Jean-Gabriel Gill-Couture 2025-01-22 10:21:08 -05:00
parent 2041ce63d7
commit d8c762e9df
5 changed files with 861 additions and 33 deletions

652
harmony-rs/Cargo.lock generated
View File

@ -188,6 +188,12 @@ version = "0.21.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
[[package]]
name = "base64"
version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]]
name = "base64ct"
version = "1.6.0"
@ -323,6 +329,7 @@ dependencies = [
"iana-time-zone",
"js-sys",
"num-traits",
"serde",
"wasm-bindgen",
"windows-targets 0.52.6",
]
@ -385,6 +392,16 @@ dependencies = [
"libc",
]
[[package]]
name = "core-foundation"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b55271e5c8c478ad3f38ad24ef34923091e0548492a266d19b3c0b4d82574c63"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]]
name = "core-foundation-sys"
version = "0.8.7"
@ -579,6 +596,12 @@ dependencies = [
"zeroize",
]
[[package]]
name = "either"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
[[package]]
name = "elliptic-curve"
version = "0.13.8"
@ -722,6 +745,19 @@ dependencies = [
"percent-encoding",
]
[[package]]
name = "fqm"
version = "0.1.0"
dependencies = [
"cidr",
"env_logger",
"harmony",
"harmony_macros",
"harmony_types",
"log",
"tokio",
]
[[package]]
name = "funty"
version = "2.0.0"
@ -877,7 +913,7 @@ dependencies = [
"futures-core",
"futures-sink",
"futures-util",
"http",
"http 0.2.12",
"indexmap",
"slab",
"tokio",
@ -916,6 +952,8 @@ version = "1.0.0"
dependencies = [
"harmony_types",
"quote",
"serde",
"serde_yaml",
"syn",
]
@ -929,6 +967,30 @@ version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
[[package]]
name = "headers"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "322106e6bd0cba2d5ead589ddb8150a13d7c4217cf80d7c4f682ca994ccc6aa9"
dependencies = [
"base64 0.21.7",
"bytes",
"headers-core",
"http 1.2.0",
"httpdate",
"mime",
"sha1",
]
[[package]]
name = "headers-core"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54b4a22553d4242c49fddb9ba998a99962b5cc6f22cb5a3482bec22522403ce4"
dependencies = [
"http 1.2.0",
]
[[package]]
name = "heck"
version = "0.5.0"
@ -985,6 +1047,17 @@ dependencies = [
"itoa",
]
[[package]]
name = "http"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea"
dependencies = [
"bytes",
"fnv",
"itoa",
]
[[package]]
name = "http-body"
version = "0.4.6"
@ -992,7 +1065,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2"
dependencies = [
"bytes",
"http",
"http 0.2.12",
"pin-project-lite",
]
[[package]]
name = "http-body"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
dependencies = [
"bytes",
"http 1.2.0",
]
[[package]]
name = "http-body-util"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f"
dependencies = [
"bytes",
"futures-util",
"http 1.2.0",
"http-body 1.0.1",
"pin-project-lite",
]
@ -1025,8 +1121,8 @@ dependencies = [
"futures-core",
"futures-util",
"h2",
"http",
"http-body",
"http 0.2.12",
"http-body 0.4.6",
"httparse",
"httpdate",
"itoa",
@ -1038,6 +1134,77 @@ dependencies = [
"want",
]
[[package]]
name = "hyper"
version = "1.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "256fb8d4bd6413123cc9d91832d78325c48ff41677595be797d90f42969beae0"
dependencies = [
"bytes",
"futures-channel",
"futures-util",
"http 1.2.0",
"http-body 1.0.1",
"httparse",
"itoa",
"pin-project-lite",
"smallvec",
"tokio",
"want",
]
[[package]]
name = "hyper-http-proxy"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d06dbdfbacf34d996c6fb540a71a684a7aae9056c71951163af8a8a4c07b9a4"
dependencies = [
"bytes",
"futures-util",
"headers",
"http 1.2.0",
"hyper 1.5.2",
"hyper-rustls",
"hyper-util",
"pin-project-lite",
"rustls-native-certs 0.7.3",
"tokio",
"tokio-rustls",
"tower-service",
]
[[package]]
name = "hyper-rustls"
version = "0.27.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2"
dependencies = [
"futures-util",
"http 1.2.0",
"hyper 1.5.2",
"hyper-util",
"log",
"rustls",
"rustls-native-certs 0.8.1",
"rustls-pki-types",
"tokio",
"tokio-rustls",
"tower-service",
]
[[package]]
name = "hyper-timeout"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0"
dependencies = [
"hyper 1.5.2",
"hyper-util",
"pin-project-lite",
"tokio",
"tower-service",
]
[[package]]
name = "hyper-tls"
version = "0.5.0"
@ -1045,12 +1212,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
dependencies = [
"bytes",
"hyper",
"hyper 0.14.30",
"native-tls",
"tokio",
"tokio-native-tls",
]
[[package]]
name = "hyper-util"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4"
dependencies = [
"bytes",
"futures-channel",
"futures-util",
"http 1.2.0",
"http-body 1.0.1",
"hyper 1.5.2",
"pin-project-lite",
"socket2",
"tokio",
"tower-service",
"tracing",
]
[[package]]
name = "iana-time-zone"
version = "0.1.61"
@ -1260,6 +1446,97 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "jsonpath-rust"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c00ae348f9f8fd2d09f82a98ca381c60df9e0820d8d79fce43e649b4dc3128b"
dependencies = [
"pest",
"pest_derive",
"regex",
"serde_json",
"thiserror 2.0.11",
]
[[package]]
name = "k8s-openapi"
version = "0.24.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c75b990324f09bef15e791606b7b7a296d02fc88a344f6eba9390970a870ad5"
dependencies = [
"base64 0.22.1",
"chrono",
"serde",
"serde-value",
"serde_json",
]
[[package]]
name = "kube"
version = "0.98.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32053dc495efad4d188c7b33cc7c02ef4a6e43038115348348876efd39a53cba"
dependencies = [
"k8s-openapi",
"kube-client",
"kube-core",
]
[[package]]
name = "kube-client"
version = "0.98.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d34ad38cdfbd1fa87195d42569f57bb1dda6ba5f260ee32fef9570b7937a0c9"
dependencies = [
"base64 0.22.1",
"bytes",
"chrono",
"either",
"futures",
"home",
"http 1.2.0",
"http-body 1.0.1",
"http-body-util",
"hyper 1.5.2",
"hyper-http-proxy",
"hyper-rustls",
"hyper-timeout",
"hyper-util",
"jsonpath-rust",
"k8s-openapi",
"kube-core",
"pem",
"rustls",
"rustls-pemfile 2.2.0",
"secrecy",
"serde",
"serde_json",
"serde_yaml",
"thiserror 2.0.11",
"tokio",
"tokio-util",
"tower",
"tower-http",
"tracing",
]
[[package]]
name = "kube-core"
version = "0.98.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97aa830b288a178a90e784d1b0f1539f2d200d2188c7b4a3146d9dc983d596f3"
dependencies = [
"chrono",
"form_urlencoded",
"http 1.2.0",
"k8s-openapi",
"serde",
"serde-value",
"serde_json",
"thiserror 2.0.11",
]
[[package]]
name = "lazy_static"
version = "1.5.0"
@ -1382,7 +1659,7 @@ dependencies = [
"openssl-probe",
"openssl-sys",
"schannel",
"security-framework",
"security-framework 2.11.1",
"security-framework-sys",
"tempfile",
]
@ -1535,7 +1812,7 @@ dependencies = [
"russh-sftp",
"serde",
"serde_json",
"thiserror",
"thiserror 1.0.63",
"tokio",
"tokio-stream",
"tokio-util",
@ -1551,7 +1828,7 @@ dependencies = [
"pretty_assertions",
"rand",
"serde",
"thiserror",
"thiserror 1.0.63",
"tokio",
"uuid",
"xml-rs",
@ -1559,6 +1836,15 @@ dependencies = [
"yaserde_derive",
]
[[package]]
name = "ordered-float"
version = "2.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68f19d67e5a2795c94e73e0bb1cc1a7edeb2e28efd39e2e1c9b7a40c1108b11c"
dependencies = [
"num-traits",
]
[[package]]
name = "p256"
version = "0.13.2"
@ -1653,6 +1939,16 @@ dependencies = [
"hmac",
]
[[package]]
name = "pem"
version = "3.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e459365e590736a54c3fa561947c84837534b8e9af6fc5bf781307e82658fae"
dependencies = [
"base64 0.22.1",
"serde",
]
[[package]]
name = "pem-rfc7468"
version = "0.7.0"
@ -1668,6 +1964,51 @@ version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
[[package]]
name = "pest"
version = "2.7.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b7cafe60d6cf8e62e1b9b2ea516a089c008945bb5a275416789e7db0bc199dc"
dependencies = [
"memchr",
"thiserror 2.0.11",
"ucd-trie",
]
[[package]]
name = "pest_derive"
version = "2.7.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "816518421cfc6887a0d62bf441b6ffb4536fcc926395a69e1a85852d4363f57e"
dependencies = [
"pest",
"pest_generator",
]
[[package]]
name = "pest_generator"
version = "2.7.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d1396fd3a870fc7838768d171b4616d5c91f6cc25e377b673d714567d99377b"
dependencies = [
"pest",
"pest_meta",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "pest_meta"
version = "2.7.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1e58089ea25d717bfd31fb534e4f3afcc2cc569c70de3e239778991ea3b7dea"
dependencies = [
"once_cell",
"pest",
"sha2",
]
[[package]]
name = "pin-project-lite"
version = "0.2.14"
@ -1873,15 +2214,15 @@ version = "0.11.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62"
dependencies = [
"base64",
"base64 0.21.7",
"bytes",
"encoding_rs",
"futures-core",
"futures-util",
"h2",
"http",
"http-body",
"hyper",
"http 0.2.12",
"http-body 0.4.6",
"hyper 0.14.30",
"hyper-tls",
"ipnet",
"js-sys",
@ -1891,11 +2232,11 @@ dependencies = [
"once_cell",
"percent-encoding",
"pin-project-lite",
"rustls-pemfile",
"rustls-pemfile 1.0.4",
"serde",
"serde_json",
"serde_urlencoded",
"sync_wrapper",
"sync_wrapper 0.1.2",
"system-configuration",
"tokio",
"tokio-native-tls",
@ -1917,6 +2258,21 @@ dependencies = [
"subtle",
]
[[package]]
name = "ring"
version = "0.17.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d"
dependencies = [
"cc",
"cfg-if",
"getrandom",
"libc",
"spin",
"untrusted",
"windows-sys 0.52.0",
]
[[package]]
name = "rsa"
version = "0.9.6"
@ -1977,7 +2333,7 @@ dependencies = [
"ssh-encoding",
"ssh-key",
"subtle",
"thiserror",
"thiserror 1.0.63",
"tokio",
]
@ -2035,7 +2391,7 @@ dependencies = [
"spki",
"ssh-encoding",
"ssh-key",
"thiserror",
"thiserror 1.0.63",
"tokio",
"tokio-stream",
"typenum",
@ -2055,7 +2411,7 @@ dependencies = [
"flurry",
"log",
"serde",
"thiserror",
"thiserror 1.0.63",
"tokio",
"tokio-util",
]
@ -2072,7 +2428,7 @@ dependencies = [
"hmac",
"rand",
"sha2",
"thiserror",
"thiserror 1.0.63",
]
[[package]]
@ -2103,13 +2459,79 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "rustls"
version = "0.23.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f287924602bf649d949c63dc8ac8b235fa5387d394020705b80c4eb597ce5b8"
dependencies = [
"log",
"once_cell",
"ring",
"rustls-pki-types",
"rustls-webpki",
"subtle",
"zeroize",
]
[[package]]
name = "rustls-native-certs"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5bfb394eeed242e909609f56089eecfe5fda225042e8b171791b9c95f5931e5"
dependencies = [
"openssl-probe",
"rustls-pemfile 2.2.0",
"rustls-pki-types",
"schannel",
"security-framework 2.11.1",
]
[[package]]
name = "rustls-native-certs"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fcff2dd52b58a8d98a70243663a0d234c4e2b79235637849d15913394a247d3"
dependencies = [
"openssl-probe",
"rustls-pki-types",
"schannel",
"security-framework 3.2.0",
]
[[package]]
name = "rustls-pemfile"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c"
dependencies = [
"base64",
"base64 0.21.7",
]
[[package]]
name = "rustls-pemfile"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50"
dependencies = [
"rustls-pki-types",
]
[[package]]
name = "rustls-pki-types"
version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2bf47e6ff922db3825eb750c4e2ff784c6ff8fb9e13046ef6a1d1c5401b0b37"
[[package]]
name = "rustls-webpki"
version = "0.102.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9"
dependencies = [
"ring",
"rustls-pki-types",
"untrusted",
]
[[package]]
@ -2167,6 +2589,15 @@ dependencies = [
"zeroize",
]
[[package]]
name = "secrecy"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e891af845473308773346dc847b2c23ee78fe442e0472ac50e22a18a93d3ae5a"
dependencies = [
"zeroize",
]
[[package]]
name = "security-framework"
version = "2.11.1"
@ -2174,7 +2605,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
dependencies = [
"bitflags 2.6.0",
"core-foundation",
"core-foundation 0.9.4",
"core-foundation-sys",
"libc",
"security-framework-sys",
]
[[package]]
name = "security-framework"
version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "271720403f46ca04f7ba6f55d438f8bd878d6b8ca0a1046e8228c4145bcbb316"
dependencies = [
"bitflags 2.6.0",
"core-foundation 0.10.0",
"core-foundation-sys",
"libc",
"security-framework-sys",
@ -2182,9 +2626,9 @@ dependencies = [
[[package]]
name = "security-framework-sys"
version = "2.11.1"
version = "2.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf"
checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32"
dependencies = [
"core-foundation-sys",
"libc",
@ -2204,18 +2648,28 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
[[package]]
name = "serde"
version = "1.0.209"
version = "1.0.217"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09"
checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.209"
name = "serde-value"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170"
checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c"
dependencies = [
"ordered-float",
"serde",
]
[[package]]
name = "serde_derive"
version = "1.0.217"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0"
dependencies = [
"proc-macro2",
"quote",
@ -2258,6 +2712,19 @@ dependencies = [
"serde",
]
[[package]]
name = "serde_yaml"
version = "0.9.34+deprecated"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47"
dependencies = [
"indexmap",
"itoa",
"ryu",
"serde",
"unsafe-libyaml",
]
[[package]]
name = "sha1"
version = "0.10.6"
@ -2426,6 +2893,12 @@ version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
[[package]]
name = "sync_wrapper"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263"
[[package]]
name = "synstructure"
version = "0.13.1"
@ -2444,7 +2917,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7"
dependencies = [
"bitflags 1.3.2",
"core-foundation",
"core-foundation 0.9.4",
"system-configuration-sys",
]
@ -2477,13 +2950,39 @@ dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "test-kube-rs"
version = "0.1.0"
dependencies = [
"cidr",
"env_logger",
"harmony",
"harmony_macros",
"http 1.2.0",
"k8s-openapi",
"kube",
"log",
"serde_yaml",
"tokio",
"url",
]
[[package]]
name = "thiserror"
version = "1.0.63"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724"
dependencies = [
"thiserror-impl",
"thiserror-impl 1.0.63",
]
[[package]]
name = "thiserror"
version = "2.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc"
dependencies = [
"thiserror-impl 2.0.11",
]
[[package]]
@ -2497,6 +2996,17 @@ dependencies = [
"syn",
]
[[package]]
name = "thiserror-impl"
version = "2.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tiny-keccak"
version = "2.0.2"
@ -2554,6 +3064,16 @@ dependencies = [
"tokio",
]
[[package]]
name = "tokio-rustls"
version = "0.26.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f6d0975eaace0cf0fcadee4e4aaa5da15b5c079146f2cffb67c113be122bf37"
dependencies = [
"rustls",
"tokio",
]
[[package]]
name = "tokio-stream"
version = "0.1.17"
@ -2578,6 +3098,47 @@ dependencies = [
"tokio",
]
[[package]]
name = "tower"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9"
dependencies = [
"futures-core",
"futures-util",
"pin-project-lite",
"sync_wrapper 1.0.2",
"tokio",
"tokio-util",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]
name = "tower-http"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "403fa3b783d4b626a8ad51d766ab03cb6d2dbfc46b1c5d4448395e6628dc9697"
dependencies = [
"base64 0.22.1",
"bitflags 2.6.0",
"bytes",
"http 1.2.0",
"http-body 1.0.1",
"mime",
"pin-project-lite",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]
name = "tower-layer"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e"
[[package]]
name = "tower-service"
version = "0.3.3"
@ -2590,10 +3151,23 @@ version = "0.1.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
dependencies = [
"log",
"pin-project-lite",
"tracing-attributes",
"tracing-core",
]
[[package]]
name = "tracing-attributes"
version = "0.1.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tracing-core"
version = "0.1.32"
@ -2615,6 +3189,12 @@ version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
[[package]]
name = "ucd-trie"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971"
[[package]]
name = "unicode-ident"
version = "1.0.12"
@ -2631,6 +3211,18 @@ dependencies = [
"subtle",
]
[[package]]
name = "unsafe-libyaml"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861"
[[package]]
name = "untrusted"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
[[package]]
name = "url"
version = "2.5.4"
@ -3037,6 +3629,7 @@ checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049"
[[package]]
name = "yaserde"
version = "0.12.0"
source = "git+https://github.com/jggc/yaserde.git#c94ca32b6505f9c9a668702a1b1f1f88c6374301"
dependencies = [
"log",
"xml-rs",
@ -3045,6 +3638,7 @@ dependencies = [
[[package]]
name = "yaserde_derive"
version = "0.12.0"
source = "git+https://github.com/jggc/yaserde.git#c94ca32b6505f9c9a668702a1b1f1f88c6374301"
dependencies = [
"heck",
"log",

View File

@ -14,3 +14,6 @@ log = { workspace = true }
env_logger = { workspace = true }
url = { workspace = true }
kube = "0.98.0"
k8s-openapi = { version = "0.24.0", features = [ "v1_30" ] }
http = "1.2.0"
serde_yaml = "0.9.34"

View File

@ -1,8 +1,194 @@
use kube::Client;
use std::collections::BTreeMap;
use harmony_macros::yaml;
use k8s_openapi::{
api::{
apps::v1::{Deployment, DeploymentSpec},
core::v1::{Container, Node, Pod, PodSpec, PodTemplateSpec},
},
apimachinery::pkg::apis::meta::v1::LabelSelector,
};
use kube::{
Api, Client, Config, ResourceExt,
api::{ListParams, ObjectMeta, PostParams},
};
#[tokio::main]
async fn main() {
let client = Client::try_default().await.expect("Should instanciate client from defaults");
println!("apiserver_version {:?}", client.apiserver_version());
let client = Client::try_default()
.await
.expect("Should instanciate client from defaults");
println!("apiserver_version {:?}", client.apiserver_version().await);
println!("default namespace {:?}", client.default_namespace());
// println!(
// "apiserver_groups {:?}",
// client
// .list_api_groups()
// .await
// .unwrap()
// .groups
// .iter()
// .map(|g| g.name.clone())
// .collect::<Vec<_>>()
// );
// let pods: Api<Pod> = Api::default_namespaced(client.clone());
// for p in pods.list(&ListParams::default()).await.unwrap() {
// println!("found pod {}", p.name_any())
// }
// let nodes : Api<Node> = Api::all(client.clone());
// for n in nodes.list(&ListParams::default()).await.unwrap() {
// println!("found node {} status {:?}", n.name_any(), n.status.unwrap())
// }
let nginxdeployment = nginx_deployment_2();
let nginxdeployment = nginx_deployment_serde();
assert_eq!(nginx_deployment_2(), nginx_macro());
assert_eq!(nginx_deployment_serde(), nginx_macro());
let nginxdeployment = nginx_macro();
let deployment: Api<Deployment> = Api::default_namespaced(client.clone());
match deployment
.create(&PostParams::default(), &nginxdeployment)
.await
{
Ok(_d) => println!("Deployment success"),
Err(e) => {
println!("Error creating deployment {}", e);
if let kube::Error::Api(error_response) = &e {
if error_response.code == http::StatusCode::CONFLICT.as_u16() {
println!("Already exists");
return;
}
}
panic!("{}", e)
}
};
println!(
"{:?}",
deployment
.get_status(&nginxdeployment.name_unchecked())
.await
.unwrap()
);
println!("Hello world");
}
fn nginx_macro() -> Deployment {
yaml!(
r#"
metadata:
name: "nginx-test"
spec:
selector:
matchLabels:
app: nginx-test
template:
metadata:
labels:
app: nginx-test
spec:
containers:
- image: nginx
name: nginx"#
)
.unwrap()
}
fn nginx_deployment_serde() -> Deployment {
let deployment: Deployment = serde_yaml::from_str(
r#"
metadata:
name: "nginx-test"
spec:
selector:
matchLabels:
app: nginx-test
template:
metadata:
labels:
app: nginx-test
spec:
containers:
- image: nginx
name: nginx"#,
)
.unwrap();
return deployment;
}
fn nginx_deployment_2() -> Deployment {
let mut pod_template = PodTemplateSpec::default();
pod_template.metadata = Some(ObjectMeta {
labels: Some(BTreeMap::from([(
"app".to_string(),
"nginx-test".to_string(),
)])),
..Default::default()
});
pod_template.spec = Some(PodSpec {
containers: vec![Container {
name: "nginx".to_string(),
image: Some("nginx".to_string()),
..Default::default()
}],
..Default::default()
});
let mut spec = DeploymentSpec::default();
spec.template = pod_template;
spec.selector = LabelSelector {
match_expressions: None,
match_labels: Some(BTreeMap::from([(
"app".to_string(),
"nginx-test".to_string(),
)])),
};
let mut deployment = Deployment::default();
deployment.spec = Some(spec);
deployment.metadata.name = Some("nginx-test".to_string());
deployment
}
fn nginx_deployment() -> Deployment {
let deployment = Deployment {
metadata: ObjectMeta {
name: Some("nginx-test".to_string()),
..Default::default()
},
spec: Some(DeploymentSpec {
min_ready_seconds: None,
paused: None,
progress_deadline_seconds: None,
replicas: Some(1),
revision_history_limit: Some(10),
selector: LabelSelector {
match_expressions: None,
match_labels: Some(BTreeMap::from([(
"app".to_string(),
"nginx-test".to_string(),
)])),
},
strategy: None,
template: PodTemplateSpec {
metadata: Some(ObjectMeta {
labels: Some(BTreeMap::from([(
"app".to_string(),
"nginx-test".to_string(),
)])),
..Default::default()
}),
spec: Some(PodSpec {
containers: vec![Container {
name: "nginx".to_string(),
image: Some("nginx".to_string()),
..Default::default()
}],
..Default::default()
}),
},
}),
status: None,
};
println!("{:?}", deployment.managed_fields());
deployment
}

View File

@ -9,4 +9,9 @@ proc-macro = true
[dependencies]
harmony_types = { path = "../harmony_types" }
quote = "1.0.37"
serde = "1.0.217"
serde_yaml = "0.9.34"
syn = "2.0.90"
[dev-dependencies]
serde = { version = "1.0.217", features = ["derive"] }

View File

@ -2,7 +2,9 @@ extern crate proc_macro;
use proc_macro::TokenStream;
use quote::quote;
use syn::{LitStr, parse_macro_input};
use serde_yaml::Value;
use syn::LitStr;
use syn::parse_macro_input;
#[proc_macro]
pub fn ip(input: TokenStream) -> TokenStream {
@ -76,3 +78,41 @@ fn parse_mac_address(mac: &str) -> Result<[u8; 6], String> {
Ok(bytes)
}
/// Verify that input is valid yaml by trying to deserialize it using
/// serde_yaml::from_str::<serde_yaml::value::Value>(input)
///
/// panics: If yaml is not valid
#[proc_macro]
pub fn yaml(input: TokenStream) -> TokenStream {
// TODO, accept a second argument that is the type to be deserialized to and validate at
// compile-time that deserialization is possible
//
// It does not seem to be doable with the way macros are designed : we may pass an ident to the
// macro, but the macro only has access to the ident, not the type itself.
//
// I also tried to create a restricted version of this macro, but this time serde got in the
// way : my use case is to make sure that the yaml I am given can deserialize strictly (with
// deny_unknown_attributes option on) to k8s-openapi types. But the k8s-openapi types are not
// annotated with deny_unknown_attributes and there does not seem to be a way to tell serde to
// deserialize in "strict mode" when calling the deserialization function itself. I tried
// wrapping the types in something like :
//
// ```rust
// #[derive(Deserialize, Debug)]
// #[serde(deny_unknown_fields)]
// struct Strict<T>(pub T);
// ```
//
// But it still does actually deserialize T strictly. I gave up for now at this point. Will
// find a solution some day!
let yaml = parse_macro_input!(input as LitStr);
serde_yaml::from_str::<Value>(yaml.value().as_str()).expect("Should be valid yaml");
quote! {
serde_yaml::from_str(#yaml)
}
.into()
}