use std::collections::HashMap;
use serde::{Serialize, Deserialize};
use serde_with::{SerializeDisplay, DeserializeFromStr};
use struct_metadata::Described;
use crate::{JsonMap, ElasticMeta, Text};
#[derive(Serialize, Deserialize, Described, PartialEq, Eq, Debug)]
#[metadata_type(ElasticMeta)]
#[metadata(index=false, store=false)]
pub struct EnvironmentVariable {
pub name: String,
pub value: String,
}
#[derive(Serialize, Deserialize, Described, PartialEq, Debug)]
#[metadata_type(ElasticMeta)]
#[metadata(index=false, store=false)]
pub struct DockerConfig {
#[serde(default)]
pub allow_internet_access: bool,
#[serde(default)]
pub command: Option<Vec<String>>,
#[serde(default="default_cpu_cores")]
pub cpu_cores: f64,
#[serde(default)]
pub environment: Vec<EnvironmentVariable>,
pub image: String,
#[serde(default)]
pub registry_username: Option<String>,
#[serde(default)]
pub registry_password: Option<String>,
#[serde(default="default_registry_type")]
pub registry_type: RegistryType,
#[serde(default)]
pub ports: Vec<String>,
#[serde(default="default_ram_mb")]
pub ram_mb: u64,
#[serde(default="default_ram_mb_min")]
pub ram_mb_min: u64,
#[serde(default)]
pub service_account: Option<String>,
}
fn default_cpu_cores() -> f64 { 1.0 }
fn default_registry_type() -> RegistryType { RegistryType::Docker }
fn default_ram_mb() -> u64 { 512 }
fn default_ram_mb_min() -> u64 { 256 }
#[derive(SerializeDisplay, DeserializeFromStr, strum::Display, strum::EnumString, Described, PartialEq, Eq, Debug)]
#[metadata_type(ElasticMeta)]
#[strum(serialize_all = "lowercase")]
pub enum RegistryType {
Docker,
Harbor,
}
#[derive(Serialize, Deserialize, Described, PartialEq, Eq, Debug)]
#[metadata_type(ElasticMeta)]
#[metadata(index=false, store=false)]
pub struct PersistentVolume {
pub mount_path: String,
pub capacity: String,
pub storage_class: String,
#[serde(default="default_access_mode")]
pub access_mode: AccessMode,
}
fn default_access_mode() -> AccessMode { AccessMode::ReadWriteOnce }
#[derive(SerializeDisplay, DeserializeFromStr, strum::Display, strum::EnumString, Described, PartialEq, Eq, Debug)]
#[metadata_type(ElasticMeta)]
pub enum AccessMode {
ReadWriteOnce, ReadWriteMany
}
#[derive(Serialize, Deserialize, Described, PartialEq, Debug)]
#[metadata_type(ElasticMeta)]
#[metadata(index=false, store=false)]
pub struct DependencyConfig {
pub container: DockerConfig,
#[serde(default)]
pub volumes: HashMap<String, PersistentVolume>,
#[serde(default)]
pub run_as_core: bool,
}
#[derive(Serialize, Deserialize, Described, PartialEq, Eq, Debug)]
#[metadata_type(ElasticMeta)]
#[metadata(index=false, store=false)]
pub struct UpdateSource {
pub name: String,
#[serde(default)]
pub password: Option<String>,
#[serde(default)]
pub pattern: Option<String>,
#[serde(default)]
pub private_key: Option<String>,
#[serde(default)]
pub ca_cert: Option<String>,
#[serde(default)]
pub ssl_ignore_errors: bool,
#[serde(default)]
pub proxy: Option<String>,
pub uri: String,
#[serde(default)]
pub username: Option<String>,
#[serde(default)]
pub headers: Vec<EnvironmentVariable>,
pub default_classification: String, #[serde(default)]
pub git_branch: Option<String>,
#[serde(default)]
pub sync: bool,
}
#[derive(Serialize, Deserialize, Described, PartialEq, Eq, Debug)]
#[metadata_type(ElasticMeta)]
#[metadata(index=false, store=false)]
pub struct UpdateConfig {
#[metadata(index=true)]
#[serde(default)]
pub generates_signatures: bool,
#[serde(default)]
pub sources: Vec<UpdateSource>,
pub update_interval_seconds: u32,
#[serde(default)]
pub wait_for_update: bool,
#[serde(default="default_signature_delimiter")]
pub signature_delimiter: SignatureDelimiter,
pub custom_delimiter: Option<String>,
}
fn default_signature_delimiter() -> SignatureDelimiter { SignatureDelimiter::DoubleNewLine }
#[derive(SerializeDisplay, DeserializeFromStr, strum::Display, strum::EnumString, Described, PartialEq, Eq, Debug)]
#[metadata_type(ElasticMeta)]
#[strum(serialize_all = "snake_case")]
pub enum SignatureDelimiter {
NewLine,
DoubleNewLine,
Pipe,
Comma,
Space,
None,
File,
Custom,
}
impl SignatureDelimiter {
pub fn token(&self) -> String {
match self {
SignatureDelimiter::NewLine => "\n".to_owned(),
SignatureDelimiter::DoubleNewLine => "\n\n".to_owned(),
SignatureDelimiter::Pipe => "|".to_owned(),
SignatureDelimiter::Comma => ",".to_owned(),
SignatureDelimiter::Space => " ".to_owned(),
SignatureDelimiter::None => "".to_owned(),
SignatureDelimiter::File => "".to_owned(),
SignatureDelimiter::Custom => "".to_owned(),
}
}
}
#[derive(Serialize, Deserialize, Described, PartialEq, Eq, Debug)]
#[metadata_type(ElasticMeta)]
#[metadata(index=false, store=false)]
pub struct SubmissionParams {
pub default: serde_json::Value,
pub name: String,
#[serde(rename="type")]
pub param_type: ParamKinds,
pub value: serde_json::Value,
pub list: Vec<serde_json::Value>,
#[serde(default)]
pub hide: bool,
}
#[derive(SerializeDisplay, DeserializeFromStr, strum::Display, strum::EnumString, Described, PartialEq, Eq, Debug)]
#[metadata_type(ElasticMeta)]
#[strum(serialize_all = "lowercase")]
pub enum ParamKinds {
Str,
Int,
List,
Bool,
}
#[derive(Serialize, Deserialize, Described, PartialEq, Debug)]
#[metadata_type(ElasticMeta)]
#[metadata(index=true, store=false)]
pub struct Service {
#[metadata(store=true)]
#[serde(default="default_service_accepts")]
pub accepts: String,
#[metadata(store=true)]
#[serde(default="default_service_rejects")]
pub rejects: Option<String>,
#[metadata(store=true, copyto="__text__")]
#[serde(default="default_category")]
pub category: String,
pub classification: String, #[metadata(index=false, store=false)]
#[serde(default)]
pub config: JsonMap,
#[metadata(store=true, copyto="__text__")]
#[serde(default="default_description")]
pub description: Text,
pub default_result_classification: String, #[metadata(store=true)]
#[serde(default)]
pub enabled: bool,
#[serde(default)]
pub is_external: bool,
#[serde(default)]
pub licence_count: u32,
#[serde(default)]
pub min_instances: Option<u32>,
#[serde(default)]
pub max_queue_length: u32,
#[serde(default)]
pub uses_tags: bool,
#[serde(default)]
pub uses_tag_scores: bool,
#[serde(default)]
pub uses_temp_submission_data: bool,
#[serde(default)]
pub uses_metadata: bool,
#[metadata(store=true, copyto="__text__")]
pub name: String,
#[metadata(store=true)]
pub version: String,
#[serde(default)]
pub privileged: bool,
#[serde(default)]
pub disable_cache: bool,
#[metadata(store=true, copyto="__text__")]
#[serde(default="default_stage")]
pub stage: String,
#[metadata(index=false)]
#[serde(default)]
pub submission_params: Vec<SubmissionParams>,
#[serde(default="default_timeout")]
pub timeout: u32,
pub docker_config: DockerConfig,
#[serde(default)]
pub dependencies: HashMap<String, DependencyConfig>,
#[serde(default="default_update_channel")]
pub update_channel: ChannelKinds,
pub update_config: Option<UpdateConfig>,
}
fn default_category() -> String { "Static Analysis".to_owned() }
fn default_description() -> Text { Text("NA".to_owned()) }
fn default_stage() -> String { "CORE".to_owned() }
fn default_timeout() -> u32 { 60 }
fn default_update_channel() -> ChannelKinds { ChannelKinds::Stable }
impl Service {
pub fn key(&self) -> String {
format!("{}_{}", self.name, self.version)
}
}
#[derive(SerializeDisplay, DeserializeFromStr, strum::Display, strum::EnumString, Described, PartialEq, Eq, Debug)]
#[metadata_type(ElasticMeta)]
#[strum(serialize_all = "lowercase")]
pub enum ChannelKinds {
Stable,
RC,
Beta,
Dev,
}
fn default_service_accepts() -> String { ".*".to_string() }
fn default_service_rejects() -> Option<String> { Some("empty|metadata/.*".to_string()) }