|
1 | 1 | //! This module allows application of settings from URIs or stdin. The inputs are expected to be |
2 | 2 | //! TOML settings files, in the same format as user data, or the JSON equivalent. The inputs are |
3 | 3 | //! pulled and applied to the API server in a single transaction. |
4 | | -use crate::apply::error::ResolverFailureSnafu; |
5 | 4 | use crate::rando; |
| 5 | +use crate::uri_resolver::{select_resolver, SettingsInput}; |
6 | 6 | use futures::future::{join, ready}; |
7 | 7 | use futures::stream::{self, StreamExt}; |
8 | | -use reqwest::Url; |
9 | 8 | use serde::de::{Deserialize, IntoDeserializer}; |
10 | 9 | use snafu::{OptionExt, ResultExt}; |
11 | | -use std::convert::TryFrom; |
12 | 10 | use std::path::Path; |
13 | 11 |
|
14 | 12 | /// Reads settings in TOML or JSON format from files at the requested URIs (or from stdin, if given |
@@ -66,70 +64,14 @@ where |
66 | 64 | Ok(()) |
67 | 65 | } |
68 | 66 |
|
69 | | -/// Holds the raw input string and the URL (if it parses). |
70 | | -pub struct SettingsInput { |
71 | | - pub input: String, |
72 | | - pub parsed_url: Option<Url>, |
73 | | -} |
74 | | -impl SettingsInput { |
75 | | - pub(crate) fn new(input: impl Into<String>) -> Self { |
76 | | - let input = input.into(); |
77 | | - let parsed_url = match Url::parse(&input) { |
78 | | - Ok(url) => Some(url), |
79 | | - Err(err) => { |
80 | | - log::debug!("URL parse failed for '{}': {}", input, err); |
81 | | - None |
82 | | - } |
83 | | - }; |
84 | | - SettingsInput { input, parsed_url } |
85 | | - } |
86 | | -} |
87 | | - |
88 | 67 | /// Retrieves the given source location and returns the result in a String. |
89 | 68 | async fn get<S>(input_source: S) -> Result<String> |
90 | 69 | where |
91 | 70 | S: AsRef<str>, |
92 | 71 | { |
93 | 72 | let settings = SettingsInput::new(input_source.as_ref()); |
94 | | - let resolver = select_resolver(&settings)?; |
95 | | - resolver.resolve().await.context(ResolverFailureSnafu) |
96 | | -} |
97 | | - |
98 | | -/// Macro to try multiple settings resolver types in sequence, returning the first one that succeeds. |
99 | | -macro_rules! try_resolvers { |
100 | | - ($input:expr, $($resolver_type:ty),+ $(,)?) => { |
101 | | - $( |
102 | | - if let Ok(r) = <$resolver_type>::try_from($input) { |
103 | | - log::debug!("select_resolver: picked {}", stringify!($resolver_type)); |
104 | | - return Ok(Box::new(r)); |
105 | | - } |
106 | | - )+ |
107 | | - }; |
108 | | -} |
109 | | - |
110 | | -/// Choose which UriResolver applies to `input` (stdin, base64:, file://, http(s)://, s3://, secretsmanager://, and ssm://). |
111 | | -fn select_resolver(input: &SettingsInput) -> Result<Box<dyn crate::uri_resolver::UriResolver>> { |
112 | | - use crate::uri_resolver::*; |
113 | | - |
114 | | - // NOTE: Order matters! More specific resolvers must come before general ones. |
115 | | - // - StdinUri first (exact match for "-") |
116 | | - // - ARN resolvers before URI resolvers (ARNs are more specific) |
117 | | - try_resolvers!(input, StdinUri, Base64Uri, FileUri, HttpUri,); |
118 | | - |
119 | | - #[cfg(feature = "tls")] |
120 | | - try_resolvers!( |
121 | | - input, |
122 | | - S3Uri, |
123 | | - SecretsManagerArn, |
124 | | - SecretsManagerUri, |
125 | | - SsmArn, |
126 | | - SsmUri, |
127 | | - ); |
128 | | - |
129 | | - error::NoResolverSnafu { |
130 | | - input_source: input.input.clone(), |
131 | | - } |
132 | | - .fail() |
| 73 | + let resolver = select_resolver(&settings).context(error::ResolverFailureSnafu)?; |
| 74 | + resolver.resolve().await.context(error::ResolverFailureSnafu) |
133 | 75 | } |
134 | 76 |
|
135 | 77 | /// Takes a string of TOML or JSON settings data and reserializes |
@@ -178,9 +120,6 @@ mod error { |
178 | 120 | source: Box<crate::Error>, |
179 | 121 | }, |
180 | 122 |
|
181 | | - #[snafu(display("No URI resolver found for '{}'", input_source))] |
182 | | - NoResolver { input_source: String }, |
183 | | - |
184 | 123 | #[snafu(display( |
185 | 124 | "Input '{}' is not valid TOML or JSON. (TOML error: {}) (JSON error: {})", |
186 | 125 | input_source, |
@@ -264,8 +203,7 @@ pub type Result<T> = std::result::Result<T, error::Error>; |
264 | 203 |
|
265 | 204 | #[cfg(test)] |
266 | 205 | mod resolver_selection_tests { |
267 | | - use super::select_resolver; |
268 | | - use crate::apply::SettingsInput; |
| 206 | + use crate::uri_resolver::{select_resolver, SettingsInput}; |
269 | 207 | use std::any::{Any, TypeId}; |
270 | 208 | use test_case::test_case; |
271 | 209 |
|
@@ -315,7 +253,7 @@ mod format_change_tests { |
315 | 253 |
|
316 | 254 | #[cfg(test)] |
317 | 255 | mod resolver_error_tests { |
318 | | - use super::{select_resolver, SettingsInput}; |
| 256 | + use crate::uri_resolver::{select_resolver, SettingsInput}; |
319 | 257 |
|
320 | 258 | #[test] |
321 | 259 | fn unsupported_scheme() { |
|
0 commit comments