Skip to main content

fakecloud_appconfig/
validation.rs

1//! Model-derived input validation for AWS AppConfig.
2//!
3//! AWS rejects requests that violate the Smithy model's top-level constraints
4//! (`@required`, `@length`, `@range`, `@enum`) with `BadRequestException`
5//! before the operation runs. This module encodes those constraints per
6//! operation so out-of-range / omitted / bad-enum inputs are rejected exactly
7//! as the real service does. The rule table is generated from
8//! `aws-models/appconfig.json`.
9
10use http::StatusCode;
11use serde_json::Value;
12
13use fakecloud_core::service::{AwsRequest, AwsServiceError};
14
15/// Where a constrained input member is bound on the wire.
16#[derive(Clone, Copy)]
17pub enum Src {
18    Body,
19    Query,
20    Label,
21}
22
23/// A single input-constraint rule from the Smithy model.
24pub enum Rule {
25    Required(&'static str, Src),
26    LenMin(&'static str, Src, usize),
27    LenMax(&'static str, Src, usize),
28    RangeMin(&'static str, Src, f64),
29    RangeMax(&'static str, Src, f64),
30    Enum(&'static str, Src, &'static [&'static str]),
31}
32
33fn bad(msg: impl Into<String>) -> AwsServiceError {
34    AwsServiceError::aws_error(StatusCode::BAD_REQUEST, "BadRequestException", msg)
35}
36
37/// Length of a value for `@length` checks: strings by char count, lists by
38/// element count, maps by entry count.
39fn value_len(v: &Value) -> Option<usize> {
40    match v {
41        Value::String(s) => Some(s.chars().count()),
42        Value::Array(a) => Some(a.len()),
43        Value::Object(o) => Some(o.len()),
44        _ => None,
45    }
46}
47
48fn as_f64(v: &Value) -> Option<f64> {
49    v.as_f64()
50        .or_else(|| v.as_str().and_then(|s| s.parse().ok()))
51}
52
53/// Validate an operation's input against the model constraints. `labels` are
54/// the decoded path labels in URI order (see `label_fields`).
55pub fn validate(action: &str, labels: &[String], req: &AwsRequest) -> Result<(), AwsServiceError> {
56    let rules = input_rules(action);
57    if rules.is_empty() {
58        return Ok(());
59    }
60    let body: Value = serde_json::from_slice(&req.body).unwrap_or(Value::Null);
61    let lf = label_fields(action);
62    let raw = |field: &str, src: Src| -> Option<Value> {
63        match src {
64            Src::Body => body.get(field).cloned().filter(|v| !v.is_null()),
65            Src::Query => req
66                .query_params
67                .get(field)
68                .map(|s| Value::String(s.clone())),
69            Src::Label => lf
70                .iter()
71                .position(|f| *f == field)
72                .and_then(|i| labels.get(i))
73                .map(|s| Value::String(s.clone())),
74        }
75    };
76    for rule in rules {
77        match rule {
78            Rule::Required(f, src) => {
79                let missing = match raw(f, src) {
80                    None => true,
81                    // An omitted path label reaches us as the literal
82                    // `{Field}` placeholder or an empty segment.
83                    Some(Value::String(s)) => {
84                        s.is_empty() || (s.starts_with('{') && s.ends_with('}'))
85                    }
86                    Some(_) => false,
87                };
88                if missing {
89                    return Err(bad(format!("{f} is required.")));
90                }
91            }
92            Rule::LenMin(f, src, n) => {
93                if let Some(len) = raw(f, src).as_ref().and_then(value_len) {
94                    if len < n {
95                        return Err(bad(format!("{f} is shorter than the minimum length.")));
96                    }
97                }
98            }
99            Rule::LenMax(f, src, n) => {
100                if let Some(len) = raw(f, src).as_ref().and_then(value_len) {
101                    if len > n {
102                        return Err(bad(format!("{f} exceeds the maximum length.")));
103                    }
104                }
105            }
106            Rule::RangeMin(f, src, n) => {
107                if let Some(x) = raw(f, src).as_ref().and_then(as_f64) {
108                    if x < n {
109                        return Err(bad(format!("{f} is below the minimum value.")));
110                    }
111                }
112            }
113            Rule::RangeMax(f, src, n) => {
114                if let Some(x) = raw(f, src).as_ref().and_then(as_f64) {
115                    if x > n {
116                        return Err(bad(format!("{f} exceeds the maximum value.")));
117                    }
118                }
119            }
120            Rule::Enum(f, src, vals) => {
121                if let Some(Value::String(s)) = raw(f, src) {
122                    if !vals.contains(&s.as_str()) {
123                        return Err(bad(format!("{f} is not a valid value.")));
124                    }
125                }
126            }
127        }
128    }
129    Ok(())
130}
131
132/// Path-label field names in URI order for each operation, so `Src::Label`
133/// rules can resolve their value from the positional `labels` slice.
134fn label_fields(action: &str) -> &'static [&'static str] {
135    match action {
136        "CreateConfigurationProfile" => &["ApplicationId"],
137        "CreateEnvironment" => &["ApplicationId"],
138        "CreateExperimentDefinition" => &["ApplicationIdentifier"],
139        "CreateHostedConfigurationVersion" => &["ApplicationId", "ConfigurationProfileId"],
140        "DeleteApplication" => &["ApplicationId"],
141        "DeleteConfigurationProfile" => &["ApplicationId", "ConfigurationProfileId"],
142        "DeleteDeploymentStrategy" => &["DeploymentStrategyId"],
143        "DeleteEnvironment" => &["ApplicationId", "EnvironmentId"],
144        "DeleteExperimentDefinition" => {
145            &["ApplicationIdentifier", "ExperimentDefinitionIdentifier"]
146        }
147        "DeleteExtension" => &["ExtensionIdentifier"],
148        "DeleteExtensionAssociation" => &["ExtensionAssociationId"],
149        "DeleteHostedConfigurationVersion" => {
150            &["ApplicationId", "ConfigurationProfileId", "VersionNumber"]
151        }
152        "GetApplication" => &["ApplicationId"],
153        "GetConfiguration" => &["Application", "Environment", "Configuration"],
154        "GetConfigurationProfile" => &["ApplicationId", "ConfigurationProfileId"],
155        "GetDeployment" => &["ApplicationId", "EnvironmentId", "DeploymentNumber"],
156        "GetDeploymentStrategy" => &["DeploymentStrategyId"],
157        "GetEnvironment" => &["ApplicationId", "EnvironmentId"],
158        "GetExperimentDefinition" => &["ApplicationIdentifier", "ExperimentDefinitionIdentifier"],
159        "GetExperimentRun" => &[
160            "ApplicationIdentifier",
161            "ExperimentDefinitionIdentifier",
162            "Run",
163        ],
164        "GetExtension" => &["ExtensionIdentifier"],
165        "GetExtensionAssociation" => &["ExtensionAssociationId"],
166        "GetHostedConfigurationVersion" => {
167            &["ApplicationId", "ConfigurationProfileId", "VersionNumber"]
168        }
169        "ListConfigurationProfiles" => &["ApplicationId"],
170        "ListDeployments" => &["ApplicationId", "EnvironmentId"],
171        "ListEnvironments" => &["ApplicationId"],
172        "ListExperimentRunEvents" => &[
173            "ApplicationIdentifier",
174            "ExperimentDefinitionIdentifier",
175            "Run",
176        ],
177        "ListExperimentRuns" => &["ApplicationIdentifier", "ExperimentDefinitionIdentifier"],
178        "ListHostedConfigurationVersions" => &["ApplicationId", "ConfigurationProfileId"],
179        "ListTagsForResource" => &["ResourceArn"],
180        "StartDeployment" => &["ApplicationId", "EnvironmentId"],
181        "StartExperimentRun" => &["ApplicationIdentifier", "ExperimentDefinitionIdentifier"],
182        "StopDeployment" => &["ApplicationId", "EnvironmentId", "DeploymentNumber"],
183        "StopExperimentRun" => &[
184            "ApplicationIdentifier",
185            "ExperimentDefinitionIdentifier",
186            "Run",
187        ],
188        "TagResource" => &["ResourceArn"],
189        "UntagResource" => &["ResourceArn"],
190        "UpdateApplication" => &["ApplicationId"],
191        "UpdateConfigurationProfile" => &["ApplicationId", "ConfigurationProfileId"],
192        "UpdateDeploymentStrategy" => &["DeploymentStrategyId"],
193        "UpdateEnvironment" => &["ApplicationId", "EnvironmentId"],
194        "UpdateExperimentDefinition" => {
195            &["ApplicationIdentifier", "ExperimentDefinitionIdentifier"]
196        }
197        "UpdateExperimentRun" => &[
198            "ApplicationIdentifier",
199            "ExperimentDefinitionIdentifier",
200            "Run",
201        ],
202        "UpdateExtension" => &["ExtensionIdentifier"],
203        "UpdateExtensionAssociation" => &["ExtensionAssociationId"],
204        "ValidateConfiguration" => &["ApplicationId", "ConfigurationProfileId"],
205        _ => &[],
206    }
207}
208
209/// Model-derived constraint rules per operation.
210#[allow(clippy::too_many_lines)]
211fn input_rules(action: &str) -> Vec<Rule> {
212    match action {
213        "CreateApplication" => vec![
214            Rule::Required("Name", Src::Body),
215            Rule::LenMin("Name", Src::Body, 1),
216            Rule::LenMax("Name", Src::Body, 64),
217            Rule::LenMin("Description", Src::Body, 0),
218            Rule::LenMax("Description", Src::Body, 1024),
219            Rule::LenMin("Tags", Src::Body, 0),
220            Rule::LenMax("Tags", Src::Body, 50),
221        ],
222        "CreateConfigurationProfile" => vec![
223            Rule::Required("ApplicationId", Src::Label),
224            Rule::LenMin("ApplicationId", Src::Label, 1),
225            Rule::LenMax("ApplicationId", Src::Label, 64),
226            Rule::Required("Name", Src::Body),
227            Rule::LenMin("Name", Src::Body, 1),
228            Rule::LenMax("Name", Src::Body, 128),
229            Rule::LenMin("Description", Src::Body, 0),
230            Rule::LenMax("Description", Src::Body, 1024),
231            Rule::Required("LocationUri", Src::Body),
232            Rule::LenMin("LocationUri", Src::Body, 1),
233            Rule::LenMax("LocationUri", Src::Body, 2048),
234            Rule::LenMin("RetrievalRoleArn", Src::Body, 20),
235            Rule::LenMax("RetrievalRoleArn", Src::Body, 2048),
236            Rule::LenMin("Validators", Src::Body, 0),
237            Rule::LenMax("Validators", Src::Body, 2),
238            Rule::LenMin("Tags", Src::Body, 0),
239            Rule::LenMax("Tags", Src::Body, 50),
240            Rule::LenMin("KmsKeyIdentifier", Src::Body, 1),
241            Rule::LenMax("KmsKeyIdentifier", Src::Body, 2048),
242        ],
243        "CreateDeploymentStrategy" => vec![
244            Rule::Required("Name", Src::Body),
245            Rule::LenMin("Name", Src::Body, 1),
246            Rule::LenMax("Name", Src::Body, 64),
247            Rule::LenMin("Description", Src::Body, 0),
248            Rule::LenMax("Description", Src::Body, 1024),
249            Rule::Required("DeploymentDurationInMinutes", Src::Body),
250            Rule::RangeMin("DeploymentDurationInMinutes", Src::Body, 0.0),
251            Rule::RangeMax("DeploymentDurationInMinutes", Src::Body, 1440.0),
252            Rule::RangeMin("FinalBakeTimeInMinutes", Src::Body, 0.0),
253            Rule::RangeMax("FinalBakeTimeInMinutes", Src::Body, 1440.0),
254            Rule::Required("GrowthFactor", Src::Body),
255            Rule::RangeMin("GrowthFactor", Src::Body, 1.0),
256            Rule::RangeMax("GrowthFactor", Src::Body, 100.0),
257            Rule::Enum("GrowthType", Src::Body, &["LINEAR", "EXPONENTIAL"]),
258            Rule::Enum("ReplicateTo", Src::Body, &["NONE", "SSM_DOCUMENT"]),
259            Rule::LenMin("Tags", Src::Body, 0),
260            Rule::LenMax("Tags", Src::Body, 50),
261        ],
262        "CreateEnvironment" => vec![
263            Rule::Required("ApplicationId", Src::Label),
264            Rule::LenMin("ApplicationId", Src::Label, 1),
265            Rule::LenMax("ApplicationId", Src::Label, 64),
266            Rule::Required("Name", Src::Body),
267            Rule::LenMin("Name", Src::Body, 1),
268            Rule::LenMax("Name", Src::Body, 64),
269            Rule::LenMin("Description", Src::Body, 0),
270            Rule::LenMax("Description", Src::Body, 1024),
271            Rule::LenMin("Monitors", Src::Body, 0),
272            Rule::LenMax("Monitors", Src::Body, 5),
273            Rule::LenMin("Tags", Src::Body, 0),
274            Rule::LenMax("Tags", Src::Body, 50),
275        ],
276        "CreateExperimentDefinition" => vec![
277            Rule::Required("ApplicationIdentifier", Src::Label),
278            Rule::LenMin("ApplicationIdentifier", Src::Label, 1),
279            Rule::LenMax("ApplicationIdentifier", Src::Label, 2048),
280            Rule::Required("Name", Src::Body),
281            Rule::Required("ConfigurationProfileIdentifier", Src::Body),
282            Rule::LenMin("ConfigurationProfileIdentifier", Src::Body, 1),
283            Rule::LenMax("ConfigurationProfileIdentifier", Src::Body, 2048),
284            Rule::Required("EnvironmentIdentifier", Src::Body),
285            Rule::LenMin("EnvironmentIdentifier", Src::Body, 1),
286            Rule::LenMax("EnvironmentIdentifier", Src::Body, 2048),
287            Rule::Required("FlagKey", Src::Body),
288            Rule::Required("Treatments", Src::Body),
289            Rule::LenMin("Treatments", Src::Body, 1),
290            Rule::LenMax("Treatments", Src::Body, 5),
291            Rule::Required("Control", Src::Body),
292            Rule::Required("AudienceRule", Src::Body),
293            Rule::LenMin("AudienceRule", Src::Body, 1),
294            Rule::LenMax("AudienceRule", Src::Body, 16384),
295            Rule::LenMin("Hypothesis", Src::Body, 0),
296            Rule::LenMax("Hypothesis", Src::Body, 1024),
297            Rule::LenMin("AudienceDescription", Src::Body, 0),
298            Rule::LenMax("AudienceDescription", Src::Body, 1024),
299            Rule::LenMin("LaunchCriteria", Src::Body, 0),
300            Rule::LenMax("LaunchCriteria", Src::Body, 1024),
301            Rule::LenMin("Tags", Src::Body, 0),
302            Rule::LenMax("Tags", Src::Body, 50),
303        ],
304        "CreateExtension" => vec![
305            Rule::Required("Name", Src::Body),
306            Rule::LenMin("Description", Src::Body, 0),
307            Rule::LenMax("Description", Src::Body, 1024),
308            Rule::Required("Actions", Src::Body),
309            Rule::LenMin("Actions", Src::Body, 1),
310            Rule::LenMax("Actions", Src::Body, 5),
311            Rule::LenMin("Parameters", Src::Body, 1),
312            Rule::LenMax("Parameters", Src::Body, 10),
313            Rule::LenMin("Tags", Src::Body, 0),
314            Rule::LenMax("Tags", Src::Body, 50),
315        ],
316        "CreateExtensionAssociation" => vec![
317            Rule::Required("ExtensionIdentifier", Src::Body),
318            Rule::LenMin("ExtensionIdentifier", Src::Body, 1),
319            Rule::LenMax("ExtensionIdentifier", Src::Body, 2048),
320            Rule::Required("ResourceIdentifier", Src::Body),
321            Rule::LenMin("ResourceIdentifier", Src::Body, 1),
322            Rule::LenMax("ResourceIdentifier", Src::Body, 2048),
323            Rule::LenMin("Parameters", Src::Body, 0),
324            Rule::LenMax("Parameters", Src::Body, 10),
325            Rule::LenMin("Tags", Src::Body, 0),
326            Rule::LenMax("Tags", Src::Body, 50),
327        ],
328        "CreateHostedConfigurationVersion" => vec![
329            Rule::Required("ApplicationId", Src::Label),
330            Rule::LenMin("ApplicationId", Src::Label, 1),
331            Rule::LenMax("ApplicationId", Src::Label, 64),
332            Rule::Required("ConfigurationProfileId", Src::Label),
333            Rule::LenMin("ConfigurationProfileId", Src::Label, 1),
334            Rule::LenMax("ConfigurationProfileId", Src::Label, 128),
335        ],
336        "DeleteApplication" => vec![
337            Rule::Required("ApplicationId", Src::Label),
338            Rule::LenMin("ApplicationId", Src::Label, 1),
339            Rule::LenMax("ApplicationId", Src::Label, 64),
340        ],
341        "DeleteConfigurationProfile" => vec![
342            Rule::Required("ApplicationId", Src::Label),
343            Rule::LenMin("ApplicationId", Src::Label, 1),
344            Rule::LenMax("ApplicationId", Src::Label, 64),
345            Rule::Required("ConfigurationProfileId", Src::Label),
346            Rule::LenMin("ConfigurationProfileId", Src::Label, 1),
347            Rule::LenMax("ConfigurationProfileId", Src::Label, 128),
348        ],
349        "DeleteDeploymentStrategy" => vec![Rule::Required("DeploymentStrategyId", Src::Label)],
350        "DeleteEnvironment" => vec![
351            Rule::Required("EnvironmentId", Src::Label),
352            Rule::LenMin("EnvironmentId", Src::Label, 1),
353            Rule::LenMax("EnvironmentId", Src::Label, 64),
354            Rule::Required("ApplicationId", Src::Label),
355            Rule::LenMin("ApplicationId", Src::Label, 1),
356            Rule::LenMax("ApplicationId", Src::Label, 64),
357        ],
358        "DeleteExperimentDefinition" => vec![
359            Rule::Required("ApplicationIdentifier", Src::Label),
360            Rule::LenMin("ApplicationIdentifier", Src::Label, 1),
361            Rule::LenMax("ApplicationIdentifier", Src::Label, 2048),
362            Rule::Required("ExperimentDefinitionIdentifier", Src::Label),
363            Rule::LenMin("ExperimentDefinitionIdentifier", Src::Label, 1),
364            Rule::LenMax("ExperimentDefinitionIdentifier", Src::Label, 2048),
365            Rule::Enum("delete_type", Src::Query, &["ARCHIVE", "DESTROY"]),
366        ],
367        "DeleteExtension" => vec![
368            Rule::Required("ExtensionIdentifier", Src::Label),
369            Rule::LenMin("ExtensionIdentifier", Src::Label, 1),
370            Rule::LenMax("ExtensionIdentifier", Src::Label, 2048),
371        ],
372        "DeleteExtensionAssociation" => vec![Rule::Required("ExtensionAssociationId", Src::Label)],
373        "DeleteHostedConfigurationVersion" => vec![
374            Rule::Required("ApplicationId", Src::Label),
375            Rule::LenMin("ApplicationId", Src::Label, 1),
376            Rule::LenMax("ApplicationId", Src::Label, 64),
377            Rule::Required("ConfigurationProfileId", Src::Label),
378            Rule::LenMin("ConfigurationProfileId", Src::Label, 1),
379            Rule::LenMax("ConfigurationProfileId", Src::Label, 128),
380            Rule::Required("VersionNumber", Src::Label),
381        ],
382        "GetApplication" => vec![
383            Rule::Required("ApplicationId", Src::Label),
384            Rule::LenMin("ApplicationId", Src::Label, 1),
385            Rule::LenMax("ApplicationId", Src::Label, 64),
386        ],
387        "GetConfiguration" => vec![
388            Rule::Required("Application", Src::Label),
389            Rule::LenMin("Application", Src::Label, 1),
390            Rule::LenMax("Application", Src::Label, 64),
391            Rule::Required("Environment", Src::Label),
392            Rule::LenMin("Environment", Src::Label, 1),
393            Rule::LenMax("Environment", Src::Label, 64),
394            Rule::Required("Configuration", Src::Label),
395            Rule::LenMin("Configuration", Src::Label, 1),
396            Rule::LenMax("Configuration", Src::Label, 64),
397            Rule::Required("client_id", Src::Query),
398            Rule::LenMin("client_id", Src::Query, 1),
399            Rule::LenMax("client_id", Src::Query, 64),
400            Rule::LenMin("client_configuration_version", Src::Query, 1),
401            Rule::LenMax("client_configuration_version", Src::Query, 1024),
402        ],
403        "GetConfigurationProfile" => vec![
404            Rule::Required("ApplicationId", Src::Label),
405            Rule::LenMin("ApplicationId", Src::Label, 1),
406            Rule::LenMax("ApplicationId", Src::Label, 64),
407            Rule::Required("ConfigurationProfileId", Src::Label),
408            Rule::LenMin("ConfigurationProfileId", Src::Label, 1),
409            Rule::LenMax("ConfigurationProfileId", Src::Label, 128),
410        ],
411        "GetDeployment" => vec![
412            Rule::Required("ApplicationId", Src::Label),
413            Rule::LenMin("ApplicationId", Src::Label, 1),
414            Rule::LenMax("ApplicationId", Src::Label, 64),
415            Rule::Required("EnvironmentId", Src::Label),
416            Rule::LenMin("EnvironmentId", Src::Label, 1),
417            Rule::LenMax("EnvironmentId", Src::Label, 64),
418            Rule::Required("DeploymentNumber", Src::Label),
419        ],
420        "GetDeploymentStrategy" => vec![Rule::Required("DeploymentStrategyId", Src::Label)],
421        "GetEnvironment" => vec![
422            Rule::Required("ApplicationId", Src::Label),
423            Rule::LenMin("ApplicationId", Src::Label, 1),
424            Rule::LenMax("ApplicationId", Src::Label, 64),
425            Rule::Required("EnvironmentId", Src::Label),
426            Rule::LenMin("EnvironmentId", Src::Label, 1),
427            Rule::LenMax("EnvironmentId", Src::Label, 64),
428        ],
429        "GetExperimentDefinition" => vec![
430            Rule::Required("ApplicationIdentifier", Src::Label),
431            Rule::LenMin("ApplicationIdentifier", Src::Label, 1),
432            Rule::LenMax("ApplicationIdentifier", Src::Label, 2048),
433            Rule::Required("ExperimentDefinitionIdentifier", Src::Label),
434            Rule::LenMin("ExperimentDefinitionIdentifier", Src::Label, 1),
435            Rule::LenMax("ExperimentDefinitionIdentifier", Src::Label, 2048),
436        ],
437        "GetExperimentRun" => vec![
438            Rule::Required("ApplicationIdentifier", Src::Label),
439            Rule::LenMin("ApplicationIdentifier", Src::Label, 1),
440            Rule::LenMax("ApplicationIdentifier", Src::Label, 2048),
441            Rule::Required("ExperimentDefinitionIdentifier", Src::Label),
442            Rule::LenMin("ExperimentDefinitionIdentifier", Src::Label, 1),
443            Rule::LenMax("ExperimentDefinitionIdentifier", Src::Label, 2048),
444            Rule::Required("Run", Src::Label),
445            Rule::RangeMin("Run", Src::Label, 1.0),
446        ],
447        "GetExtension" => vec![
448            Rule::Required("ExtensionIdentifier", Src::Label),
449            Rule::LenMin("ExtensionIdentifier", Src::Label, 1),
450            Rule::LenMax("ExtensionIdentifier", Src::Label, 2048),
451        ],
452        "GetExtensionAssociation" => vec![Rule::Required("ExtensionAssociationId", Src::Label)],
453        "GetHostedConfigurationVersion" => vec![
454            Rule::Required("ApplicationId", Src::Label),
455            Rule::LenMin("ApplicationId", Src::Label, 1),
456            Rule::LenMax("ApplicationId", Src::Label, 64),
457            Rule::Required("ConfigurationProfileId", Src::Label),
458            Rule::LenMin("ConfigurationProfileId", Src::Label, 1),
459            Rule::LenMax("ConfigurationProfileId", Src::Label, 128),
460            Rule::Required("VersionNumber", Src::Label),
461        ],
462        "ListApplications" => vec![
463            Rule::RangeMin("max_results", Src::Query, 1.0),
464            Rule::RangeMax("max_results", Src::Query, 50.0),
465            Rule::LenMin("next_token", Src::Query, 1),
466            Rule::LenMax("next_token", Src::Query, 2048),
467        ],
468        "ListConfigurationProfiles" => vec![
469            Rule::Required("ApplicationId", Src::Label),
470            Rule::LenMin("ApplicationId", Src::Label, 1),
471            Rule::LenMax("ApplicationId", Src::Label, 64),
472            Rule::RangeMin("max_results", Src::Query, 1.0),
473            Rule::RangeMax("max_results", Src::Query, 50.0),
474            Rule::LenMin("next_token", Src::Query, 1),
475            Rule::LenMax("next_token", Src::Query, 2048),
476        ],
477        "ListDeploymentStrategies" => vec![
478            Rule::RangeMin("max_results", Src::Query, 1.0),
479            Rule::RangeMax("max_results", Src::Query, 50.0),
480            Rule::LenMin("next_token", Src::Query, 1),
481            Rule::LenMax("next_token", Src::Query, 2048),
482        ],
483        "ListDeployments" => vec![
484            Rule::Required("ApplicationId", Src::Label),
485            Rule::LenMin("ApplicationId", Src::Label, 1),
486            Rule::LenMax("ApplicationId", Src::Label, 64),
487            Rule::Required("EnvironmentId", Src::Label),
488            Rule::LenMin("EnvironmentId", Src::Label, 1),
489            Rule::LenMax("EnvironmentId", Src::Label, 64),
490            Rule::RangeMin("max_results", Src::Query, 1.0),
491            Rule::RangeMax("max_results", Src::Query, 50.0),
492            Rule::LenMin("next_token", Src::Query, 1),
493            Rule::LenMax("next_token", Src::Query, 2048),
494        ],
495        "ListEnvironments" => vec![
496            Rule::Required("ApplicationId", Src::Label),
497            Rule::LenMin("ApplicationId", Src::Label, 1),
498            Rule::LenMax("ApplicationId", Src::Label, 64),
499            Rule::RangeMin("max_results", Src::Query, 1.0),
500            Rule::RangeMax("max_results", Src::Query, 50.0),
501            Rule::LenMin("next_token", Src::Query, 1),
502            Rule::LenMax("next_token", Src::Query, 2048),
503        ],
504        "ListExperimentDefinitions" => vec![
505            Rule::LenMin("application_identifier", Src::Query, 1),
506            Rule::LenMax("application_identifier", Src::Query, 2048),
507            Rule::LenMin("configuration_profile_identifier", Src::Query, 1),
508            Rule::LenMax("configuration_profile_identifier", Src::Query, 2048),
509            Rule::LenMin("environment_identifier", Src::Query, 1),
510            Rule::LenMax("environment_identifier", Src::Query, 2048),
511            Rule::Enum("status", Src::Query, &["ACTIVE", "IDLE", "ARCHIVED"]),
512            Rule::RangeMin("max_results", Src::Query, 1.0),
513            Rule::RangeMax("max_results", Src::Query, 50.0),
514            Rule::LenMin("next_token", Src::Query, 1),
515            Rule::LenMax("next_token", Src::Query, 2048),
516        ],
517        "ListExperimentRunEvents" => vec![
518            Rule::Required("ApplicationIdentifier", Src::Label),
519            Rule::LenMin("ApplicationIdentifier", Src::Label, 1),
520            Rule::LenMax("ApplicationIdentifier", Src::Label, 2048),
521            Rule::Required("ExperimentDefinitionIdentifier", Src::Label),
522            Rule::LenMin("ExperimentDefinitionIdentifier", Src::Label, 1),
523            Rule::LenMax("ExperimentDefinitionIdentifier", Src::Label, 2048),
524            Rule::Required("Run", Src::Label),
525            Rule::RangeMin("Run", Src::Label, 1.0),
526            Rule::RangeMin("max_results", Src::Query, 1.0),
527            Rule::RangeMax("max_results", Src::Query, 50.0),
528            Rule::LenMin("next_token", Src::Query, 1),
529            Rule::LenMax("next_token", Src::Query, 2048),
530        ],
531        "ListExperimentRuns" => vec![
532            Rule::Required("ApplicationIdentifier", Src::Label),
533            Rule::LenMin("ApplicationIdentifier", Src::Label, 1),
534            Rule::LenMax("ApplicationIdentifier", Src::Label, 2048),
535            Rule::Required("ExperimentDefinitionIdentifier", Src::Label),
536            Rule::LenMin("ExperimentDefinitionIdentifier", Src::Label, 1),
537            Rule::LenMax("ExperimentDefinitionIdentifier", Src::Label, 2048),
538            Rule::RangeMin("max_results", Src::Query, 1.0),
539            Rule::RangeMax("max_results", Src::Query, 50.0),
540            Rule::LenMin("next_token", Src::Query, 1),
541            Rule::LenMax("next_token", Src::Query, 2048),
542            Rule::Enum("status", Src::Query, &["RUNNING", "DONE"]),
543        ],
544        "ListExtensionAssociations" => vec![
545            Rule::LenMin("resource_identifier", Src::Query, 20),
546            Rule::LenMax("resource_identifier", Src::Query, 2048),
547            Rule::LenMin("extension_identifier", Src::Query, 1),
548            Rule::LenMax("extension_identifier", Src::Query, 2048),
549            Rule::RangeMin("max_results", Src::Query, 1.0),
550            Rule::RangeMax("max_results", Src::Query, 50.0),
551            Rule::LenMin("next_token", Src::Query, 1),
552            Rule::LenMax("next_token", Src::Query, 2048),
553        ],
554        "ListExtensions" => vec![
555            Rule::RangeMin("max_results", Src::Query, 1.0),
556            Rule::RangeMax("max_results", Src::Query, 50.0),
557            Rule::LenMin("next_token", Src::Query, 1),
558            Rule::LenMax("next_token", Src::Query, 2048),
559            Rule::LenMin("name", Src::Query, 1),
560            Rule::LenMax("name", Src::Query, 64),
561        ],
562        "ListHostedConfigurationVersions" => vec![
563            Rule::Required("ApplicationId", Src::Label),
564            Rule::LenMin("ApplicationId", Src::Label, 1),
565            Rule::LenMax("ApplicationId", Src::Label, 64),
566            Rule::Required("ConfigurationProfileId", Src::Label),
567            Rule::LenMin("ConfigurationProfileId", Src::Label, 1),
568            Rule::LenMax("ConfigurationProfileId", Src::Label, 128),
569            Rule::RangeMin("max_results", Src::Query, 1.0),
570            Rule::RangeMax("max_results", Src::Query, 50.0),
571            Rule::LenMin("next_token", Src::Query, 1),
572            Rule::LenMax("next_token", Src::Query, 2048),
573            Rule::LenMin("version_label", Src::Query, 1),
574            Rule::LenMax("version_label", Src::Query, 64),
575        ],
576        "ListTagsForResource" => vec![
577            Rule::Required("ResourceArn", Src::Label),
578            Rule::LenMin("ResourceArn", Src::Label, 20),
579            Rule::LenMax("ResourceArn", Src::Label, 2048),
580        ],
581        "StartDeployment" => vec![
582            Rule::Required("ApplicationId", Src::Label),
583            Rule::LenMin("ApplicationId", Src::Label, 1),
584            Rule::LenMax("ApplicationId", Src::Label, 64),
585            Rule::Required("EnvironmentId", Src::Label),
586            Rule::LenMin("EnvironmentId", Src::Label, 1),
587            Rule::LenMax("EnvironmentId", Src::Label, 64),
588            Rule::Required("DeploymentStrategyId", Src::Body),
589            Rule::Required("ConfigurationProfileId", Src::Body),
590            Rule::LenMin("ConfigurationProfileId", Src::Body, 1),
591            Rule::LenMax("ConfigurationProfileId", Src::Body, 128),
592            Rule::Required("ConfigurationVersion", Src::Body),
593            Rule::LenMin("ConfigurationVersion", Src::Body, 1),
594            Rule::LenMax("ConfigurationVersion", Src::Body, 1024),
595            Rule::LenMin("Description", Src::Body, 0),
596            Rule::LenMax("Description", Src::Body, 1024),
597            Rule::LenMin("Tags", Src::Body, 0),
598            Rule::LenMax("Tags", Src::Body, 50),
599            Rule::LenMin("KmsKeyIdentifier", Src::Body, 1),
600            Rule::LenMax("KmsKeyIdentifier", Src::Body, 2048),
601            Rule::LenMin("DynamicExtensionParameters", Src::Body, 1),
602            Rule::LenMax("DynamicExtensionParameters", Src::Body, 10),
603        ],
604        "StartExperimentRun" => vec![
605            Rule::Required("ApplicationIdentifier", Src::Label),
606            Rule::LenMin("ApplicationIdentifier", Src::Label, 1),
607            Rule::LenMax("ApplicationIdentifier", Src::Label, 2048),
608            Rule::Required("ExperimentDefinitionIdentifier", Src::Label),
609            Rule::LenMin("ExperimentDefinitionIdentifier", Src::Label, 1),
610            Rule::LenMax("ExperimentDefinitionIdentifier", Src::Label, 2048),
611            Rule::LenMin("Description", Src::Body, 0),
612            Rule::LenMax("Description", Src::Body, 1024),
613            Rule::RangeMin("ExposurePercentage", Src::Body, 0.0),
614            Rule::RangeMax("ExposurePercentage", Src::Body, 100.0),
615            Rule::LenMin("Tags", Src::Body, 0),
616            Rule::LenMax("Tags", Src::Body, 50),
617        ],
618        "StopDeployment" => vec![
619            Rule::Required("ApplicationId", Src::Label),
620            Rule::LenMin("ApplicationId", Src::Label, 1),
621            Rule::LenMax("ApplicationId", Src::Label, 64),
622            Rule::Required("EnvironmentId", Src::Label),
623            Rule::LenMin("EnvironmentId", Src::Label, 1),
624            Rule::LenMax("EnvironmentId", Src::Label, 64),
625            Rule::Required("DeploymentNumber", Src::Label),
626        ],
627        "StopExperimentRun" => vec![
628            Rule::Required("ApplicationIdentifier", Src::Label),
629            Rule::LenMin("ApplicationIdentifier", Src::Label, 1),
630            Rule::LenMax("ApplicationIdentifier", Src::Label, 2048),
631            Rule::Required("ExperimentDefinitionIdentifier", Src::Label),
632            Rule::LenMin("ExperimentDefinitionIdentifier", Src::Label, 1),
633            Rule::LenMax("ExperimentDefinitionIdentifier", Src::Label, 2048),
634            Rule::Required("Run", Src::Label),
635            Rule::RangeMin("Run", Src::Label, 1.0),
636        ],
637        "TagResource" => vec![
638            Rule::Required("ResourceArn", Src::Label),
639            Rule::LenMin("ResourceArn", Src::Label, 20),
640            Rule::LenMax("ResourceArn", Src::Label, 2048),
641            Rule::Required("Tags", Src::Body),
642            Rule::LenMin("Tags", Src::Body, 0),
643            Rule::LenMax("Tags", Src::Body, 50),
644        ],
645        "UntagResource" => vec![
646            Rule::Required("ResourceArn", Src::Label),
647            Rule::LenMin("ResourceArn", Src::Label, 20),
648            Rule::LenMax("ResourceArn", Src::Label, 2048),
649            Rule::Required("tagKeys", Src::Query),
650            Rule::LenMin("tagKeys", Src::Query, 0),
651            Rule::LenMax("tagKeys", Src::Query, 50),
652        ],
653        "UpdateApplication" => vec![
654            Rule::Required("ApplicationId", Src::Label),
655            Rule::LenMin("ApplicationId", Src::Label, 1),
656            Rule::LenMax("ApplicationId", Src::Label, 64),
657            Rule::LenMin("Name", Src::Body, 1),
658            Rule::LenMax("Name", Src::Body, 64),
659            Rule::LenMin("Description", Src::Body, 0),
660            Rule::LenMax("Description", Src::Body, 1024),
661        ],
662        "UpdateConfigurationProfile" => vec![
663            Rule::Required("ApplicationId", Src::Label),
664            Rule::LenMin("ApplicationId", Src::Label, 1),
665            Rule::LenMax("ApplicationId", Src::Label, 64),
666            Rule::Required("ConfigurationProfileId", Src::Label),
667            Rule::LenMin("ConfigurationProfileId", Src::Label, 1),
668            Rule::LenMax("ConfigurationProfileId", Src::Label, 128),
669            Rule::LenMin("Name", Src::Body, 1),
670            Rule::LenMax("Name", Src::Body, 128),
671            Rule::LenMin("Description", Src::Body, 0),
672            Rule::LenMax("Description", Src::Body, 1024),
673            Rule::LenMin("RetrievalRoleArn", Src::Body, 20),
674            Rule::LenMax("RetrievalRoleArn", Src::Body, 2048),
675            Rule::LenMin("Validators", Src::Body, 0),
676            Rule::LenMax("Validators", Src::Body, 2),
677            Rule::LenMin("KmsKeyIdentifier", Src::Body, 0),
678            Rule::LenMax("KmsKeyIdentifier", Src::Body, 2048),
679        ],
680        "UpdateDeploymentStrategy" => vec![
681            Rule::Required("DeploymentStrategyId", Src::Label),
682            Rule::LenMin("Description", Src::Body, 0),
683            Rule::LenMax("Description", Src::Body, 1024),
684            Rule::RangeMin("DeploymentDurationInMinutes", Src::Body, 0.0),
685            Rule::RangeMax("DeploymentDurationInMinutes", Src::Body, 1440.0),
686            Rule::RangeMin("FinalBakeTimeInMinutes", Src::Body, 0.0),
687            Rule::RangeMax("FinalBakeTimeInMinutes", Src::Body, 1440.0),
688            Rule::RangeMin("GrowthFactor", Src::Body, 1.0),
689            Rule::RangeMax("GrowthFactor", Src::Body, 100.0),
690            Rule::Enum("GrowthType", Src::Body, &["LINEAR", "EXPONENTIAL"]),
691        ],
692        "UpdateEnvironment" => vec![
693            Rule::Required("ApplicationId", Src::Label),
694            Rule::LenMin("ApplicationId", Src::Label, 1),
695            Rule::LenMax("ApplicationId", Src::Label, 64),
696            Rule::Required("EnvironmentId", Src::Label),
697            Rule::LenMin("EnvironmentId", Src::Label, 1),
698            Rule::LenMax("EnvironmentId", Src::Label, 64),
699            Rule::LenMin("Name", Src::Body, 1),
700            Rule::LenMax("Name", Src::Body, 64),
701            Rule::LenMin("Description", Src::Body, 0),
702            Rule::LenMax("Description", Src::Body, 1024),
703            Rule::LenMin("Monitors", Src::Body, 0),
704            Rule::LenMax("Monitors", Src::Body, 5),
705        ],
706        "UpdateExperimentDefinition" => vec![
707            Rule::Required("ApplicationIdentifier", Src::Label),
708            Rule::LenMin("ApplicationIdentifier", Src::Label, 1),
709            Rule::LenMax("ApplicationIdentifier", Src::Label, 2048),
710            Rule::Required("ExperimentDefinitionIdentifier", Src::Label),
711            Rule::LenMin("ExperimentDefinitionIdentifier", Src::Label, 1),
712            Rule::LenMax("ExperimentDefinitionIdentifier", Src::Label, 2048),
713            Rule::LenMin("Treatments", Src::Body, 1),
714            Rule::LenMax("Treatments", Src::Body, 5),
715            Rule::LenMin("Hypothesis", Src::Body, 0),
716            Rule::LenMax("Hypothesis", Src::Body, 1024),
717            Rule::LenMin("AudienceRule", Src::Body, 1),
718            Rule::LenMax("AudienceRule", Src::Body, 16384),
719            Rule::LenMin("AudienceDescription", Src::Body, 0),
720            Rule::LenMax("AudienceDescription", Src::Body, 1024),
721            Rule::LenMin("LaunchCriteria", Src::Body, 0),
722            Rule::LenMax("LaunchCriteria", Src::Body, 1024),
723        ],
724        "UpdateExperimentRun" => vec![
725            Rule::Required("ApplicationIdentifier", Src::Label),
726            Rule::LenMin("ApplicationIdentifier", Src::Label, 1),
727            Rule::LenMax("ApplicationIdentifier", Src::Label, 2048),
728            Rule::Required("ExperimentDefinitionIdentifier", Src::Label),
729            Rule::LenMin("ExperimentDefinitionIdentifier", Src::Label, 1),
730            Rule::LenMax("ExperimentDefinitionIdentifier", Src::Label, 2048),
731            Rule::Required("Run", Src::Label),
732            Rule::RangeMin("Run", Src::Label, 1.0),
733            Rule::LenMin("Description", Src::Body, 0),
734            Rule::LenMax("Description", Src::Body, 1024),
735            Rule::RangeMin("ExposurePercentage", Src::Body, 0.0),
736            Rule::RangeMax("ExposurePercentage", Src::Body, 100.0),
737        ],
738        "UpdateExtension" => vec![
739            Rule::Required("ExtensionIdentifier", Src::Label),
740            Rule::LenMin("ExtensionIdentifier", Src::Label, 1),
741            Rule::LenMax("ExtensionIdentifier", Src::Label, 2048),
742            Rule::LenMin("Description", Src::Body, 0),
743            Rule::LenMax("Description", Src::Body, 1024),
744            Rule::LenMin("Actions", Src::Body, 1),
745            Rule::LenMax("Actions", Src::Body, 5),
746            Rule::LenMin("Parameters", Src::Body, 1),
747            Rule::LenMax("Parameters", Src::Body, 10),
748        ],
749        "UpdateExtensionAssociation" => vec![
750            Rule::Required("ExtensionAssociationId", Src::Label),
751            Rule::LenMin("Parameters", Src::Body, 0),
752            Rule::LenMax("Parameters", Src::Body, 10),
753        ],
754        "ValidateConfiguration" => vec![
755            Rule::Required("ApplicationId", Src::Label),
756            Rule::LenMin("ApplicationId", Src::Label, 1),
757            Rule::LenMax("ApplicationId", Src::Label, 64),
758            Rule::Required("ConfigurationProfileId", Src::Label),
759            Rule::LenMin("ConfigurationProfileId", Src::Label, 1),
760            Rule::LenMax("ConfigurationProfileId", Src::Label, 128),
761            Rule::Required("configuration_version", Src::Query),
762            Rule::LenMin("configuration_version", Src::Query, 1),
763            Rule::LenMax("configuration_version", Src::Query, 1024),
764        ],
765        _ => vec![],
766    }
767}