1#![deny(missing_debug_implementations)]
73#![deny(missing_docs)]
74
75pub use crate::{
76 parameter::{
77 parameter_values_from_file,
78 parameter_values_from_str,
79 parameter_values_from_yaml,
80 ParameterValue,
81 ParameterValues,
82 },
83 secret::{Secret, Secrets},
84 template::Template,
85};
86
87mod parameter;
88mod processor;
89mod secret;
90mod template;
91
92#[cfg(test)]
93mod tests {
94 use std::fs::File;
95 use std::io::Read;
96
97 use super::{
98 parameter_values_from_file,
99 ParameterValue,
100 ParameterValues,
101 Secret,
102 Secrets,
103 Template,
104 };
105
106 #[test]
107 fn process_keys() {
108 let template_contents = r#"
109---
110objects:
111 - $(FOO): bar
112parameters:
113 - name: FOO
114 value: baz
115"#;
116 let template = Template::new(
117 template_contents.to_string(),
118 ParameterValues::new(),
119 None,
120 )
121 .unwrap();
122
123 let processed_template = template.process().unwrap();
124
125 assert_eq!(
126 processed_template
127 .lines()
128 .map(|l| l.trim_end())
129 .collect::<Vec<&str>>()
130 .join("\n"),
131 r#"---
132baz: bar"#
133 );
134 }
135
136 #[test]
137 fn encode_secrets() {
138 let template_contents = r#"
139---
140kind: "Template"
141apiVersion: "v1"
142metadata:
143 name: "example"
144objects:
145 - kind: "Secret"
146 apiVersion: "v1"
147 metadata:
148 name: "webapp"
149 data:
150 config.yml: |
151 username: "carl"
152 password: "$(PASSWORD)"
153 type: "Opaque"
154parameters:
155 - name: "PASSWORD"
156 description: "The password for the web app"
157 required: true
158 parameterType: "string"
159"#;
160
161 let mut parameter_values = ParameterValues::new();
162
163 parameter_values.insert(
164 "PASSWORD".to_string(),
165 ParameterValue::Plain("narble".to_string()),
166 );
167
168 let mut secrets = Secrets::new();
169
170 secrets.insert(Secret {
171 name: "webapp".to_string(),
172 namespace: "default".to_string(),
173 });
174
175 let template = Template::new(
176 template_contents.to_string(),
177 parameter_values,
178 Some(secrets),
179 )
180 .unwrap();
181
182 let processed_template = template.process().unwrap();
183
184 assert_eq!(
185 processed_template
186 .lines()
187 .map(|l| l.trim_end())
188 .collect::<Vec<&str>>()
189 .join("\n"),
190 r#"---
191kind: Secret
192apiVersion: v1
193metadata:
194 name: webapp
195data:
196 config.yml: dXNlcm5hbWU6ICJjYXJsIgpwYXNzd29yZDogIm5hcmJsZSIK
197type: Opaque"#
198 );
199 }
200
201 #[test]
202 fn missing_secret() {
203 let template_contents = r#"
204---
205kind: "Template"
206apiVersion: "v1"
207metadata:
208 name: "example"
209objects:
210 - kind: "Namespace"
211 apiVersion: "v1"
212 metadata:
213 name: "$(NAMESPACE)"
214parameters:
215 - name: "NAMESPACE"
216 description: "The namespace to create"
217 required: true
218 parameterType: "string"
219"#;
220
221 let mut parameter_values = ParameterValues::new();
222
223 parameter_values.insert(
224 "NAMESPACE".to_string(),
225 ParameterValue::Plain("foo".to_string()),
226 );
227
228 let mut secrets = Secrets::new();
229
230 secrets.insert(Secret {
231 name: "ghost".to_string(),
232 namespace: "default".to_string(),
233 });
234
235 let template = Template::new(
236 template_contents.to_string(),
237 parameter_values,
238 Some(secrets),
239 )
240 .unwrap();
241
242 assert!(template.process().is_err());
243 }
244
245 #[test]
246 fn parameter_file() {
247 let mut template_file = File::open("example.yml").unwrap();
248 let mut template_contents = String::new();
249
250 template_file
251 .read_to_string(&mut template_contents)
252 .unwrap();
253
254 let parameter_values = parameter_values_from_file("params.yml").unwrap();
255
256 let template =
257 Template::new(template_contents.to_string(), parameter_values, None).unwrap();
258
259 let processed_template = template.process().unwrap();
260
261 assert_eq!(
262 processed_template
263 .lines()
264 .map(|l| l.trim_end())
265 .collect::<Vec<&str>>()
266 .join("\n"),
267 r#"---
268kind: Service
269apiVersion: v1
270metadata:
271 name: mongodb
272spec:
273 ports:
274 - name: mongo
275 protocol: TCP
276 targetPort: 27017
277 selector:
278 name: mongodb
279---
280kind: ReplicationController
281apiVersion: v1
282metadata:
283 name: mongodb
284spec:
285 replicas: 2
286 selector:
287 name: mongodb
288 template:
289 metadata:
290 creationTimestamp: ~
291 labels:
292 name: mongodb
293 spec:
294 containers:
295 - name: mongodb
296 image: docker.io/centos/mongodb-26-centos7
297 ports:
298 - containerPort: 27017
299 protocol: TCP
300 env:
301 - name: MONGODB_USER
302 value: carl
303 - name: MONGODB_PASSWORD
304 value: c2VjcmV0
305 - name: MONGODB_DATABASE
306 value: sampledb"#
307 );
308 }
309}