first commit
This commit is contained in:
commit
fc346d45f1
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/target
|
696
Cargo.lock
generated
Normal file
696
Cargo.lock
generated
Normal file
@ -0,0 +1,696 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.10.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "build_html"
|
||||
version = "2.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa8ffb62af7b0911893e2d6126891b2a018e387078fa5d855cb42d0d90d88075"
|
||||
|
||||
[[package]]
|
||||
name = "bytecount"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2c676a478f63e9fa2dd5368a42f28bba0d6c560b775f38583c8bbaa7fcd67c9c"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.77"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4"
|
||||
|
||||
[[package]]
|
||||
name = "cdh"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"build_html",
|
||||
"clap",
|
||||
"env_logger",
|
||||
"handlebars",
|
||||
"log",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_yaml",
|
||||
"tabled",
|
||||
"version-compare",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ec7a4128863c188deefe750ac1d1dfe66c236909f845af04beed823638dc1b2"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"clap_derive",
|
||||
"clap_lex",
|
||||
"is-terminal",
|
||||
"once_cell",
|
||||
"strsim",
|
||||
"termcolor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "4.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "684a277d672e91966334af371f1a7b5833f9aa00b07c84e92fbce95e00208ce8"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "783fe232adfca04f90f56201b26d79682d4cd2625e0bc7290b95123afe558ade"
|
||||
dependencies = [
|
||||
"os_str_bytes",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.10.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "adfbc57365a37acbd2ebf2b64d7e69bb766e2fea813521ed536f5d0520dcf86c"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"crypto-common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0"
|
||||
dependencies = [
|
||||
"humantime",
|
||||
"is-terminal",
|
||||
"log",
|
||||
"regex",
|
||||
"termcolor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1"
|
||||
dependencies = [
|
||||
"errno-dragonfly",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "errno-dragonfly"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "handlebars"
|
||||
version = "4.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "433e4ab33f1213cdc25b5fa45c76881240cfe79284cf2b395e8b9e312a30a2fd"
|
||||
dependencies = [
|
||||
"log",
|
||||
"pest",
|
||||
"pest_derive",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "humantime"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "io-lifetimes"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e394faa0efb47f9f227f1cd89978f854542b318a6f64fa695489c9c993056656"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is-terminal"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28dfb6c8100ccc63462345b67d1bbc3679177c75ee4bf59bf29c8b1d110b8189"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"io-lifetimes",
|
||||
"rustix",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.137"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89"
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f9f08d8963a6c613f4b1a78f4f4a4dbfadf8e6545b2d72861731e4858b8b47f"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860"
|
||||
|
||||
[[package]]
|
||||
name = "os_str_bytes"
|
||||
version = "6.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3baf96e39c5359d2eb0dd6ccb42c62b91d9678aa68160d261b9e0ccbf9e9dea9"
|
||||
|
||||
[[package]]
|
||||
name = "papergrid"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1526bb6aa9f10ec339fb10360f22c57edf81d5678d0278e93bc12a47ffbe4b01"
|
||||
dependencies = [
|
||||
"bytecount",
|
||||
"fnv",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pest"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dbc7bc69c062e492337d74d59b120c274fd3d261b6bf6d3207d499b4b379c41a"
|
||||
dependencies = [
|
||||
"thiserror",
|
||||
"ucd-trie",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pest_derive"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60b75706b9642ebcb34dab3bc7750f811609a0eb1dd8b88c2d15bf628c1c65b2"
|
||||
dependencies = [
|
||||
"pest",
|
||||
"pest_generator",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pest_generator"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4f9272122f5979a6511a749af9db9bfc810393f63119970d7085fed1c4ea0db"
|
||||
dependencies = [
|
||||
"pest",
|
||||
"pest_meta",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pest_meta"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c8717927f9b79515e565a64fe46c38b8cd0427e64c40680b14a7365ab09ac8d"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"pest",
|
||||
"sha1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
||||
dependencies = [
|
||||
"proc-macro-error-attr",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error-attr"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.47"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.36.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4feacf7db682c6c329c4ede12649cd36ecab0f3be5b7d74e6a20304725db4549"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"errno",
|
||||
"io-lifetimes",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.147"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.147"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.87"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ce777b7b150d76b9cf60d28b55f5847135a003f7d7350c6be7a773508ce7d45"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_yaml"
|
||||
version = "0.9.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92b5b431e8907b50339b51223b97d102db8d987ced36f6e4d03621db9316c834"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
"unsafe-libyaml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha1"
|
||||
version = "0.10.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.103"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tabled"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56c3ee73732ffceaea7b8f6b719ce3bb17f253fa27461ffeaf568ebd0cdb4b85"
|
||||
dependencies = [
|
||||
"papergrid",
|
||||
"tabled_derive",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tabled_derive"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "beca1b4eaceb4f2755df858b88d9b9315b7ccfd1ffd0d7a48a52602301f01a57"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"
|
||||
|
||||
[[package]]
|
||||
name = "ucd-trie"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
|
||||
|
||||
[[package]]
|
||||
name = "unsafe-libyaml"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc7ed8ba44ca06be78ea1ad2c3682a43349126c8818054231ee6f4748012aed2"
|
||||
|
||||
[[package]]
|
||||
name = "version-compare"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fe88247b92c1df6b6de80ddc290f3976dbdf2f5f5d3fd049a9fb598c6dd5ca73"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.42.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.42.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.42.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.42.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.42.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.42.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.42.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.42.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5"
|
18
Cargo.toml
Normal file
18
Cargo.toml
Normal file
@ -0,0 +1,18 @@
|
||||
[package]
|
||||
name = "cdh"
|
||||
authors = ["allanger <allanger@zohomail.com>"]
|
||||
version = "0.1.0"
|
||||
description = "Your helm releases are outdated, aren't they? Now you can check"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
serde = { version = "1.0.126", features = ["derive"] }
|
||||
serde_json = "1.0.64"
|
||||
log = "0.4.17"
|
||||
env_logger = "0.10.0"
|
||||
version-compare = "0.1.0"
|
||||
clap = { version = "4.1.1", features = ["derive", "env"] }
|
||||
serde_yaml = "0.9.16"
|
||||
tabled = "0.10.0"
|
||||
build_html = "2.1.0"
|
||||
handlebars = "4.3.1"
|
2
README.md
Normal file
2
README.md
Normal file
@ -0,0 +1,2 @@
|
||||
# Check Da Helm
|
||||
> Your helm releases are outdated, aren't they? Now you can check!
|
14
examples/helmfile.yaml
Normal file
14
examples/helmfile.yaml
Normal file
@ -0,0 +1,14 @@
|
||||
repositories:
|
||||
- name: keel
|
||||
url: https://charts.keel.sh
|
||||
|
||||
releases:
|
||||
# -----------------------------
|
||||
# -- Keel
|
||||
# -----------------------------
|
||||
- name: keel
|
||||
installed: true
|
||||
namespace: keel-system
|
||||
createNamespace: true
|
||||
chart: keel/keel
|
||||
version: 0.9.11
|
115
src/connectors/argo.rs
Normal file
115
src/connectors/argo.rs
Normal file
@ -0,0 +1,115 @@
|
||||
use clap::Arg;
|
||||
use log::{debug, info, error};
|
||||
use serde_json::from_str;
|
||||
use crate::types::{self, HelmRepo};
|
||||
|
||||
use super::Connector;
|
||||
use std::{borrow::Borrow, io::{Result, Error, ErrorKind}, process::Command};
|
||||
|
||||
pub(crate) struct Argo;
|
||||
|
||||
impl Connector for Argo {
|
||||
type ConnectorType = Argo;
|
||||
|
||||
fn get_app(&self) -> Result<Vec<types::HelmChart>> {
|
||||
let cmd: String = "argocd app list -o json | jq '[.[] | {chart: .spec.source.chart, version: .spec.source.targetRevision}]'".to_string();
|
||||
|
||||
debug!("executing '${}'", cmd);
|
||||
let output = Command::new("bash")
|
||||
.arg("-c")
|
||||
.arg(cmd)
|
||||
.output()
|
||||
.expect("argo is failed");
|
||||
let helm_stdout = String::from_utf8_lossy(&output.stdout);
|
||||
|
||||
match from_str::<Vec<types::HelmChart>>(Borrow::borrow(&helm_stdout)) {
|
||||
Ok(mut charts) => {
|
||||
charts.dedup();
|
||||
Ok(charts)
|
||||
}
|
||||
Err(err) => Err(err.into()),
|
||||
}
|
||||
}
|
||||
fn sync_repos(&self) -> Result<()> {
|
||||
info!("syncing helm repos");
|
||||
let cmd: String = "argocd app list -o json | jq '[ .[] | {name: .spec.source.chart, url: .spec.source.repoURL} ]'".to_string();
|
||||
let output = Command::new("bash")
|
||||
.arg("-c")
|
||||
.arg(cmd)
|
||||
.output()
|
||||
.expect("helmfile is failed");
|
||||
info!("{:?}", output.clone());
|
||||
if output.status.success() {
|
||||
let repos: Vec<HelmRepo> = serde_json::from_slice(&output.stdout).unwrap();
|
||||
info!("adding repositories");
|
||||
for repo in repos.iter() {
|
||||
let name = repo.name.clone();
|
||||
if name.is_some() {
|
||||
info!(
|
||||
"syncing {} with the origin {}",
|
||||
name.clone().unwrap(),
|
||||
repo.url
|
||||
);
|
||||
let cmd = format!(
|
||||
"helm repo add {} {}",
|
||||
name.clone().unwrap(),
|
||||
repo.url.clone()
|
||||
);
|
||||
debug!("running {}", cmd);
|
||||
let output = Command::new("bash")
|
||||
.arg("-c")
|
||||
.arg(cmd)
|
||||
.output()
|
||||
.expect("helm repo sync is failed");
|
||||
match output.status.success() {
|
||||
true => {
|
||||
info!(
|
||||
"{} with the origin {} is synced successfully",
|
||||
name.unwrap(),
|
||||
repo.url
|
||||
);
|
||||
}
|
||||
false => {
|
||||
error!(
|
||||
"{} with the origin {} can't be synced",
|
||||
name.unwrap(),
|
||||
repo.url
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let cmd = "helm repo update";
|
||||
let output = Command::new("bash")
|
||||
.arg("-c")
|
||||
.arg(cmd)
|
||||
.output()
|
||||
.expect("helm repo sync is failed");
|
||||
match output.status.success() {
|
||||
true => {
|
||||
info!("repositories are updated successfully");
|
||||
}
|
||||
false => {
|
||||
error!(
|
||||
"repositories can't be updated, {}",
|
||||
String::from_utf8_lossy(&output.stderr)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
} else {
|
||||
Err(Error::new(
|
||||
ErrorKind::Other,
|
||||
String::from_utf8_lossy(&output.stderr),
|
||||
))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
impl Argo{
|
||||
pub(crate) fn init() -> Argo {
|
||||
Argo
|
||||
}
|
||||
}
|
23
src/connectors/helm.rs
Normal file
23
src/connectors/helm.rs
Normal file
@ -0,0 +1,23 @@
|
||||
use crate::types;
|
||||
|
||||
use super::Connector;
|
||||
use std::io::Result;
|
||||
|
||||
pub(crate) struct Helm;
|
||||
|
||||
impl Connector for Helm {
|
||||
fn get_app(&self) -> Result<Vec<types::HelmChart>> {
|
||||
todo!()
|
||||
}
|
||||
fn sync_repos(&self) -> Result<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
type ConnectorType = Helm;
|
||||
}
|
||||
|
||||
impl Helm {
|
||||
pub(crate) fn init() -> Helm {
|
||||
Helm
|
||||
}
|
||||
}
|
53
src/connectors/helmfile.rs
Normal file
53
src/connectors/helmfile.rs
Normal file
@ -0,0 +1,53 @@
|
||||
use log::debug;
|
||||
use serde_json::from_str;
|
||||
|
||||
use crate::types;
|
||||
|
||||
use super::Connector;
|
||||
use std::{borrow::Borrow, fmt::format, io::Result, process::Command};
|
||||
|
||||
pub(crate) struct Helmfile {
|
||||
path: String,
|
||||
}
|
||||
|
||||
impl Connector for Helmfile {
|
||||
fn get_app(&self) -> Result<Vec<types::HelmChart>> {
|
||||
let cmd: String = format!(
|
||||
"helmfile -f {} list --output json | jq '[.[] | {{chart: .name, version: .version}}]'",
|
||||
self.path
|
||||
)
|
||||
.to_string();
|
||||
|
||||
debug!("executing '${}'", cmd);
|
||||
let output = Command::new("bash")
|
||||
.arg("-c")
|
||||
.arg(cmd)
|
||||
.output()
|
||||
.expect("helmfile list is failed");
|
||||
let helm_stdout = String::from_utf8_lossy(&output.stdout);
|
||||
|
||||
match from_str::<Vec<types::HelmChart>>(Borrow::borrow(&helm_stdout)) {
|
||||
Ok(mut charts) => {
|
||||
charts.dedup();
|
||||
Ok(charts)
|
||||
}
|
||||
Err(err) => Err(err.into()),
|
||||
}
|
||||
}
|
||||
fn sync_repos(&self) -> Result<()> {
|
||||
let cmd: String = format!("helmfile -f {} sync", self.path);
|
||||
Command::new("bash")
|
||||
.arg("-c")
|
||||
.arg(cmd)
|
||||
.output()
|
||||
.expect("helmfile sync is failed");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
type ConnectorType = Helmfile;
|
||||
}
|
||||
impl Helmfile {
|
||||
pub(crate) fn init(path: String) -> Self {
|
||||
Self { path: path }
|
||||
}
|
||||
}
|
16
src/connectors/mod.rs
Normal file
16
src/connectors/mod.rs
Normal file
@ -0,0 +1,16 @@
|
||||
mod argo;
|
||||
mod helm;
|
||||
mod helmfile;
|
||||
|
||||
use std::io::Result;
|
||||
use crate::types;
|
||||
|
||||
pub (crate) use self::argo::Argo;
|
||||
pub (crate) use self::helm::Helm;
|
||||
pub (crate) use self::helmfile::Helmfile;
|
||||
|
||||
pub(crate) trait Connector {
|
||||
type ConnectorType;
|
||||
fn get_app(&self) -> Result<Vec<types::HelmChart>>;
|
||||
fn sync_repos(&self) -> Result<()>;
|
||||
}
|
381
src/main.rs
Normal file
381
src/main.rs
Normal file
@ -0,0 +1,381 @@
|
||||
mod connectors;
|
||||
mod types;
|
||||
|
||||
use clap::{Parser, ValueEnum};
|
||||
use connectors::{Argo, Connector, Helm, Helmfile};
|
||||
use handlebars::Handlebars;
|
||||
use log::{debug, error, info, warn};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::from_str;
|
||||
use std::{
|
||||
borrow::Borrow,
|
||||
fmt::{self, format},
|
||||
io::{Error, ErrorKind, Result},
|
||||
process::{exit, Command},
|
||||
};
|
||||
use tabled::Tabled;
|
||||
use version_compare::{Cmp, Version};
|
||||
|
||||
use crate::types::HelmChart;
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)]
|
||||
enum Kinds {
|
||||
Argo,
|
||||
Helm,
|
||||
Helmfile,
|
||||
}
|
||||
|
||||
/// Check you helm releaseas managed by Argo
|
||||
#[derive(Parser)]
|
||||
#[clap(author, version, about, long_about = None)]
|
||||
struct Args {
|
||||
/// Type of the
|
||||
#[clap(long, value_enum)]
|
||||
kind: Kinds,
|
||||
/// Path to the helmfile
|
||||
#[clap(short, long, value_parser, default_value = "./")]
|
||||
path: String,
|
||||
/// Should execution be failed if you have outdated charts
|
||||
#[clap(short, long, action, default_value_t = false, env = "OUTDATED_FAIL")]
|
||||
outdated_fail: bool,
|
||||
/// Set to true if you don't want to sync repositories
|
||||
#[clap(short, long, action, default_value_t = false)]
|
||||
no_sync: bool,
|
||||
}
|
||||
|
||||
/// A struct to write helm repo description to
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
|
||||
struct Repo {
|
||||
name: Option<String>,
|
||||
url: String,
|
||||
}
|
||||
|
||||
/// Struct for parsing charts info from helmfile
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
|
||||
struct LocalCharts {
|
||||
#[serde(alias = "name", alias = "chart")]
|
||||
chart: Option<String>,
|
||||
version: Option<String>,
|
||||
}
|
||||
|
||||
/// Three possible statuses of versions comparison
|
||||
#[derive(Clone, Serialize)]
|
||||
enum Status {
|
||||
Uptodate,
|
||||
Outdated,
|
||||
Missing,
|
||||
}
|
||||
|
||||
impl fmt::Display for Status {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Status::Uptodate => write!(f, "Up-to-date"),
|
||||
Status::Outdated => write!(f, "Outdated"),
|
||||
Status::Missing => write!(f, "Missing"),
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Clone, Tabled, Serialize)]
|
||||
struct ExecResult {
|
||||
name: String,
|
||||
latest_version: String,
|
||||
current_version: String,
|
||||
status: Status,
|
||||
}
|
||||
|
||||
// Implementation for the ExecResult struct
|
||||
impl ExecResult {
|
||||
fn new(name: String, latest_version: String, current_version: String, status: Status) -> Self {
|
||||
Self {
|
||||
name,
|
||||
latest_version,
|
||||
current_version,
|
||||
status,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// Preparations step
|
||||
env_logger::init();
|
||||
let args = Args::parse();
|
||||
let mut result: Vec<ExecResult> = Vec::new();
|
||||
|
||||
let charts = match args.kind {
|
||||
Kinds::Argo => Argo::init().get_app(),
|
||||
Kinds::Helm => Helm::init().get_app(),
|
||||
Kinds::Helmfile => Helmfile::init(args.path.clone()).get_app(),
|
||||
}
|
||||
.unwrap();
|
||||
|
||||
if !args.no_sync {
|
||||
info!("syncing helm repositories");
|
||||
let res = match args.kind {
|
||||
Kinds::Argo => Argo::init().sync_repos(),
|
||||
Kinds::Helm => Helm::init().sync_repos(),
|
||||
Kinds::Helmfile => Helmfile::init(args.path).sync_repos(),
|
||||
};
|
||||
match res {
|
||||
Ok(_) => info!("helm repos are synced"),
|
||||
Err(err) => error!("couldn't sync repos', {}", err),
|
||||
}
|
||||
}
|
||||
|
||||
charts.iter().for_each(|a| {
|
||||
let err = check_chart(&mut result, a);
|
||||
});
|
||||
|
||||
// Parse the helmfile
|
||||
// Handling the result
|
||||
match handle_result(&result, args.outdated_fail) {
|
||||
Ok(result) => {
|
||||
if result {
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
error!("{}", err);
|
||||
exit(1);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
fn check_chart(result: &mut Vec<ExecResult>, local_chart: &types::HelmChart) -> Result<()> {
|
||||
if local_chart.clone().name.is_some() {
|
||||
let version = local_chart.version.clone().unwrap();
|
||||
let chart = local_chart.name.clone().unwrap();
|
||||
return match version.is_empty() {
|
||||
true => {
|
||||
warn!(
|
||||
"version is not specified for the '{}' chart, skipping",
|
||||
chart
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
false => {
|
||||
info!("checking {} - {}", chart, version);
|
||||
let cmd = format!(
|
||||
"helm search repo {}/{} --versions --output json",
|
||||
chart, chart
|
||||
);
|
||||
debug!("executing '${}'", cmd);
|
||||
let output = Command::new("bash")
|
||||
.arg("-c")
|
||||
.arg(cmd)
|
||||
.output()
|
||||
.expect("helmfile is failed");
|
||||
let helm_stdout = String::from_utf8_lossy(&output.stdout);
|
||||
|
||||
// Remove "v" from version definitions
|
||||
let mut versions: Vec<HelmChart> = from_str(helm_stdout.borrow()).unwrap();
|
||||
versions.iter_mut().for_each(|f| {
|
||||
if f.version.is_some() {
|
||||
f.version = Some(f.version.as_ref().unwrap().replace('v', ""));
|
||||
}
|
||||
});
|
||||
// Create a Version from the chart version string
|
||||
let local = Version::from(&version).unwrap();
|
||||
let mut current_version: String = "0.0.0".to_string();
|
||||
|
||||
// Get the latest remote version
|
||||
for v in versions.iter() {
|
||||
current_version = get_newer_version(
|
||||
current_version.clone(),
|
||||
v.version.as_ref().unwrap().clone(),
|
||||
);
|
||||
}
|
||||
let remote = Version::from(current_version.as_str()).unwrap();
|
||||
let status: Status = if versions.contains(&HelmChart {
|
||||
name: Some(format!("{}/{}", chart.clone(), chart.clone())),
|
||||
version: Some(version.clone()),
|
||||
}) {
|
||||
match local.compare(remote.clone()) {
|
||||
Cmp::Lt => Status::Outdated,
|
||||
Cmp::Eq => Status::Uptodate,
|
||||
Cmp::Gt => Status::Missing,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
} else {
|
||||
Status::Missing
|
||||
};
|
||||
|
||||
result.push(ExecResult::new(
|
||||
chart.clone(),
|
||||
current_version.clone(),
|
||||
version.clone(),
|
||||
status,
|
||||
));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
};
|
||||
} else {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
/// Handle result
|
||||
fn handle_result(result: &Vec<ExecResult>, outdated_fail: bool) -> Result<bool> {
|
||||
let mut failed = false;
|
||||
for r in result.clone() {
|
||||
match r.status {
|
||||
Status::Uptodate => info!("{} is up-to-date", r.name),
|
||||
Status::Outdated => {
|
||||
if outdated_fail {
|
||||
failed = true
|
||||
}
|
||||
warn!(
|
||||
"{} is outdated. Current version is {}, but the latest is {}",
|
||||
r.name, r.current_version, r.latest_version
|
||||
);
|
||||
}
|
||||
Status::Missing => {
|
||||
failed = true;
|
||||
error!(
|
||||
"{} is broken. Current version is {}, but it can't be found in the repo",
|
||||
r.name, r.current_version
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
let template = r#"
|
||||
<table>
|
||||
<tr>
|
||||
<th>Chart Name</th>
|
||||
<th>Current Version</th>
|
||||
<th>Latest Version</th>
|
||||
<th>Status</th>
|
||||
</tr>
|
||||
{{#each this as |tr|}}
|
||||
<tr>
|
||||
<th>{{tr.name}}</th>
|
||||
<th>{{tr.current_version}}</th>
|
||||
<th>{{tr.latest_version}}</th>
|
||||
<th>{{tr.status}}</th>
|
||||
</tr>
|
||||
{{/each}}
|
||||
</table>
|
||||
"#;
|
||||
let mut reg = Handlebars::new();
|
||||
|
||||
// TODO: Handle this error
|
||||
reg.register_template_string("html_table", template)
|
||||
.unwrap();
|
||||
|
||||
match reg.render("html_table", &result) {
|
||||
Ok(res) => println!("{}", res),
|
||||
Err(err) => error!("{}", err),
|
||||
};
|
||||
Ok(failed)
|
||||
}
|
||||
|
||||
/// Downloading repos from repositories
|
||||
fn repo_sync() -> Result<()> {
|
||||
info!("syncing helm repos");
|
||||
let cmd: String = "argocd app list -o json | jq '[ .[] | {name: .spec.source.chart, url: .spec.source.repoURL} ]'".to_string();
|
||||
let output = Command::new("bash")
|
||||
.arg("-c")
|
||||
.arg(cmd)
|
||||
.output()
|
||||
.expect("helmfile is failed");
|
||||
info!("{:?}", output.clone());
|
||||
if output.status.success() {
|
||||
let repos: Vec<Repo> = serde_json::from_slice(&output.stdout).unwrap();
|
||||
info!("adding repositories");
|
||||
for repo in repos.iter() {
|
||||
let name = repo.name.clone();
|
||||
if name.is_some() {
|
||||
info!(
|
||||
"syncing {} with the origin {}",
|
||||
name.clone().unwrap(),
|
||||
repo.url
|
||||
);
|
||||
let cmd = format!(
|
||||
"helm repo add {} {}",
|
||||
name.clone().unwrap(),
|
||||
repo.url.clone()
|
||||
);
|
||||
debug!("running {}", cmd);
|
||||
let output = Command::new("bash")
|
||||
.arg("-c")
|
||||
.arg(cmd)
|
||||
.output()
|
||||
.expect("helm repo sync is failed");
|
||||
match output.status.success() {
|
||||
true => {
|
||||
info!(
|
||||
"{} with the origin {} is synced successfully",
|
||||
name.unwrap(),
|
||||
repo.url
|
||||
);
|
||||
}
|
||||
false => {
|
||||
error!(
|
||||
"{} with the origin {} can't be synced",
|
||||
name.unwrap(),
|
||||
repo.url
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let cmd = "helm repo update";
|
||||
let output = Command::new("bash")
|
||||
.arg("-c")
|
||||
.arg(cmd)
|
||||
.output()
|
||||
.expect("helm repo sync is failed");
|
||||
match output.status.success() {
|
||||
true => {
|
||||
info!("repositories are updated successfully");
|
||||
}
|
||||
false => {
|
||||
error!(
|
||||
"repositories can't be updated, {}",
|
||||
String::from_utf8_lossy(&output.stderr)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
} else {
|
||||
Err(Error::new(
|
||||
ErrorKind::Other,
|
||||
String::from_utf8_lossy(&output.stderr),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
/// Run helmfile list and write the result into struct
|
||||
fn parse_argo_apps() -> Result<Vec<LocalCharts>> {
|
||||
let cmd: String = "argocd app list -o json | jq '[.[] | {chart: .spec.source.chart, version: .spec.source.targetRevision}]'".to_string();
|
||||
|
||||
debug!("executing '${}'", cmd);
|
||||
let output = Command::new("bash")
|
||||
.arg("-c")
|
||||
.arg(cmd)
|
||||
.output()
|
||||
.expect("helmfile is failed");
|
||||
let helm_stdout = String::from_utf8_lossy(&output.stdout);
|
||||
|
||||
match from_str::<Vec<LocalCharts>>(Borrow::borrow(&helm_stdout)) {
|
||||
Ok(mut charts) => {
|
||||
charts.dedup();
|
||||
Ok(charts)
|
||||
}
|
||||
Err(err) => Err(err.into()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Takes two version and returns the newer one.
|
||||
fn get_newer_version(v1: String, v2: String) -> String {
|
||||
match Version::from(&v1.replace('v', ""))
|
||||
.unwrap()
|
||||
.compare(Version::from(&v2.replace('v', "")).unwrap().clone())
|
||||
{
|
||||
Cmp::Eq => v1,
|
||||
Cmp::Lt => v2,
|
||||
Cmp::Gt => v1,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
33
src/types/mod.rs
Normal file
33
src/types/mod.rs
Normal file
@ -0,0 +1,33 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
||||
/// Struct for parsing charts info from helmfile
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
|
||||
pub(crate) struct HelmChart {
|
||||
#[serde(alias = "name", alias = "chart")]
|
||||
pub(crate) name: Option<String>,
|
||||
pub(crate) version: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
|
||||
pub(crate) struct HelmRepo {
|
||||
pub(crate) name: Option<String>,
|
||||
pub(crate) url: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize)]
|
||||
enum Status {
|
||||
Uptodate,
|
||||
Outdated,
|
||||
Missing,
|
||||
}
|
||||
|
||||
impl fmt::Display for Status {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Status::Uptodate => write!(f, "Up-to-date"),
|
||||
Status::Outdated => write!(f, "Outdated"),
|
||||
Status::Missing => write!(f, "Missing"),
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user