mirror of
https://github.com/ruvnet/RuVector.git
synced 2026-05-30 12:13:34 +00:00
sec(hailo): expose --tls-ca / mTLS flags on the embed CLI (iter 188)
Symmetric with iter-187 bench plumbing — adds the same TLS knobs to
`ruvector-hailo-embed` so ops can drive a one-shot embed against a
TLS-configured worker without having to build a custom client. All
flags `#[cfg(feature = "tls")]` so the no-tls build stays clean.
Same partial-config + orphan-flag refusals as iter-187:
- --tls-domain / --tls-client-cert / --tls-client-key without
--tls-ca → loud error
- --tls-client-cert without --tls-client-key (or vice versa) →
loud error
- missing CA file → fs error surfaced with full path
Smoke-tested on the workstation:
$ ruvector-hailo-embed --workers 100.77.59.83:50051 --tls-domain example.com --text hello
Error: "--tls-domain / --tls-client-cert / --tls-client-key require --tls-ca"
$ ruvector-hailo-embed --workers 100.77.59.83:50051 --tls-ca /nonexistent/ca.pem --text hello
Error: "--tls-ca: transport error to <tls>: read ca pem at /nonexistent/ca.pem: No such file or directory (os error 2)"
$ ruvector-hailo-embed --workers 100.77.59.83:50051 --text "iter 188 smoke test"
{"text":"iter 188 smoke test","dim":384,"latency_us":433538,"vec_head":[...]}
Pi plaintext bench regression (c=4 b=1, 8 s × 3):
iter-187: 68.5, 68.7, 66.7 → mean 68.0/sec, p50=56-59 ms
iter-188: 70.3, 69.0, 67.9 → mean 69.1/sec, p50=55-57 ms
Δ throughput: +1.6% (within tailnet noise; embed CLI changes don't
touch the bench code path)
The TLS server-side path is now fully callable from both client tools
in this repo. Pi-side cert generation + systemd unit wiring (the
actual end-to-end TLS smoke against cognitum-v0) remains the deferred
ops follow-up.
Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
parent
840d276592
commit
168051bc1e
1 changed files with 81 additions and 0 deletions
|
|
@ -69,6 +69,18 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
// texts are embedded in order and the binary exits. Repeat the
|
||||
// flag to embed multiple texts in one invocation.
|
||||
let mut inline_texts: Vec<String> = Vec::new();
|
||||
// Iter 188 — symmetric TLS plumbing (mirror of iter-187 bench
|
||||
// additions). Lets ops drive a single embed against a TLS-enabled
|
||||
// worker without building a custom client. All flags
|
||||
// `#[cfg(feature = "tls")]` so the no-tls build is unchanged.
|
||||
#[cfg(feature = "tls")]
|
||||
let mut tls_ca: Option<String> = None;
|
||||
#[cfg(feature = "tls")]
|
||||
let mut tls_domain: Option<String> = None;
|
||||
#[cfg(feature = "tls")]
|
||||
let mut tls_client_cert: Option<String> = None;
|
||||
#[cfg(feature = "tls")]
|
||||
let mut tls_client_key: Option<String> = None;
|
||||
|
||||
let mut i = 1;
|
||||
while i < args.len() {
|
||||
|
|
@ -130,6 +142,14 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
}
|
||||
i += 2;
|
||||
}
|
||||
#[cfg(feature = "tls")]
|
||||
"--tls-ca" => { tls_ca = args.get(i + 1).cloned(); i += 2; }
|
||||
#[cfg(feature = "tls")]
|
||||
"--tls-domain" => { tls_domain = args.get(i + 1).cloned(); i += 2; }
|
||||
#[cfg(feature = "tls")]
|
||||
"--tls-client-cert" => { tls_client_cert = args.get(i + 1).cloned(); i += 2; }
|
||||
#[cfg(feature = "tls")]
|
||||
"--tls-client-key" => { tls_client_key = args.get(i + 1).cloned(); i += 2; }
|
||||
"--help" | "-h" => { print_help(); return Ok(()); }
|
||||
"--version" | "-V" => {
|
||||
println!("{} {}", env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION"));
|
||||
|
|
@ -194,6 +214,55 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
}
|
||||
}
|
||||
|
||||
// Iter 188 — TLS transport when --tls-ca is set; mirrors iter-187
|
||||
// bench plumbing. Same partial-config + orphan-flag refusals so a
|
||||
// misconfigured invocation surfaces an early error instead of a
|
||||
// silent plaintext downgrade.
|
||||
#[cfg(feature = "tls")]
|
||||
let transport: Arc<dyn ruvector_hailo_cluster::transport::EmbeddingTransport + Send + Sync> = {
|
||||
if let Some(ca_path) = tls_ca.as_deref() {
|
||||
let addr0 = workers.first().map(|w| w.address.clone()).unwrap_or_default();
|
||||
let domain = tls_domain.clone().unwrap_or_else(|| {
|
||||
ruvector_hailo_cluster::tls::domain_from_address(&addr0).to_string()
|
||||
});
|
||||
let mut tls = ruvector_hailo_cluster::tls::TlsClient::from_pem_files(ca_path, &domain)
|
||||
.map_err(|e| format!("--tls-ca: {}", e))?;
|
||||
match (tls_client_cert.as_deref(), tls_client_key.as_deref()) {
|
||||
(Some(c), Some(k)) => {
|
||||
tls = tls.with_client_identity(c, k)
|
||||
.map_err(|e| format!("--tls-client-cert/--tls-client-key: {}", e))?;
|
||||
if !quiet {
|
||||
eprintln!("ruvector-hailo-embed: mTLS client identity attached");
|
||||
}
|
||||
}
|
||||
(Some(_), None) | (None, Some(_)) => {
|
||||
return Err(
|
||||
"--tls-client-cert and --tls-client-key must both be set or both unset".into(),
|
||||
);
|
||||
}
|
||||
(None, None) => {}
|
||||
}
|
||||
if !quiet {
|
||||
eprintln!(
|
||||
"ruvector-hailo-embed: TLS enabled ca={} domain={}",
|
||||
ca_path, domain
|
||||
);
|
||||
}
|
||||
Arc::new(GrpcTransport::with_tls(
|
||||
std::time::Duration::from_secs(5),
|
||||
std::time::Duration::from_secs(2),
|
||||
tls,
|
||||
)?)
|
||||
} else {
|
||||
if tls_domain.is_some() || tls_client_cert.is_some() || tls_client_key.is_some() {
|
||||
return Err(
|
||||
"--tls-domain / --tls-client-cert / --tls-client-key require --tls-ca".into(),
|
||||
);
|
||||
}
|
||||
Arc::new(GrpcTransport::new()?)
|
||||
}
|
||||
};
|
||||
#[cfg(not(feature = "tls"))]
|
||||
let transport: Arc<dyn ruvector_hailo_cluster::transport::EmbeddingTransport + Send + Sync> =
|
||||
Arc::new(GrpcTransport::new()?);
|
||||
|
||||
|
|
@ -601,6 +670,18 @@ OPTIONS:
|
|||
text and exit (skips stdin). Repeat
|
||||
the flag to embed multiple texts
|
||||
in one invocation.
|
||||
--tls-ca <path> Enable HTTPS by trusting the PEM CA
|
||||
bundle at <path>. Without this the
|
||||
embed CLI dials plaintext gRPC.
|
||||
(Requires --features tls.)
|
||||
--tls-domain <name> SNI / SAN value to assert against the
|
||||
server cert. Defaults to the hostname
|
||||
half of the first worker address.
|
||||
--tls-client-cert <path> mTLS client cert (PEM). Pair with
|
||||
--tls-client-key.
|
||||
--tls-client-key <path> mTLS client private key (PEM). Both
|
||||
cert and key must be set or both
|
||||
unset.
|
||||
--help, -h Print this help and exit.
|
||||
--version, -V Print the binary name + version and exit.
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue