mirror of
https://github.com/Noratrieb/terustform.git
synced 2026-01-14 16:35:11 +01:00
continue
This commit is contained in:
parent
bac720c512
commit
69daf83c53
7 changed files with 442 additions and 91 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -1 +1,2 @@
|
||||||
/target
|
/target
|
||||||
|
*.tfstate*
|
||||||
|
|
|
||||||
222
Cargo.lock
generated
222
Cargo.lock
generated
|
|
@ -137,6 +137,12 @@ version = "0.21.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
|
checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "base64"
|
||||||
|
version = "0.22.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9475866fec1451be56a3c2400fd081ff546538961565ccb5b7142cbd22bc7a51"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "1.3.2"
|
version = "1.3.2"
|
||||||
|
|
@ -167,6 +173,15 @@ version = "1.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "deranged"
|
||||||
|
version = "0.3.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
|
||||||
|
dependencies = [
|
||||||
|
"powerfmt",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "either"
|
name = "either"
|
||||||
version = "1.10.0"
|
version = "1.10.0"
|
||||||
|
|
@ -427,6 +442,12 @@ version = "1.0.11"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
|
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazy_static"
|
||||||
|
version = "1.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.153"
|
version = "0.2.153"
|
||||||
|
|
@ -499,6 +520,22 @@ version = "0.10.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "defc4c55412d89136f966bbb339008b474350e5e6e78d2714439c386b3137a03"
|
checksum = "defc4c55412d89136f966bbb339008b474350e5e6e78d2714439c386b3137a03"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nu-ansi-term"
|
||||||
|
version = "0.46.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84"
|
||||||
|
dependencies = [
|
||||||
|
"overload",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-conv"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num_cpus"
|
name = "num_cpus"
|
||||||
version = "1.16.0"
|
version = "1.16.0"
|
||||||
|
|
@ -524,6 +561,12 @@ version = "1.19.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "overload"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parking_lot"
|
name = "parking_lot"
|
||||||
version = "0.12.1"
|
version = "0.12.1"
|
||||||
|
|
@ -547,6 +590,16 @@ dependencies = [
|
||||||
"windows-targets 0.48.5",
|
"windows-targets 0.48.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pem"
|
||||||
|
version = "3.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8e459365e590736a54c3fa561947c84837534b8e9af6fc5bf781307e82658fae"
|
||||||
|
dependencies = [
|
||||||
|
"base64 0.22.0",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "percent-encoding"
|
name = "percent-encoding"
|
||||||
version = "2.3.1"
|
version = "2.3.1"
|
||||||
|
|
@ -595,6 +648,12 @@ version = "0.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "powerfmt"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ppv-lite86"
|
name = "ppv-lite86"
|
||||||
version = "0.2.17"
|
version = "0.2.17"
|
||||||
|
|
@ -712,6 +771,19 @@ dependencies = [
|
||||||
"getrandom",
|
"getrandom",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rcgen"
|
||||||
|
version = "0.13.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "54077e1872c46788540de1ea3d7f4ccb1983d12f9aa909b234468676c1a36779"
|
||||||
|
dependencies = [
|
||||||
|
"pem",
|
||||||
|
"ring",
|
||||||
|
"rustls-pki-types",
|
||||||
|
"time",
|
||||||
|
"yasna",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redox_syscall"
|
name = "redox_syscall"
|
||||||
version = "0.4.1"
|
version = "0.4.1"
|
||||||
|
|
@ -784,6 +856,20 @@ dependencies = [
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustls"
|
||||||
|
version = "0.22.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "99008d7ad0bbbea527ec27bddbc0e432c5b87d8175178cee68d2eec9c4a1813c"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
"ring",
|
||||||
|
"rustls-pki-types",
|
||||||
|
"rustls-webpki",
|
||||||
|
"subtle",
|
||||||
|
"zeroize",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls"
|
name = "rustls"
|
||||||
version = "0.23.4"
|
version = "0.23.4"
|
||||||
|
|
@ -799,6 +885,16 @@ dependencies = [
|
||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustls-pemfile"
|
||||||
|
version = "2.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d"
|
||||||
|
dependencies = [
|
||||||
|
"base64 0.22.0",
|
||||||
|
"rustls-pki-types",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls-pki-types"
|
name = "rustls-pki-types"
|
||||||
version = "1.4.1"
|
version = "1.4.1"
|
||||||
|
|
@ -848,6 +944,15 @@ dependencies = [
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sharded-slab"
|
||||||
|
version = "0.1.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"
|
||||||
|
dependencies = [
|
||||||
|
"lazy_static",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "signal-hook-registry"
|
name = "signal-hook-registry"
|
||||||
version = "1.4.1"
|
version = "1.4.1"
|
||||||
|
|
@ -927,14 +1032,50 @@ dependencies = [
|
||||||
name = "terraform-provider-terustform"
|
name = "terraform-provider-terustform"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"base64 0.22.0",
|
||||||
"eyre",
|
"eyre",
|
||||||
"prost",
|
"prost",
|
||||||
"rustls",
|
"rcgen",
|
||||||
|
"rustls 0.23.4",
|
||||||
|
"tempfile",
|
||||||
|
"time",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"tokio-stream",
|
||||||
"tonic",
|
"tonic",
|
||||||
"tonic-build",
|
"tonic-build",
|
||||||
|
"tracing",
|
||||||
|
"tracing-subscriber",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thread_local"
|
||||||
|
version = "1.1.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"once_cell",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time"
|
||||||
|
version = "0.3.35"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ef89ece63debf11bc32d1ed8d078ac870cbeb44da02afb02a9ff135ae7ca0582"
|
||||||
|
dependencies = [
|
||||||
|
"deranged",
|
||||||
|
"num-conv",
|
||||||
|
"powerfmt",
|
||||||
|
"serde",
|
||||||
|
"time-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time-core"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "1.37.0"
|
version = "1.37.0"
|
||||||
|
|
@ -975,6 +1116,17 @@ dependencies = [
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-rustls"
|
||||||
|
version = "0.25.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f"
|
||||||
|
dependencies = [
|
||||||
|
"rustls 0.22.3",
|
||||||
|
"rustls-pki-types",
|
||||||
|
"tokio",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-stream"
|
name = "tokio-stream"
|
||||||
version = "0.1.15"
|
version = "0.1.15"
|
||||||
|
|
@ -1009,7 +1161,7 @@ dependencies = [
|
||||||
"async-stream",
|
"async-stream",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"axum",
|
"axum",
|
||||||
"base64",
|
"base64 0.21.7",
|
||||||
"bytes",
|
"bytes",
|
||||||
"h2",
|
"h2",
|
||||||
"http",
|
"http",
|
||||||
|
|
@ -1019,7 +1171,10 @@ dependencies = [
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"pin-project",
|
"pin-project",
|
||||||
"prost",
|
"prost",
|
||||||
|
"rustls-pemfile",
|
||||||
|
"rustls-pki-types",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"tokio-rustls",
|
||||||
"tokio-stream",
|
"tokio-stream",
|
||||||
"tower",
|
"tower",
|
||||||
"tower-layer",
|
"tower-layer",
|
||||||
|
|
@ -1101,6 +1256,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
|
checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"once_cell",
|
"once_cell",
|
||||||
|
"valuable",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing-log"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
"once_cell",
|
||||||
|
"tracing-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing-subscriber"
|
||||||
|
version = "0.3.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b"
|
||||||
|
dependencies = [
|
||||||
|
"nu-ansi-term",
|
||||||
|
"sharded-slab",
|
||||||
|
"smallvec",
|
||||||
|
"thread_local",
|
||||||
|
"tracing-core",
|
||||||
|
"tracing-log",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1121,6 +1302,12 @@ version = "0.9.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
|
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "valuable"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "want"
|
name = "want"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
|
|
@ -1136,6 +1323,28 @@ version = "0.11.0+wasi-snapshot-preview1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||||
|
|
||||||
|
[[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-x86_64-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-sys"
|
name = "windows-sys"
|
||||||
version = "0.48.0"
|
version = "0.48.0"
|
||||||
|
|
@ -1268,6 +1477,15 @@ version = "0.52.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8"
|
checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "yasna"
|
||||||
|
version = "0.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd"
|
||||||
|
dependencies = [
|
||||||
|
"time",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zeroize"
|
name = "zeroize"
|
||||||
version = "1.7.0"
|
version = "1.7.0"
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,18 @@ version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
base64 = "0.22.0"
|
||||||
eyre = "0.6.12"
|
eyre = "0.6.12"
|
||||||
prost = "0.12.4"
|
prost = "0.12.4"
|
||||||
|
rcgen = "0.13.1"
|
||||||
rustls = { version = "0.23.4", default-features = false, features = ["ring", "logging", "std", "tls12"] }
|
rustls = { version = "0.23.4", default-features = false, features = ["ring", "logging", "std", "tls12"] }
|
||||||
|
tempfile = "3.10.1"
|
||||||
|
time = "0.3.35"
|
||||||
tokio = { version = "1.37.0", features = ["full"] }
|
tokio = { version = "1.37.0", features = ["full"] }
|
||||||
tonic = "0.11.0"
|
tokio-stream = { version = "0.1.15", features = ["net"] }
|
||||||
|
tonic = { version = "0.11.0", features = ["tls"] }
|
||||||
|
tracing = "0.1.40"
|
||||||
|
tracing-subscriber = "0.3.18"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
tonic-build = "0.11.0"
|
tonic-build = "0.11.0"
|
||||||
|
|
|
||||||
29
src/cert.rs
Normal file
29
src/cert.rs
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
use eyre::{Context, Result};
|
||||||
|
use rcgen::{DistinguishedName, DnType, IsCa, KeyUsagePurpose};
|
||||||
|
use time::Duration;
|
||||||
|
|
||||||
|
pub fn generate_cert() -> Result<(tonic::transport::Identity, rcgen::Certificate)> {
|
||||||
|
// https://github.com/hashicorp/go-plugin/blob/8d2aaa458971cba97c3bfec1b0380322e024b514/mtls.go#L20
|
||||||
|
let keypair = rcgen::KeyPair::generate_for(&rcgen::PKCS_ECDSA_P256_SHA256)
|
||||||
|
.wrap_err("failed to generate keypair")?;
|
||||||
|
|
||||||
|
let mut params =
|
||||||
|
rcgen::CertificateParams::new(["localhost".to_owned()]).wrap_err("creating cert params")?;
|
||||||
|
params.key_usages = vec![
|
||||||
|
KeyUsagePurpose::DigitalSignature,
|
||||||
|
KeyUsagePurpose::KeyEncipherment,
|
||||||
|
KeyUsagePurpose::KeyAgreement,
|
||||||
|
KeyUsagePurpose::KeyCertSign,
|
||||||
|
];
|
||||||
|
params.is_ca = IsCa::Ca(rcgen::BasicConstraints::Unconstrained);
|
||||||
|
params.not_before = time::OffsetDateTime::now_utc().saturating_add(Duration::seconds(-30));
|
||||||
|
params.not_after = time::OffsetDateTime::now_utc().saturating_add(Duration::seconds(262980));
|
||||||
|
let mut dn = DistinguishedName::new();
|
||||||
|
dn.push(DnType::OrganizationName, "HashiCorp");
|
||||||
|
dn.push(DnType::CommonName, "localhost");
|
||||||
|
params.distinguished_name = dn;
|
||||||
|
|
||||||
|
let cert = params.self_signed(&keypair).wrap_err("signing cert")?;
|
||||||
|
|
||||||
|
Ok((tonic::transport::Identity::from_pem(cert.pem(), keypair.serialize_pem()), cert))
|
||||||
|
}
|
||||||
75
src/main.rs
75
src/main.rs
|
|
@ -1,18 +1,29 @@
|
||||||
use std::{
|
mod cert;
|
||||||
env,
|
|
||||||
io::Write,
|
|
||||||
net::{IpAddr, Ipv4Addr, SocketAddr},
|
|
||||||
};
|
|
||||||
|
|
||||||
use eyre::{bail, ensure, Context, Result};
|
|
||||||
|
|
||||||
mod server;
|
mod server;
|
||||||
|
|
||||||
|
use std::{env, path::PathBuf};
|
||||||
|
|
||||||
|
use base64::Engine;
|
||||||
|
use eyre::{bail, Context, Result};
|
||||||
|
use tokio::net::UnixListener;
|
||||||
|
use tonic::transport::{Certificate, ServerTlsConfig};
|
||||||
|
use tracing::{info, Level};
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> eyre::Result<()> {
|
async fn main() -> eyre::Result<()> {
|
||||||
let addr = init_handshake();
|
tracing_subscriber::fmt()
|
||||||
|
.with_max_level(Level::DEBUG)
|
||||||
|
.with_writer(std::io::stderr)
|
||||||
|
.without_time()
|
||||||
|
.init();
|
||||||
|
|
||||||
let addr = match addr {
|
let client_cert =
|
||||||
|
std::env::var("PLUGIN_CLIENT_CERT").wrap_err("PLUGIN_CLIENT_CERT not found")?;
|
||||||
|
let client_cert = Certificate::from_pem(client_cert);
|
||||||
|
let (server_identity, server_cert) =
|
||||||
|
cert::generate_cert().wrap_err("generating server certificate")?;
|
||||||
|
|
||||||
|
let (_tmpdir, socket) = match init_handshake(&server_cert).await {
|
||||||
Ok(addr) => addr,
|
Ok(addr) => addr,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
println!("{:?}", err);
|
println!("{:?}", err);
|
||||||
|
|
@ -20,40 +31,58 @@ async fn main() -> eyre::Result<()> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let cert = std::env::var("PLUGIN_CLIENT_CERT").wrap_err("PLUGIN_CLIENT_CERT not found")?;
|
let tls = ServerTlsConfig::new()
|
||||||
|
.identity(server_identity)
|
||||||
|
.client_auth_optional(true) // ??? terraform doesn't send certs ???
|
||||||
|
.client_ca_root(client_cert);
|
||||||
|
|
||||||
|
|
||||||
|
info!("Listening on {}", socket.display());
|
||||||
|
|
||||||
|
let uds = UnixListener::bind(socket).wrap_err("failed to bind unix listener")?;
|
||||||
|
let uds_stream = tokio_stream::wrappers::UnixListenerStream::new(uds);
|
||||||
|
|
||||||
tonic::transport::Server::builder()
|
tonic::transport::Server::builder()
|
||||||
|
.tls_config(tls)
|
||||||
|
.wrap_err("invalid TLS config")?
|
||||||
.add_service(server::tfplugin6::provider_server::ProviderServer::new(
|
.add_service(server::tfplugin6::provider_server::ProviderServer::new(
|
||||||
server::MyProvider,
|
server::MyProvider,
|
||||||
))
|
))
|
||||||
.serve(addr)
|
.serve_with_incoming(uds_stream)
|
||||||
.await
|
.await
|
||||||
.wrap_err("failed to start server")?;
|
.wrap_err("failed to start server")?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init_handshake() -> Result<SocketAddr> {
|
const _MAGIC_COOKIE_KEY: &str = "TF_PLUGIN_MAGIC_COOKIE";
|
||||||
|
const _MAGIC_COOKIE_VALUE: &str =
|
||||||
|
"d602bf8f470bc67ca7faa0386276bbdd4330efaf76d1a219cb4d6991ca9872b2";
|
||||||
|
|
||||||
|
async fn init_handshake(server_cert: &rcgen::Certificate) -> Result<(tempfile::TempDir, PathBuf)> {
|
||||||
// https://github.com/hashicorp/go-plugin/blob/8d2aaa458971cba97c3bfec1b0380322e024b514/docs/internals.md
|
// https://github.com/hashicorp/go-plugin/blob/8d2aaa458971cba97c3bfec1b0380322e024b514/docs/internals.md
|
||||||
|
|
||||||
let min_port = env::var("PLUGIN_MIN_PORT")
|
let _ = env::var("PLUGIN_MIN_PORT")
|
||||||
.wrap_err("PLUGIN_MIN_PORT not found")?
|
.wrap_err("PLUGIN_MIN_PORT not found")?
|
||||||
.parse::<u16>()
|
.parse::<u16>()
|
||||||
.wrap_err("PLUGIN_MIN_PORT not an int")?;
|
.wrap_err("PLUGIN_MIN_PORT not an int")?;
|
||||||
let max_port = env::var("PLUGIN_MAX_PORT")
|
let _ = env::var("PLUGIN_MAX_PORT")
|
||||||
.wrap_err("PLUGIN_MAX_PORT not found")?
|
.wrap_err("PLUGIN_MAX_PORT not found")?
|
||||||
.parse::<u16>()
|
.parse::<u16>()
|
||||||
.wrap_err("PLUGIN_MAX_PORT not an int")?;
|
.wrap_err("PLUGIN_MAX_PORT not an int")?;
|
||||||
|
|
||||||
let port = min_port + 15; // chosen by a d20, lol
|
let tmpdir = tempfile::TempDir::new().wrap_err("failed to create temporary directory")?;
|
||||||
ensure!(port < max_port);
|
let socket = tmpdir.path().join("plugin");
|
||||||
|
|
||||||
let addr = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1));
|
// https://github.com/hashicorp/go-plugin/blob/8d2aaa458971cba97c3bfec1b0380322e024b514/server.go#L426
|
||||||
let addr = SocketAddr::new(addr, port);
|
const CORE_PROTOCOL_VERSION: u8 = 1;
|
||||||
|
const PROTO_VERSION: u8 = 6;
|
||||||
|
let listener_addr_network = "unix";
|
||||||
|
let listener_addr = socket.display();
|
||||||
|
let proto_type = "grpc";
|
||||||
|
let b64_cert = base64::prelude::BASE64_STANDARD_NO_PAD.encode(server_cert.der());
|
||||||
|
|
||||||
const VERSION: u8 = 6;
|
println!("{CORE_PROTOCOL_VERSION}|{PROTO_VERSION}|{listener_addr_network}|{listener_addr}|{proto_type}|{b64_cert}");
|
||||||
|
|
||||||
println!("1|{VERSION}|tcp|{addr}|grpc");
|
Ok((tmpdir, socket))
|
||||||
|
|
||||||
Ok(addr)
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
193
src/server.rs
193
src/server.rs
|
|
@ -1,13 +1,32 @@
|
||||||
|
#![allow(unused_variables, unused_imports)]
|
||||||
|
|
||||||
pub mod tfplugin6 {
|
pub mod tfplugin6 {
|
||||||
tonic::include_proto!("tfplugin6");
|
tonic::include_proto!("tfplugin6");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
use std::{collections::HashMap, vec};
|
||||||
|
|
||||||
use tfplugin6::provider_server::{Provider, ProviderServer};
|
use tfplugin6::provider_server::{Provider, ProviderServer};
|
||||||
use tonic::{transport::Server, Request, Response, Result, Status};
|
use tonic::{transport::Server, Request, Response, Result, Status};
|
||||||
|
use tracing::info;
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct MyProvider;
|
pub struct MyProvider;
|
||||||
|
|
||||||
|
fn empty_schema() -> tfplugin6::Schema {
|
||||||
|
tfplugin6::Schema {
|
||||||
|
version: 1,
|
||||||
|
block: Some(tfplugin6::schema::Block {
|
||||||
|
version: 0,
|
||||||
|
attributes: vec![],
|
||||||
|
block_types: vec![],
|
||||||
|
description: "hello world".to_owned(),
|
||||||
|
description_kind: 0,
|
||||||
|
deprecated: false,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[tonic::async_trait]
|
#[tonic::async_trait]
|
||||||
impl Provider for MyProvider {
|
impl Provider for MyProvider {
|
||||||
/// GetMetadata returns upfront information about server capabilities and
|
/// GetMetadata returns upfront information about server capabilities and
|
||||||
|
|
@ -17,122 +36,166 @@ impl Provider for MyProvider {
|
||||||
/// ignore the error and call the GetProviderSchema RPC as a fallback.
|
/// ignore the error and call the GetProviderSchema RPC as a fallback.
|
||||||
async fn get_metadata(
|
async fn get_metadata(
|
||||||
&self,
|
&self,
|
||||||
request: tonic::Request<tfplugin6::get_metadata::Request>,
|
request: Request<tfplugin6::get_metadata::Request>,
|
||||||
) -> std::result::Result<tonic::Response<tfplugin6::get_metadata::Response>, tonic::Status> {
|
) -> Result<Response<tfplugin6::get_metadata::Response>, Status> {
|
||||||
todo!()
|
Err(Status::unimplemented(
|
||||||
|
"GetMetadata: Not implemeneted".to_owned(),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
/// GetSchema returns schema information for the provider, data resources,
|
/// GetSchema returns schema information for the provider, data resources,
|
||||||
/// and managed resources.
|
/// and managed resources.
|
||||||
async fn get_provider_schema(
|
async fn get_provider_schema(
|
||||||
&self,
|
&self,
|
||||||
request: tonic::Request<tfplugin6::get_provider_schema::Request>,
|
request: Request<tfplugin6::get_provider_schema::Request>,
|
||||||
) -> std::result::Result<tonic::Response<tfplugin6::get_provider_schema::Response>, tonic::Status>
|
) -> Result<Response<tfplugin6::get_provider_schema::Response>, Status> {
|
||||||
{
|
info!("Received get_provider_schema");
|
||||||
todo!()
|
let reply = tfplugin6::get_provider_schema::Response {
|
||||||
|
provider: Some(empty_schema()),
|
||||||
|
provider_meta: Some(empty_schema()),
|
||||||
|
server_capabilities: Some(tfplugin6::ServerCapabilities {
|
||||||
|
plan_destroy: true,
|
||||||
|
get_provider_schema_optional: true,
|
||||||
|
move_resource_state: false,
|
||||||
|
}),
|
||||||
|
data_source_schemas: HashMap::default(),
|
||||||
|
resource_schemas: HashMap::from([("terustform_hello".to_owned(), empty_schema())]),
|
||||||
|
functions: HashMap::default(),
|
||||||
|
diagnostics: vec![],
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(Response::new(reply))
|
||||||
}
|
}
|
||||||
async fn validate_provider_config(
|
async fn validate_provider_config(
|
||||||
&self,
|
&self,
|
||||||
request: tonic::Request<tfplugin6::validate_provider_config::Request>,
|
request: Request<tfplugin6::validate_provider_config::Request>,
|
||||||
) -> std::result::Result<
|
) -> Result<Response<tfplugin6::validate_provider_config::Response>, Status> {
|
||||||
tonic::Response<tfplugin6::validate_provider_config::Response>,
|
tracing::info!("validate_provider_config");
|
||||||
tonic::Status,
|
|
||||||
> {
|
let reply = tfplugin6::validate_provider_config::Response {
|
||||||
todo!()
|
diagnostics: vec![],
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(Response::new(reply))
|
||||||
}
|
}
|
||||||
async fn validate_resource_config(
|
async fn validate_resource_config(
|
||||||
&self,
|
&self,
|
||||||
request: tonic::Request<tfplugin6::validate_resource_config::Request>,
|
request: Request<tfplugin6::validate_resource_config::Request>,
|
||||||
) -> std::result::Result<
|
) -> Result<Response<tfplugin6::validate_resource_config::Response>, Status> {
|
||||||
tonic::Response<tfplugin6::validate_resource_config::Response>,
|
tracing::info!("validate_resource_config");
|
||||||
tonic::Status,
|
|
||||||
> {
|
let reply = tfplugin6::validate_resource_config::Response {
|
||||||
todo!()
|
diagnostics: vec![],
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(Response::new(reply))
|
||||||
}
|
}
|
||||||
async fn validate_data_resource_config(
|
async fn validate_data_resource_config(
|
||||||
&self,
|
&self,
|
||||||
request: tonic::Request<tfplugin6::validate_data_resource_config::Request>,
|
request: Request<tfplugin6::validate_data_resource_config::Request>,
|
||||||
) -> std::result::Result<
|
) -> Result<Response<tfplugin6::validate_data_resource_config::Response>, Status> {
|
||||||
tonic::Response<tfplugin6::validate_data_resource_config::Response>,
|
tracing::error!("validate_data_resource_config");
|
||||||
tonic::Status,
|
todo!("validate_data_resource_config")
|
||||||
> {
|
|
||||||
todo!()
|
|
||||||
}
|
}
|
||||||
async fn upgrade_resource_state(
|
async fn upgrade_resource_state(
|
||||||
&self,
|
&self,
|
||||||
request: tonic::Request<tfplugin6::upgrade_resource_state::Request>,
|
request: Request<tfplugin6::upgrade_resource_state::Request>,
|
||||||
) -> std::result::Result<tonic::Response<tfplugin6::upgrade_resource_state::Response>, tonic::Status>
|
) -> Result<Response<tfplugin6::upgrade_resource_state::Response>, Status> {
|
||||||
{
|
tracing::error!("upgrade_resource_state");
|
||||||
todo!()
|
todo!("upgrade_resource_state")
|
||||||
}
|
}
|
||||||
/// ////// One-time initialization, called before other functions below
|
/// ////// One-time initialization, called before other functions below
|
||||||
async fn configure_provider(
|
async fn configure_provider(
|
||||||
&self,
|
&self,
|
||||||
request: tonic::Request<tfplugin6::configure_provider::Request>,
|
request: Request<tfplugin6::configure_provider::Request>,
|
||||||
) -> std::result::Result<tonic::Response<tfplugin6::configure_provider::Response>, tonic::Status>
|
) -> Result<Response<tfplugin6::configure_provider::Response>, Status> {
|
||||||
{
|
tracing::info!("configure_provider");
|
||||||
todo!()
|
let reply = tfplugin6::configure_provider::Response {
|
||||||
|
diagnostics: vec![],
|
||||||
|
};
|
||||||
|
Ok(Response::new(reply))
|
||||||
}
|
}
|
||||||
/// ////// Managed Resource Lifecycle
|
/// ////// Managed Resource Lifecycle
|
||||||
async fn read_resource(
|
async fn read_resource(
|
||||||
&self,
|
&self,
|
||||||
request: tonic::Request<tfplugin6::read_resource::Request>,
|
request: Request<tfplugin6::read_resource::Request>,
|
||||||
) -> std::result::Result<tonic::Response<tfplugin6::read_resource::Response>, tonic::Status> {
|
) -> Result<Response<tfplugin6::read_resource::Response>, Status> {
|
||||||
todo!()
|
tracing::error!("read_resource");
|
||||||
|
todo!("read_resource")
|
||||||
}
|
}
|
||||||
async fn plan_resource_change(
|
async fn plan_resource_change(
|
||||||
&self,
|
&self,
|
||||||
request: tonic::Request<tfplugin6::plan_resource_change::Request>,
|
request: Request<tfplugin6::plan_resource_change::Request>,
|
||||||
) -> std::result::Result<tonic::Response<tfplugin6::plan_resource_change::Response>, tonic::Status>
|
) -> Result<Response<tfplugin6::plan_resource_change::Response>, Status> {
|
||||||
{
|
tracing::error!("plan_resource_change");
|
||||||
todo!()
|
|
||||||
|
let reply = tfplugin6::plan_resource_change::Response {
|
||||||
|
planned_state: todo!(),
|
||||||
|
requires_replace: vec![],
|
||||||
|
planned_private: vec![],
|
||||||
|
diagnostics: vec![],
|
||||||
|
legacy_type_system: false,
|
||||||
|
deferred: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
todo!("plan_resource_change")
|
||||||
}
|
}
|
||||||
async fn apply_resource_change(
|
async fn apply_resource_change(
|
||||||
&self,
|
&self,
|
||||||
request: tonic::Request<tfplugin6::apply_resource_change::Request>,
|
request: Request<tfplugin6::apply_resource_change::Request>,
|
||||||
) -> std::result::Result<tonic::Response<tfplugin6::apply_resource_change::Response>, tonic::Status>
|
) -> Result<Response<tfplugin6::apply_resource_change::Response>, Status> {
|
||||||
{
|
tracing::error!("apply_resource_change");
|
||||||
todo!()
|
|
||||||
|
todo!("apply_resource_change")
|
||||||
}
|
}
|
||||||
async fn import_resource_state(
|
async fn import_resource_state(
|
||||||
&self,
|
&self,
|
||||||
request: tonic::Request<tfplugin6::import_resource_state::Request>,
|
request: Request<tfplugin6::import_resource_state::Request>,
|
||||||
) -> std::result::Result<tonic::Response<tfplugin6::import_resource_state::Response>, tonic::Status>
|
) -> Result<Response<tfplugin6::import_resource_state::Response>, Status> {
|
||||||
{
|
tracing::error!("import_resource_state");
|
||||||
todo!()
|
|
||||||
|
todo!("import_resource_state")
|
||||||
}
|
}
|
||||||
async fn move_resource_state(
|
async fn move_resource_state(
|
||||||
&self,
|
&self,
|
||||||
request: tonic::Request<tfplugin6::move_resource_state::Request>,
|
request: Request<tfplugin6::move_resource_state::Request>,
|
||||||
) -> std::result::Result<tonic::Response<tfplugin6::move_resource_state::Response>, tonic::Status>
|
) -> Result<Response<tfplugin6::move_resource_state::Response>, Status> {
|
||||||
{
|
tracing::error!("move_resource_state");
|
||||||
todo!()
|
|
||||||
|
todo!("move_resource_state")
|
||||||
}
|
}
|
||||||
async fn read_data_source(
|
async fn read_data_source(
|
||||||
&self,
|
&self,
|
||||||
request: tonic::Request<tfplugin6::read_data_source::Request>,
|
request: Request<tfplugin6::read_data_source::Request>,
|
||||||
) -> std::result::Result<tonic::Response<tfplugin6::read_data_source::Response>, tonic::Status>
|
) -> Result<Response<tfplugin6::read_data_source::Response>, Status> {
|
||||||
{
|
tracing::error!("read_data_source");
|
||||||
todo!()
|
|
||||||
|
todo!("read_data_source")
|
||||||
}
|
}
|
||||||
/// GetFunctions returns the definitions of all functions.
|
/// GetFunctions returns the definitions of all functions.
|
||||||
async fn get_functions(
|
async fn get_functions(
|
||||||
&self,
|
&self,
|
||||||
request: tonic::Request<tfplugin6::get_functions::Request>,
|
request: Request<tfplugin6::get_functions::Request>,
|
||||||
) -> std::result::Result<tonic::Response<tfplugin6::get_functions::Response>, tonic::Status> {
|
) -> Result<Response<tfplugin6::get_functions::Response>, Status> {
|
||||||
todo!()
|
tracing::error!("get_functions");
|
||||||
|
|
||||||
|
todo!("get_functions")
|
||||||
}
|
}
|
||||||
/// ////// Provider-contributed Functions
|
/// ////// Provider-contributed Functions
|
||||||
async fn call_function(
|
async fn call_function(
|
||||||
&self,
|
&self,
|
||||||
request: tonic::Request<tfplugin6::call_function::Request>,
|
request: Request<tfplugin6::call_function::Request>,
|
||||||
) -> std::result::Result<tonic::Response<tfplugin6::call_function::Response>, tonic::Status> {
|
) -> Result<Response<tfplugin6::call_function::Response>, Status> {
|
||||||
todo!()
|
tracing::error!("call_function");
|
||||||
|
|
||||||
|
todo!("call_function")
|
||||||
}
|
}
|
||||||
/// ////// Graceful Shutdown
|
/// ////// Graceful Shutdown
|
||||||
async fn stop_provider(
|
async fn stop_provider(
|
||||||
&self,
|
&self,
|
||||||
request: tonic::Request<tfplugin6::stop_provider::Request>,
|
request: Request<tfplugin6::stop_provider::Request>,
|
||||||
) -> std::result::Result<tonic::Response<tfplugin6::stop_provider::Response>, tonic::Status> {
|
) -> Result<Response<tfplugin6::stop_provider::Response>, Status> {
|
||||||
todo!()
|
tracing::error!("stop_provider");
|
||||||
|
|
||||||
|
todo!("stop_provider")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,3 +5,7 @@ terraform {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
provider "terustform" {}
|
||||||
|
|
||||||
|
resource "terustform_hello" "test1" {}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue