1use std::collections::HashMap;
2
3use serde::{Serialize, Deserialize};
4use serde_with::{SerializeDisplay, DeserializeFromStr};
5use struct_metadata::Described;
6
7use crate::types::classification::{unrestricted_classification, unrestricted_classification_string};
8use crate::types::{ClassificationString, JsonMap, NonZeroInteger, ServiceName, Text};
9use crate::{ElasticMeta, Readable};
10
11#[derive(Serialize, Deserialize, Clone, Described, PartialEq, Eq, Debug)]
13#[metadata_type(ElasticMeta)]
14#[metadata(index=false, store=false)]
15pub struct EnvironmentVariable {
16 pub name: String,
18 pub value: String,
20}
21
22
23#[derive(Serialize, Deserialize, Clone, Described, PartialEq, Debug)]
25#[metadata_type(ElasticMeta)]
26#[metadata(index=false, store=false)]
27pub struct DockerConfig {
28 #[serde(default)]
30 pub allow_internet_access: bool,
31 #[serde(default)]
33 pub command: Option<Vec<String>>,
34 #[serde(default="default_cpu_cores")]
36 pub cpu_cores: f32,
37 #[serde(default)]
39 pub environment: Vec<EnvironmentVariable>,
40 pub image: String,
42 #[serde(default)]
44 pub registry_username: Option<String>,
45 #[serde(default)]
47 pub registry_password: Option<String>,
48 #[serde(default="default_registry_type")]
50 pub registry_type: RegistryType,
51 #[serde(default)]
53 pub ports: Vec<String>,
54 #[serde(default="default_ram_mb")]
56 pub ram_mb: i32,
57 #[serde(default="default_ram_mb_min")]
59 pub ram_mb_min: i32,
60 #[serde(default)]
62 pub service_account: Option<String>,
63 #[serde(default)]
65 pub labels: Vec<EnvironmentVariable>,
66}
67
68fn default_cpu_cores() -> f32 { 1.0 }
69fn default_registry_type() -> RegistryType { RegistryType::Docker }
70fn default_ram_mb() -> i32 { 512 }
71fn default_ram_mb_min() -> i32 { 256 }
72
73#[derive(SerializeDisplay, DeserializeFromStr, strum::Display, strum::EnumString, Described, PartialEq, Eq, Debug, Clone, Copy)]
74#[metadata_type(ElasticMeta)]
75#[strum(serialize_all = "lowercase")]
76pub enum RegistryType {
77 Docker,
78 Harbor,
79}
80
81#[derive(Serialize, Deserialize, Clone, Described, PartialEq, Eq, Debug)]
83#[metadata_type(ElasticMeta)]
84#[metadata(index=false, store=false)]
85pub struct PersistentVolume {
86 pub mount_path: String,
88 pub capacity: String,
90 pub storage_class: String,
92 #[serde(default="default_access_mode")]
94 pub access_mode: AccessMode,
95}
96
97fn default_access_mode() -> AccessMode { AccessMode::ReadWriteOnce }
98
99#[derive(SerializeDisplay, DeserializeFromStr, strum::Display, strum::EnumString, Described, PartialEq, Eq, Debug, Clone, Copy)]
100#[metadata_type(ElasticMeta)]
101pub enum AccessMode {
102 ReadWriteOnce, ReadWriteMany
103}
104
105#[derive(Serialize, Deserialize, Clone, Described, PartialEq, Debug)]
107#[metadata_type(ElasticMeta)]
108#[metadata(index=false, store=false)]
109pub struct DependencyConfig {
110 pub container: DockerConfig,
112 #[serde(default)]
114 pub volumes: HashMap<String, PersistentVolume>,
115 #[serde(default)]
117 pub run_as_core: bool,
118}
119
120#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, Default, Described)]
121#[metadata_type(ElasticMeta)]
122#[serde(rename_all="UPPERCASE")]
123pub enum FetchMethods {
124 #[default]
125 Get,
126 Post,
127 Git,
128}
129
130
131#[derive(Serialize, Deserialize, Clone, Described, PartialEq, Eq, Debug)]
133#[metadata_type(ElasticMeta)]
134#[metadata(index=false, store=false)]
135pub struct UpdateSource {
136 #[serde(default="default_enabled")]
138 pub enabled: bool,
139 pub name: String,
141 #[serde(default)]
143 pub password: Option<String>,
144 #[serde(default)]
146 pub pattern: Option<String>,
147 #[serde(default)]
149 pub private_key: Option<String>,
150 #[serde(default)]
152 pub ca_cert: Option<String>,
153 #[serde(default)]
155 pub ssl_ignore_errors: bool,
156 #[serde(default)]
158 pub proxy: Option<String>,
159 pub uri: String,
161 #[serde(default)]
163 pub username: Option<String>,
164 #[serde(default)]
166 pub headers: Vec<EnvironmentVariable>,
167 #[serde(default="unrestricted_classification_string")]
169 pub default_classification: ClassificationString,
170 #[serde(default)]
172 pub use_managed_identity: bool,
173 #[serde(default)]
175 pub git_branch: Option<String>,
176 #[serde(default)]
178 pub sync: bool,
179 #[serde(default)]
181 pub fetch_method: FetchMethods,
182 #[serde(default)]
184 pub override_classification: bool,
185 #[serde(default)]
187 pub configuration: HashMap<String, serde_json::Value>,
188 #[serde(default)]
190 pub data: Option<Text>,
191 #[serde(default)]
193 #[metadata(mapping="integer")]
194 update_interval: Option<NonZeroInteger>,
195 #[serde(default)]
197 pub ignore_cache: bool,
198}
199
200fn default_enabled() -> bool { true }
201
202#[derive(Serialize, Deserialize, Clone, Described, PartialEq, Eq, Debug)]
204#[metadata_type(ElasticMeta)]
205#[metadata(index=false, store=false)]
206pub struct UpdateConfig {
207 #[metadata(index=true)]
209 #[serde(default)]
210 pub generates_signatures: bool,
211 #[serde(default)]
213 pub sources: Vec<UpdateSource>,
214 pub update_interval_seconds: i32,
216 #[serde(default)]
218 pub wait_for_update: bool,
219 #[serde(default="default_signature_delimiter")]
221 pub signature_delimiter: SignatureDelimiter,
222 pub custom_delimiter: Option<String>,
224 #[serde(default="default_default_pattern")]
226 pub default_pattern: Text,
227}
228
229fn default_signature_delimiter() -> SignatureDelimiter { SignatureDelimiter::DoubleNewLine }
230fn default_default_pattern() -> Text { ".*".into() }
231
232#[derive(SerializeDisplay, DeserializeFromStr, strum::Display, strum::EnumString, Described, PartialEq, Eq, Debug, Clone, Copy)]
233#[metadata_type(ElasticMeta)]
234#[strum(serialize_all = "snake_case")]
235pub enum SignatureDelimiter {
236 NewLine,
237 DoubleNewLine,
238 Pipe,
239 Comma,
240 Space,
241 None,
242 File,
243 Custom,
244}
245
246impl SignatureDelimiter {
247 pub fn token(&self) -> String {
248 match self {
249 SignatureDelimiter::NewLine => "\n".to_owned(),
250 SignatureDelimiter::DoubleNewLine => "\n\n".to_owned(),
251 SignatureDelimiter::Pipe => "|".to_owned(),
252 SignatureDelimiter::Comma => ",".to_owned(),
253 SignatureDelimiter::Space => " ".to_owned(),
254 SignatureDelimiter::None => "".to_owned(),
255 SignatureDelimiter::File => "".to_owned(),
256 SignatureDelimiter::Custom => "".to_owned(),
257 }
258 }
259}
260
261#[derive(Serialize, Deserialize, Clone, Described, PartialEq, Eq, Debug)]
263#[metadata_type(ElasticMeta)]
264#[metadata(index=false, store=false)]
265pub struct SubmissionParams {
266 pub default: serde_json::Value,
268 pub name: String,
270 #[serde(rename="type")]
272 pub param_type: ParamKinds,
273 pub value: serde_json::Value,
275 #[serde(default)]
277 pub list: Vec<serde_json::Value>,
278 #[serde(default)]
280 pub hide: bool,
281}
282
283#[derive(SerializeDisplay, DeserializeFromStr, strum::Display, strum::EnumString, Described, PartialEq, Eq, Debug, Clone, Copy)]
284#[metadata_type(ElasticMeta)]
285#[strum(serialize_all = "lowercase")]
286pub enum ParamKinds {
287 Str,
288 Int,
289 List,
290 Bool,
291}
292
293#[derive(Serialize, Deserialize, Clone, Described, PartialEq, Debug)]
295#[metadata_type(ElasticMeta)]
296#[metadata(index=true, store=false)]
297pub struct Service {
298 #[metadata(store=true)]
301 #[serde(default="default_service_accepts")]
302 pub accepts: String,
303 #[metadata(store=true)]
306 #[serde(default="default_service_rejects")]
307 pub rejects: Option<String>,
308 #[serde(default)]
310 pub auto_update: bool,
311 #[metadata(store=true, copyto="__text__")]
313 #[serde(default="default_category")]
314 pub category: ServiceName,
315 #[serde(default="unrestricted_classification")]
317 pub classification: String,
318 #[metadata(index=false, store=false)]
320 #[serde(default)]
321 pub config: JsonMap,
322 #[metadata(store=true, copyto="__text__")]
324 #[serde(default="default_description")]
325 pub description: Text,
326 #[serde(default="unrestricted_classification")]
328 pub default_result_classification: String,
329 #[metadata(store=true)]
331 #[serde(default)]
332 pub enabled: bool,
333 #[serde(default)]
335 pub is_external: bool,
336 #[serde(default)]
338 #[metadata(mapping="integer")]
339 pub licence_count: u32,
340 #[serde(default)]
342 #[metadata(mapping="integer")]
343 pub min_instances: Option<u32>,
344 #[serde(default)]
346 #[metadata(mapping="integer")]
347 pub max_queue_length: u32,
348
349 #[serde(default)]
351 pub uses_tags: bool,
352 #[serde(default)]
354 pub uses_tag_scores: bool,
355 #[serde(default)]
357 pub uses_temp_submission_data: bool,
358 #[serde(default)]
360 pub uses_metadata: bool,
361 #[serde(default)]
363 pub monitored_keys: Vec<String>,
364
365 #[metadata(store=true, copyto="__text__")]
367 pub name: ServiceName,
368 #[metadata(store=true)]
370 pub version: String,
371
372 #[serde(default)]
374 pub privileged: bool,
375 #[serde(default)]
377 pub disable_cache: bool,
378
379 #[metadata(store=true, copyto="__text__")]
381 #[serde(default="default_stage")]
382 pub stage: String,
383 #[metadata(index=false)]
385 #[serde(default)]
386 pub submission_params: Vec<SubmissionParams>,
387 #[serde(default="default_timeout")]
389 pub timeout: i32,
390
391 pub docker_config: DockerConfig,
393 #[serde(default)]
395 pub dependencies: HashMap<String, DependencyConfig>,
396
397 #[serde(default="default_update_channel")]
399 pub update_channel: ChannelKinds,
400 pub update_config: Option<UpdateConfig>,
402
403 #[serde(default)]
405 pub recursion_prevention: Vec<ServiceName>,
406}
407
408fn default_category() -> ServiceName { ServiceName::from_string("Static Analysis".to_owned()) }
409fn default_description() -> Text { Text("NA".to_owned()) }
410fn default_stage() -> String { "CORE".to_owned() }
411fn default_timeout() -> i32 { 60 }
412fn default_update_channel() -> ChannelKinds { ChannelKinds::Stable }
413
414impl Service {
415 pub fn key(&self) -> String {
416 format!("{}_{}", self.name, self.version)
417 }
418}
419
420#[derive(SerializeDisplay, DeserializeFromStr, strum::Display, strum::EnumString, Described, PartialEq, Eq, Debug, Clone, Copy)]
421#[metadata_type(ElasticMeta)]
422#[strum(serialize_all = "lowercase")]
423pub enum ChannelKinds {
424 Stable,
425 RC,
426 Beta,
427 Dev,
428}
429
430fn default_service_accepts() -> String { ".*".to_string() }
431fn default_service_rejects() -> Option<String> { Some("empty|metadata/.*".to_string()) }
432
433impl Readable for Service {
434 fn set_from_archive(&mut self, _from_archive: bool) {}
435}