1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#![allow(missing_docs)] // delete when we move away from the `property` crate.

use std::collections::HashMap;
use std::path::Path;

use wick_packet::RuntimeConfig;

use crate::config::template_config::Renderable;
use crate::config::TemplateConfig;
use crate::error::ManifestError;

#[derive(Debug, Clone, serde::Serialize)]
#[must_use]
pub enum ResourceRestriction {
  Volume(VolumeRestriction),
  Url(UrlRestriction),
  TcpPort(PortRestriction),
  UdpPort(PortRestriction),
}

impl Renderable for ResourceRestriction {
  fn render_config(
    &mut self,
    source: Option<&Path>,
    root_config: Option<&RuntimeConfig>,
    env: Option<&HashMap<String, String>>,
  ) -> Result<(), ManifestError> {
    match self {
      Self::Volume(restriction) => restriction.render_config(source, root_config, env),
      Self::Url(restriction) => restriction.render_config(source, root_config, env),
      Self::TcpPort(restriction) | Self::UdpPort(restriction) => restriction.render_config(source, root_config, env),
    }
  }
}

#[derive(Debug, Clone, property::Property, serde::Serialize)]
#[property(get(public), set(private), mut(disable))]
/// Settings that define restrictions on what Volumes can be accessed.
pub struct VolumeRestriction {
  /// The components that apply to this restriction.
  pub(crate) components: Vec<String>,
  /// The volumes this restriction allows access to.
  pub(crate) allow: TemplateConfig<String>,
}

impl VolumeRestriction {
  /// Create a new [VolumeRestriction] for the passed components.
  #[must_use]
  pub fn new_from_template(components: Vec<String>, allow: impl Into<String>) -> Self {
    Self {
      components,
      allow: TemplateConfig::new_template(allow.into()),
    }
  }
}

impl Renderable for VolumeRestriction {
  fn render_config(
    &mut self,
    source: Option<&Path>,
    root_config: Option<&RuntimeConfig>,
    env: Option<&HashMap<String, String>>,
  ) -> Result<(), ManifestError> {
    self.allow.set_value(self.allow.render(source, root_config, env)?);
    Ok(())
  }
}

#[derive(Debug, Clone, property::Property, serde::Serialize)]
#[property(get(public), set(private), mut(disable))]
/// Settings that define restrictions on what Urls can be accessed.
pub struct UrlRestriction {
  /// The components that apply to this restriction.
  pub(crate) components: Vec<String>,
  /// A regular expression that defines what urls are allowed.
  pub(crate) allow: TemplateConfig<String>,
}

impl UrlRestriction {
  /// Create a new [UrlRestriction] for the passed components.
  #[must_use]
  pub fn new_from_template(components: Vec<String>, allow: impl Into<String>) -> Self {
    Self {
      components,
      allow: TemplateConfig::new_template(allow.into()),
    }
  }
}

impl Renderable for UrlRestriction {
  fn render_config(
    &mut self,
    source: Option<&Path>,
    root_config: Option<&RuntimeConfig>,
    env: Option<&HashMap<String, String>>,
  ) -> Result<(), ManifestError> {
    self.allow.set_value(self.allow.render(source, root_config, env)?);
    Ok(())
  }
}

#[derive(Debug, Clone, property::Property, serde::Serialize)]
#[property(get(public), set(private), mut(disable))]
pub struct PortRestriction {
  /// The components that apply to this restriction.
  pub(crate) components: Vec<String>,
  /// The IP address this restriction applies to.
  pub(crate) address: TemplateConfig<String>,
  /// The port this restriction applies to.
  pub(crate) port: TemplateConfig<String>,
}

impl PortRestriction {
  /// Create a new [PortRestriction] for the passed components.
  #[must_use]
  pub fn new_from_template(components: Vec<String>, address: impl Into<String>, port: impl Into<String>) -> Self {
    Self {
      components,
      address: TemplateConfig::new_template(address.into()),
      port: TemplateConfig::new_template(port.into()),
    }
  }
}
impl Renderable for PortRestriction {
  fn render_config(
    &mut self,
    source: Option<&Path>,
    root_config: Option<&RuntimeConfig>,
    env: Option<&HashMap<String, String>>,
  ) -> Result<(), ManifestError> {
    self.address.set_value(self.address.render(source, root_config, env)?);
    self.port.set_value(self.port.render(source, root_config, env)?);
    Ok(())
  }
}