11//! This module allows application of settings from URIs or stdin. The inputs are expected to be
22//! TOML settings files, in the same format as user data, or the JSON equivalent. The inputs are
33//! pulled and applied to the API server in a single transaction.
4- //! use aws_smithy_runtime_api::client::result::SdkError;
5- use aws_sdk_secretsmanager:: operation:: get_secret_value:: GetSecretValueError ;
64use aws_sdk_secretsmanager:: config:: http:: HttpResponse as SdkHttpResponse ;
7- use aws_sdk_ssm:: operation:: get_parameter:: GetParameterError ;
8- use crate :: uri_resolver:: { StdinUri , FileUri , HttpUri , S3Uri , UriResolver , SecretsManagerUri , SsmUri } ;
95use crate :: rando;
10- use futures:: future:: { join, ready, TryFutureExt } ;
6+ use futures:: future:: { join, ready} ;
117use futures:: stream:: { self , StreamExt } ;
128use reqwest:: Url ;
139use serde:: de:: { Deserialize , IntoDeserializer } ;
14- use snafu:: { futures :: try_future :: TryFutureExt as SnafuTryFutureExt , OptionExt , ResultExt } ;
10+ use snafu:: { OptionExt , ResultExt } ;
1511use std:: convert:: TryFrom ;
1612use std:: path:: Path ;
17- use tokio:: io:: AsyncReadExt ;
1813
1914
2015/// Reads settings in TOML or JSON format from files at the requested URIs (or from stdin, if given
@@ -73,43 +68,47 @@ where
7368}
7469
7570/// Retrieves the given source location and returns the result in a String.
76- pub async fn get ( input : & str ) -> Result < String > {
77- let resolver = select_resolver ( input) ?;
71+ async fn get < S > ( input_source : S ) -> Result < String >
72+ where
73+ S : AsRef < str > ,
74+ {
75+ let resolver = select_resolver ( input_source. as_ref ( ) ) ?;
7876 resolver. resolve ( ) . await
7977}
8078
79+
8180/// Choose which UriResolver applies to `input` (stdin, file://, http(s):// or s3://).
82- fn select_resolver ( input : & str ) -> Result < Box < dyn UriResolver > > {
83- // 1) "-" → stdin
84- if let Ok ( r) = StdinUri :: try_from ( input) {
81+ fn select_resolver ( input : & str ) -> Result < Box < dyn crate :: uri_resolver :: UriResolver > > {
82+ // "-" → stdin
83+ if let Ok ( r) = crate :: uri_resolver :: StdinUri :: try_from ( input) {
8584 return Ok ( Box :: new ( r) ) ;
8685 }
8786
88- // 2) parse as a URL
87+ // parse as a URL
8988 let url = Url :: parse ( input) . context ( error:: UriSnafu { input_source : input. to_string ( ) } ) ?;
9089
91- // 3) file://
92- if let Ok ( r) = FileUri :: try_from ( & url) {
90+ // file://
91+ if let Ok ( r) = crate :: uri_resolver :: FileUri :: try_from ( & url) {
9392 return Ok ( Box :: new ( r) ) ;
9493 }
9594
96- // 4) http(s)://
97- if let Ok ( r) = HttpUri :: try_from ( url. clone ( ) ) {
95+ // http(s)://
96+ if let Ok ( r) = crate :: uri_resolver :: HttpUri :: try_from ( url. clone ( ) ) {
9897 return Ok ( Box :: new ( r) ) ;
9998 }
10099
101- // 5) s3://
102- if let Ok ( r) = S3Uri :: try_from ( url. clone ( ) ) {
100+ // s3://
101+ if let Ok ( r) = crate :: uri_resolver :: S3Uri :: try_from ( url. clone ( ) ) {
103102 return Ok ( Box :: new ( r) ) ;
104103 }
105104
106- // 6) secretsmanager://
107- if let Ok ( r) = SecretsManagerUri :: try_from ( input) {
105+ // secretsmanager://
106+ if let Ok ( r) = crate :: uri_resolver :: SecretsManagerUri :: try_from ( input) {
108107 return Ok ( Box :: new ( r) ) ;
109108 }
110109
111- // 6) ssm://
112- if let Ok ( r) = SsmUri :: try_from ( input) {
110+ // ssm://
111+ if let Ok ( r) = crate :: uri_resolver :: SsmUri :: try_from ( input) {
113112 return Ok ( Box :: new ( r) ) ;
114113 }
115114
@@ -155,6 +154,10 @@ fn format_change(input: &str, input_source: &str) -> Result<String> {
155154pub ( crate ) mod error {
156155 use aws_sdk_secretsmanager:: operation:: get_secret_value:: GetSecretValueError ;
157156 use aws_sdk_ssm:: operation:: get_parameter:: GetParameterError ;
157+ use crate :: apply:: SdkHttpResponse ;
158+ use aws_smithy_runtime_api:: client:: result:: SdkError ;
159+ use aws_sdk_s3:: operation:: get_object:: GetObjectError ;
160+ //use aws_smithy_http::result::SdkHttpResponse;
158161 use snafu:: Snafu ;
159162
160163 #[ derive( Debug , Snafu ) ]
@@ -237,6 +240,24 @@ pub(crate) mod error {
237240 #[ snafu( display( "Invalid S3 URI '{}': missing bucket name" , input_source) ) ]
238241 S3UriMissingBucket { input_source : String } ,
239242
243+ #[ snafu( display( "Failed to perform HTTP GET to '{}': {}" , uri, source) ) ]
244+ HttpRequest {
245+ uri : String ,
246+ source : reqwest:: Error ,
247+ } ,
248+
249+ #[ snafu( display( "Non-success HTTP status from '{}': {}" , uri, status) ) ]
250+ HttpStatus {
251+ uri : String ,
252+ status : reqwest:: StatusCode ,
253+ } ,
254+
255+ #[ snafu( display( "Failed to read HTTP response body from '{}': {}" , uri, source) ) ]
256+ HttpBody {
257+ uri : String ,
258+ source : reqwest:: Error ,
259+ } ,
260+
240261 #[ snafu( display( "Given invalid file URI '{}'" , input_source) ) ]
241262 InvalidFileUri { input_source : String } ,
242263
@@ -246,6 +267,20 @@ pub(crate) mod error {
246267 #[ snafu( display( "Failed to read standard input: {}" , source) ) ]
247268 StdinRead { source : std:: io:: Error } ,
248269
270+ #[ snafu( display( "Failed to read S3 object body '{bucket}/{key}': {}" , source) ) ]
271+ S3Body {
272+ bucket : String ,
273+ key : String ,
274+ source : aws_sdk_s3:: primitives:: ByteStreamError ,
275+ } ,
276+
277+ #[ snafu( display( "Failed to fetch S3 object '{bucket}/{key}': {}" , source) ) ]
278+ S3Get {
279+ bucket : String ,
280+ key : String ,
281+ source : SdkError < GetObjectError , SdkHttpResponse > ,
282+ } ,
283+
249284 #[ snafu( display( "Invalid S3 URI scheme for '{}', expected s3://" , input_source) ) ]
250285 S3UriScheme { input_source : String } ,
251286
0 commit comments