Initial Commit
This commit is contained in:
commit
a48db9c4c8
5 changed files with 520 additions and 0 deletions
16
Cargo.toml
Normal file
16
Cargo.toml
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
[package]
|
||||||
|
name = "openmetrics-vici-exporter"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
config = { version = "0.13.1", features = ["yaml"] }
|
||||||
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
prometheus-client = "0.18.1"
|
||||||
|
futures-util = "0.3.25"
|
||||||
|
actix-web-httpauth = "0.8.0"
|
||||||
|
actix-web = "4.2.1"
|
||||||
|
tokio = "1.21.2"
|
||||||
|
rsvici = "0.1"
|
4
README.md
Normal file
4
README.md
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
`groupadd vici`
|
||||||
|
`chown root:vici /var/run/charon.vici`
|
||||||
|
`chmod 0770 /var/run/charon.vici`
|
||||||
|
`usermod -aG vici $user`
|
5
config.yml
Normal file
5
config.yml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
vici_socket: "/var/run/charon.vici"
|
||||||
|
actix_bind_addr: "0.0.0.0"
|
||||||
|
actix_bind_port: "80"
|
||||||
|
actix_auth_token: ""
|
122
src/main.rs
Normal file
122
src/main.rs
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
#![allow(dead_code,non_camel_case_types)] // I don't want to be bothered for case stuff decided upon me by the VICI API
|
||||||
|
|
||||||
|
use actix_web::{web, App, HttpResponse, HttpServer, Responder, Result};
|
||||||
|
|
||||||
|
use prometheus_client::{
|
||||||
|
registry::Registry,
|
||||||
|
encoding::{text::encode},
|
||||||
|
metrics::{
|
||||||
|
family::Family,
|
||||||
|
info::Info,
|
||||||
|
counter::Counter,
|
||||||
|
gauge::Gauge,
|
||||||
|
MetricType::Unknown,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
use std::{
|
||||||
|
collections::HashMap,
|
||||||
|
error::Error,
|
||||||
|
sync::Mutex,
|
||||||
|
net::IpAddr,
|
||||||
|
path::Path,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
use futures_util::{
|
||||||
|
stream::{TryStreamExt},
|
||||||
|
pin_mut,
|
||||||
|
};
|
||||||
|
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
use config::Config;
|
||||||
|
|
||||||
|
mod vici_structs;
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct Configuration {
|
||||||
|
vici_socket: String,
|
||||||
|
actix_bind_addr: IpAddr,
|
||||||
|
actix_bind_port: u16,
|
||||||
|
axtix_auth_token: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn metrics_handler(state: web::Data<Mutex<AppState>>) -> Result<HttpResponse> {
|
||||||
|
let state = state.lock().unwrap();
|
||||||
|
let mut buf = Vec::new();
|
||||||
|
encode(&mut buf, &state.registry)?;
|
||||||
|
let body = std::str::from_utf8(buf.as_slice()).unwrap().to_string();
|
||||||
|
Ok(HttpResponse::Ok()
|
||||||
|
.content_type("application/openmetrics-text; version=1.0.0; charset=utf-8")
|
||||||
|
.body(body))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct AppState {
|
||||||
|
pub registry: Registry,
|
||||||
|
pub vici: vici_structs::VICIState,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Metrics {
|
||||||
|
sa_uptime: Family<vici_structs::SecurityAssociationLabels, Counter>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Metrics {
|
||||||
|
pub fn sa_uptime(&self, security_associations: vici_structs::SecurityAssociations) {
|
||||||
|
for (sa_name, sa_values) in security_associations.into_iter() {
|
||||||
|
self.sa_uptime.get_or_create(&vici_structs::SecurityAssociationLabels{uniqueid: sa_values.uniqueid}).inner(sa_values.established); // "Vertrau mir Bruder"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
pub fn get_vici_state(client: rsvici::Client) -> Result<vici_structs::VICIState, actix_web::Error>{
|
||||||
|
let version: vici_structs::Version = client.request("version", ()).await?;
|
||||||
|
let statistics: vici_structs::Statistics = client.request("statistics", ()).await?;
|
||||||
|
let connections = client.stream_request::<(), vici_structs::Connections>("list-connections", "list-conn", ());
|
||||||
|
pin_mut!(connections);
|
||||||
|
while let Some(conn) = connections.try_next().await? {
|
||||||
|
println!("{:#?}", conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#[actix_web::main]
|
||||||
|
async fn main() -> std::io::Result<()> {
|
||||||
|
let settings = Config::builder()
|
||||||
|
.add_source(config::File::with_name("config"))
|
||||||
|
.add_source(config::Environment::with_prefix("VICI_EXPORTER"))
|
||||||
|
.build()
|
||||||
|
.unwrap();
|
||||||
|
let mut conf: Configuration = settings.try_deserialize().unwrap();
|
||||||
|
let mut client = rsvici::unix::connect(conf.vici_socket).await?;
|
||||||
|
let mut vici_state: vici_structs::VICIState;
|
||||||
|
|
||||||
|
let metrics = web::Data::new(Metrics {
|
||||||
|
sa_uptime: Family::default(),
|
||||||
|
});
|
||||||
|
|
||||||
|
let mut state = AppState {
|
||||||
|
registry: Registry::default(),
|
||||||
|
vici: vici_structs::VICIState.update(client),
|
||||||
|
};
|
||||||
|
|
||||||
|
state.registry.register(
|
||||||
|
"sa_uptime",
|
||||||
|
"How Long a connection has been established",
|
||||||
|
Box::new(metrics.sa_uptime.clone()),
|
||||||
|
);
|
||||||
|
let state = web::Data::new(Mutex::new(state));
|
||||||
|
|
||||||
|
HttpServer::new(move || {
|
||||||
|
App::new()
|
||||||
|
//.app_data(metrics.clone())
|
||||||
|
.app_data(state.clone())
|
||||||
|
.service(web::resource("/metrics").route(web::get().to(metrics_handler)))
|
||||||
|
})
|
||||||
|
.bind((conf.actix_bind_addr, conf.actix_bind_port))?
|
||||||
|
.run()
|
||||||
|
.await
|
||||||
|
}
|
373
src/vici_structs.rs
Normal file
373
src/vici_structs.rs
Normal file
|
@ -0,0 +1,373 @@
|
||||||
|
#![allow(dead_code,non_camel_case_types)] // I don't want to be bothered for case stuff decided upon me by the VICI API
|
||||||
|
|
||||||
|
use serde::Deserialize;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use prometheus_client::{
|
||||||
|
encoding::text::Encode,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub struct VICIState {
|
||||||
|
pub version: Version,
|
||||||
|
pub statistics: Statistics,
|
||||||
|
pub policies: Policies,
|
||||||
|
pub connections: Connections,
|
||||||
|
pub security_associations: SecurityAssociations,
|
||||||
|
pub certificates: Certificates,
|
||||||
|
pub authorities: Authorities,
|
||||||
|
pub pools: Pools,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E> VICIState {
|
||||||
|
async fn update(client: rsvici::Client) -> Result<VICIState, E> {
|
||||||
|
VICIState {
|
||||||
|
version: client.request("version", ()).await?,
|
||||||
|
statistics: client.request("statistics", ()).await?,
|
||||||
|
policies: client.stream_request::<(), Policies>("list-policies", "list-policy", ()).await?,
|
||||||
|
connections: client.stream_request::<(), Connections>("list-connections", "list-conn", ()).await?,
|
||||||
|
security_associations: client.stream_request::<(), SecurityAssociations>("list-sas", "list-sa", ()).await?,
|
||||||
|
certificates: client.stream_request::<(), Certificates>("list-certs", "list-cert", ()).await?,
|
||||||
|
authorities: client.stream_request::<(), Authorities>("list-authoroties", "list-authoroty", ()).await?,
|
||||||
|
pools: client.stream_request::<(), Pools>("list-pools", "list-pool", ()).await?,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Structs for parsing the control interface
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub struct Version {
|
||||||
|
pub daemon: String,
|
||||||
|
pub version: String,
|
||||||
|
pub sysname: String,
|
||||||
|
pub release: String,
|
||||||
|
pub machine: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub struct Statistics {
|
||||||
|
pub uptime: StatisticsUptime,
|
||||||
|
pub workers: StatisticsWorkers,
|
||||||
|
pub queues: StatisticsJobPriorities,
|
||||||
|
pub scheduled: String,
|
||||||
|
pub ikesecurity_associations: StatisticsIKESecurityAssociations,
|
||||||
|
pub plugins: Vec<String>,
|
||||||
|
pub mem: Option<StatisticsMem>,
|
||||||
|
pub mallinfo: Option<StatisticsMallinfo>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub struct StatisticsUptime {
|
||||||
|
pub running: String,
|
||||||
|
pub since: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub struct StatisticsWorkers {
|
||||||
|
pub total: String,
|
||||||
|
pub idle: String,
|
||||||
|
pub active: StatisticsJobPriorities,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub struct StatisticsJobPriorities {
|
||||||
|
pub critical: String,
|
||||||
|
pub high: String,
|
||||||
|
pub medium: String,
|
||||||
|
pub low: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub struct StatisticsIKESecurityAssociations {
|
||||||
|
pub total: String,
|
||||||
|
pub half_open: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub struct StatisticsMem {
|
||||||
|
pub total: String,
|
||||||
|
pub allocs: String,
|
||||||
|
}
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub struct StatisticsMallinfo {
|
||||||
|
pub sbrk: String,
|
||||||
|
pub mmap: String,
|
||||||
|
pub used: String,
|
||||||
|
pub free: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type Policies = HashMap<String, Policy>;
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub struct Policy {
|
||||||
|
pub child: String,
|
||||||
|
pub ike: Option<String>,
|
||||||
|
pub mode: PolicyMode,
|
||||||
|
pub local_ts: Option<Vec<String>>,
|
||||||
|
pub remote_ts: Option<Vec<String>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
enum PolicyMode {
|
||||||
|
tunnel,
|
||||||
|
transport,
|
||||||
|
pass,
|
||||||
|
drop,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type Connections = HashMap<String, Conn>;
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub struct Conn {
|
||||||
|
pub local_addrs: Vec<String>,
|
||||||
|
pub remote_addrs: Vec<String>,
|
||||||
|
pub version: String,
|
||||||
|
pub reauth_time: u32,
|
||||||
|
pub rekey_time: u32,
|
||||||
|
pub children: HashMap<String, ConnChildSection>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub struct ConnAuthSection {
|
||||||
|
pub class: String,
|
||||||
|
pub eap_type: Option<String>,
|
||||||
|
pub eap_vendor: Option<String>,
|
||||||
|
pub xauth: Option<String>,
|
||||||
|
pub revocation: Option<String>,
|
||||||
|
pub id: String,
|
||||||
|
pub aaa_id: Option<String>,
|
||||||
|
pub eap_id: Option<String>,
|
||||||
|
pub xauth_id: Option<String>,
|
||||||
|
pub groups: Option<Vec<String>>,
|
||||||
|
pub certificates: Option<Vec<String>>,
|
||||||
|
pub cacerts: Option<Vec<String>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub struct ConnChildSection {
|
||||||
|
pub mode: ChildSecurityAssociationMode,
|
||||||
|
pub rekey_time: u32,
|
||||||
|
pub rekey_bytes: u64,
|
||||||
|
pub rekey_packets: u64,
|
||||||
|
pub local_ts: Option<Vec<String>>,
|
||||||
|
pub remote_ts: Option<Vec<String>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Clone, Hash, PartialEq, Eq)]
|
||||||
|
enum ChildSecurityAssociationMode {
|
||||||
|
TUNNEL,
|
||||||
|
TRANSPORT,
|
||||||
|
BEET,
|
||||||
|
}
|
||||||
|
#[derive(Debug, Deserialize, Clone, Hash, PartialEq, Eq)]
|
||||||
|
enum ChildSecurityAssociationProtocol {
|
||||||
|
AH,
|
||||||
|
ESP,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type SecurityAssociations = HashMap<String, SecurityAssociation>;
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
#[serde(rename_all = "kebab-case")]
|
||||||
|
pub struct SecurityAssociation {
|
||||||
|
pub uniqueid: String,
|
||||||
|
pub version: u8,
|
||||||
|
pub state: String,
|
||||||
|
pub local_host: Option<String>,
|
||||||
|
pub local_port: Option<u16>,
|
||||||
|
pub local_id: Option<String>,
|
||||||
|
pub remote_host: Option<String>,
|
||||||
|
pub remote_port: Option<u16>,
|
||||||
|
pub remote_id: Option<String>,
|
||||||
|
pub remote_xauth_id: Option<String>,
|
||||||
|
pub remote_epa_id: Option<String>,
|
||||||
|
pub initiator: Option<bool>,
|
||||||
|
pub initiator_spi: Option<String>,
|
||||||
|
pub responder_spi: Option<String>,
|
||||||
|
pub nat_local: Option<bool>,
|
||||||
|
pub nat_remote: Option<bool>,
|
||||||
|
pub nat_fake: Option<bool>,
|
||||||
|
pub nat_any: Option<bool>,
|
||||||
|
pub if_id_in: Option<String>,
|
||||||
|
pub if_id_out: Option<String>,
|
||||||
|
pub encr_alg: Option<String>,
|
||||||
|
pub encr_keysize: Option<String>,
|
||||||
|
pub integ_alg: Option<String>,
|
||||||
|
pub integ_keysize: Option<String>,
|
||||||
|
pub prf_alg: Option<String>,
|
||||||
|
pub dh_group: Option<String>,
|
||||||
|
pub established: u64,
|
||||||
|
pub rekey_time: Option<u32>,
|
||||||
|
pub reauth_time: Option<u32>,
|
||||||
|
pub local_vips: Option<Vec<String>>,
|
||||||
|
pub remote_vips: Option<Vec<String>>,
|
||||||
|
pub tasks_queued: Option<Vec<String>>,
|
||||||
|
pub tasks_active: Option<Vec<String>>,
|
||||||
|
pub tasks_passive: Option<Vec<String>>,
|
||||||
|
pub child_security_associations: Option<HashMap<String, SecurityAssociationChild>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
#[serde(rename_all = "kebab-case")]
|
||||||
|
pub struct SecurityAssociationChild {
|
||||||
|
pub name: String,
|
||||||
|
pub uniqueid: String,
|
||||||
|
pub reqid: String,
|
||||||
|
pub state: String,
|
||||||
|
pub mode: ChildSecurityAssociationMode,
|
||||||
|
pub protocol: ChildSecurityAssociationProtocol,
|
||||||
|
pub encap: Option<bool>,
|
||||||
|
pub spi_in: String,
|
||||||
|
pub spi_out: String,
|
||||||
|
pub cpi_in: Option<String>,
|
||||||
|
pub cpi_out: Option<String>,
|
||||||
|
pub mark_in: Option<String>,
|
||||||
|
pub mark_mask_in: Option<String>,
|
||||||
|
pub mark_out: Option<String>,
|
||||||
|
pub mark_mask_out: Option<String>,
|
||||||
|
pub if_id_in: Option<String>,
|
||||||
|
pub if_id_out: Option<String>,
|
||||||
|
pub encr_alg: Option<String>,
|
||||||
|
pub encr_keysize: Option<String>,
|
||||||
|
pub integ_alg: Option<String>,
|
||||||
|
pub integ_keysize: Option<String>,
|
||||||
|
pub prf_alg: Option<String>,
|
||||||
|
pub dh_group: Option<String>,
|
||||||
|
pub esn: Option<u16>,
|
||||||
|
pub bytes_in: u64,
|
||||||
|
pub packets_in: u64,
|
||||||
|
pub use_in: Option<u32>,
|
||||||
|
pub bytes_out: u64,
|
||||||
|
pub packets_out: u64,
|
||||||
|
pub use_out: Option<u32>,
|
||||||
|
pub rekey_time: Option<u32>,
|
||||||
|
pub life_time: u32,
|
||||||
|
pub install_time: u64,
|
||||||
|
pub local_ts: Vec<String>,
|
||||||
|
pub remote_ts: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type Certificates = HashMap<String, Cert>;
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub struct Cert {
|
||||||
|
pub r#type: CertType,
|
||||||
|
pub flag: X509CertFlag,
|
||||||
|
pub has_privkey: Option<String>,
|
||||||
|
pub data: String,
|
||||||
|
pub subject: Option<String>,
|
||||||
|
pub not_before: Option<String>,
|
||||||
|
pub not_after: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
enum CertType {
|
||||||
|
X509,
|
||||||
|
X509_AC,
|
||||||
|
X509_CRL,
|
||||||
|
OSCP_RESPONSE,
|
||||||
|
PUBKEY,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
enum X509CertFlag {
|
||||||
|
NONE,
|
||||||
|
CA,
|
||||||
|
AA,
|
||||||
|
OCSP,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type Authorities = HashMap<String, Authority>;
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub struct Authority {
|
||||||
|
pub cacert: String,
|
||||||
|
pub crl_uris: Vec<String>,
|
||||||
|
pub ocsp_uris: Vec<String>,
|
||||||
|
pub cert_uri_base: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type Pools = HashMap<String, Pool>;
|
||||||
|
|
||||||
|
#[derive(Debug,Deserialize)]
|
||||||
|
pub struct Pool {
|
||||||
|
pub name: String,
|
||||||
|
pub base: String,
|
||||||
|
pub size: u128,
|
||||||
|
pub online: u128,
|
||||||
|
pub offline: u128,
|
||||||
|
pub leases: Option<HashMap<u16,PoolLease>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug,Deserialize)]
|
||||||
|
pub struct PoolLease {
|
||||||
|
pub address: String,
|
||||||
|
pub identity: String,
|
||||||
|
pub status: PoolLeaseStatus,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
enum PoolLeaseStatus {
|
||||||
|
online,
|
||||||
|
offline,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Structs for generating metrics, TODO
|
||||||
|
|
||||||
|
/*
|
||||||
|
#[derive(Debug, Deserialize, Clone, Hash, PartialEq, Eq)]
|
||||||
|
pub struct SecurityAssociationLabels {
|
||||||
|
pub uniqueid: String,
|
||||||
|
pub local_id: String,
|
||||||
|
pub local_host: String,
|
||||||
|
pub local_port: u16,
|
||||||
|
pub remote_id: String,
|
||||||
|
pub remote_host: String,
|
||||||
|
pub remote_port: u16,
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
#[derive(Debug, Deserialize, Clone, Hash, PartialEq, Eq)]
|
||||||
|
pub struct SecurityAssociationInfo {
|
||||||
|
pub uniqueid: String,
|
||||||
|
pub version: u8,
|
||||||
|
pub local_host: String,
|
||||||
|
pub local_port: u16,
|
||||||
|
pub local_id: String,
|
||||||
|
pub remote_host: String,
|
||||||
|
pub remote_port: u16,
|
||||||
|
pub remote_id: String,
|
||||||
|
pub if_id_in: String,
|
||||||
|
pub if_id_out: String,
|
||||||
|
pub encr_alg: String,
|
||||||
|
pub encr_keysize: String,
|
||||||
|
pub integ_alg: String,
|
||||||
|
pub integ_keysize: String,
|
||||||
|
pub prf_alg: String,
|
||||||
|
pub dh_group: Option<String>,
|
||||||
|
pub local_vips: Vec<String>,
|
||||||
|
pub remote_vips: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Clone, Hash, PartialEq, Eq)]
|
||||||
|
pub struct SecurityAssociationChildInfo {
|
||||||
|
pub name: String,
|
||||||
|
pub uniqueid: String,
|
||||||
|
pub reqid: String,
|
||||||
|
pub mode: ChildSecurityAssociationMode,
|
||||||
|
pub if_id_in: String,
|
||||||
|
pub if_id_out: String,
|
||||||
|
pub encr_alg: String,
|
||||||
|
pub encr_keysize: String,
|
||||||
|
pub integ_alg: String,
|
||||||
|
pub integ_keysize: String,
|
||||||
|
pub prf_alg: String,
|
||||||
|
pub dh_group: Option<String>,
|
||||||
|
pub local_ts: Vec<String>,
|
||||||
|
pub remote_ts: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Hash, PartialEq, Eq, Encode)]
|
||||||
|
pub struct SecurityAssociationLabels {
|
||||||
|
pub uniqueid: String,
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue