cloudformation-validate-template-model 1.15.0

AWS CloudFormation Validate
Documentation
use crate::json_value::JsonValue;
use serde::Serialize;
use std::collections::HashMap;

/// Advanced introspection view of a parsed CloudFormation template: its reference graph,
/// conditions, and resolved resources and outputs.
#[derive(Debug, Clone, Serialize)]
#[cfg_attr(feature = "wasm-bindings", derive(tsify::Tsify))]
#[cfg_attr(feature = "uniffi-bindings", derive(uniffi::Record))]
#[serde(rename_all = "camelCase")]
pub struct DiagnosticModel {
    pub template: DiagnosticTemplate,
    #[cfg_attr(feature = "wasm-bindings", tsify(type = "Record<string, JsonValue>"))]
    pub parameters: HashMap<String, JsonValue>,
    #[cfg_attr(feature = "wasm-bindings", tsify(type = "Record<string, DiagnosticCondition>"))]
    pub conditions: HashMap<String, DiagnosticCondition>,
    /// Parameter logical IDs referenced by the template's condition expressions.
    pub condition_param_refs: Vec<String>,
    /// Logical implications between conditions: if the antecedent condition holds, the consequent condition must also hold.
    pub condition_implications: Vec<DiagnosticImplication>,
    /// Groups of conditions that are mutually exclusive because they test the same parameter against different values.
    pub condition_mutex_groups: Vec<DiagnosticMutexGroup>,
    /// Pairs of condition names that can never both be true at the same time.
    pub condition_exclusions: Vec<Vec<String>>,
    /// Maps each resource's logical ID to the name of the condition that gates whether it is created.
    #[cfg_attr(feature = "wasm-bindings", tsify(type = "Record<string, string>"))]
    pub resource_condition_map: HashMap<String, String>,
    pub mappings: JsonValue,
    #[cfg_attr(feature = "wasm-bindings", tsify(type = "Record<string, DiagnosticResource>"))]
    pub resources: HashMap<String, DiagnosticResource>,
    #[cfg_attr(feature = "wasm-bindings", tsify(type = "Record<string, DiagnosticOutput>"))]
    pub outputs: HashMap<String, DiagnosticOutput>,
    pub edges: Vec<ReferenceEdge>,
    /// Reference cycles in the template, each listed as the resource logical IDs forming the cycle.
    pub cycles: Vec<Vec<String>>,
    /// Output names whose value is an Fn::Join with an empty delimiter.
    pub output_empty_joins: Vec<String>,
    /// Logical IDs of resources the SAM transform generates implicitly (such as function execution roles and an implicit REST API).
    pub sam_implicit_resources: Vec<String>,
    /// Parameter logical IDs referenced from the SAM Globals section.
    pub globals_param_refs: Vec<String>,
    /// True when the template appears to be generated by the AWS CDK.
    pub is_cdk: bool,
    /// Names of conditions referenced by Fn::If expressions in the template.
    pub fn_if_conditions: Vec<String>,
    /// Mapping names referenced by Fn::FindInMap expressions.
    pub find_in_map_names: Vec<String>,
    /// Parameter logical IDs referenced from within other parameters' own definitions.
    pub params_referenced_in_definitions: Vec<String>,
    /// True when a Fn::FindInMap uses a computed mapping name rather than a literal string.
    pub has_dynamic_findinmap_name: bool,
    /// True when the template could not be fully parsed and the model is therefore incomplete.
    pub has_parse_errors: bool,
    /// The template's Rules section, each with its optional condition and assertions.
    pub parsed_rules: Vec<DiagnosticRule>,
    /// For resolved resource properties, records where each value came from (such as a parameter default, allowed values, an override, or an intrinsic).
    pub resolution_sources: Vec<ResolutionSource>,
}

/// Top-level template metadata.
#[derive(Debug, Clone, Serialize)]
#[cfg_attr(feature = "wasm-bindings", derive(tsify::Tsify))]
#[cfg_attr(feature = "uniffi-bindings", derive(uniffi::Record))]
#[serde(rename_all = "camelCase")]
pub struct DiagnosticTemplate {
    #[cfg_attr(feature = "wasm-bindings", tsify(optional))]
    #[cfg_attr(feature = "uniffi-bindings", uniffi(default))]
    pub format_version: Option<String>,
    #[cfg_attr(feature = "wasm-bindings", tsify(optional))]
    #[cfg_attr(feature = "uniffi-bindings", uniffi(default))]
    pub description: Option<String>,
    pub transforms: Vec<String>,
    /// The top-level section names present in the template as written.
    pub raw_top_level_keys: Vec<String>,
}

/// A single Conditions entry with its expression and relationships to other conditions.
#[derive(Debug, Clone, Serialize)]
#[cfg_attr(feature = "wasm-bindings", derive(tsify::Tsify))]
#[cfg_attr(feature = "uniffi-bindings", derive(uniffi::Record))]
#[serde(rename_all = "camelCase")]
pub struct DiagnosticCondition {
    /// The condition expression rendered as a readable string.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[cfg_attr(feature = "uniffi-bindings", uniffi(default))]
    pub expression: Option<String>,
    /// Names of other conditions this condition depends on.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[cfg_attr(feature = "uniffi-bindings", uniffi(default))]
    pub deps: Option<Vec<String>>,
    /// Names of conditions that are mutually exclusive with this one.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[cfg_attr(feature = "uniffi-bindings", uniffi(default))]
    pub mutex_with: Option<Vec<String>>,
}

/// An implication between two conditions: whenever the antecedent holds, the consequent also holds.
#[derive(Debug, Clone, Serialize)]
#[cfg_attr(feature = "wasm-bindings", derive(tsify::Tsify))]
#[cfg_attr(feature = "uniffi-bindings", derive(uniffi::Record))]
#[serde(rename_all = "camelCase")]
pub struct DiagnosticImplication {
    pub antecedent: String,
    pub consequent: String,
}

/// A set of conditions that are mutually exclusive because they test the same parameter against different values.
#[derive(Debug, Clone, Serialize)]
#[cfg_attr(feature = "wasm-bindings", derive(tsify::Tsify))]
#[cfg_attr(feature = "uniffi-bindings", derive(uniffi::Record))]
#[serde(rename_all = "camelCase")]
pub struct DiagnosticMutexGroup {
    pub conditions: Vec<String>,
    /// The parameter all conditions in the group test.
    pub parameter: String,
    /// The distinct parameter values the conditions compare against, one per condition.
    pub values: Vec<String>,
}

/// A single edge in the template's reference graph, from a referencing resource to its target.
#[derive(Debug, Clone, Serialize)]
#[cfg_attr(feature = "wasm-bindings", derive(tsify::Tsify))]
#[cfg_attr(feature = "uniffi-bindings", derive(uniffi::Record))]
#[serde(rename_all = "camelCase")]
pub struct ReferenceEdge {
    /// Logical ID of the resource that makes the reference.
    pub source: String,
    /// Property path within the source where the reference occurs.
    pub source_path: String,
    /// Logical ID of the referenced resource or parameter.
    pub target: String,
    /// How the reference is made, such as Ref, GetAtt, Sub, or DependsOn.
    pub kind: String,
    /// For a GetAtt or Sub reference, the attribute or variable name being referenced.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[cfg_attr(feature = "uniffi-bindings", uniffi(default))]
    pub attr: Option<String>,
    /// Name of the condition under which this reference is active, if it is inside a conditional branch.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[cfg_attr(feature = "uniffi-bindings", uniffi(default))]
    pub condition_context: Option<String>,
}

/// A reference a resource makes to another resource or parameter.
#[derive(Debug, Clone, Serialize)]
#[cfg_attr(feature = "wasm-bindings", derive(tsify::Tsify))]
#[cfg_attr(feature = "uniffi-bindings", derive(uniffi::Record))]
#[serde(rename_all = "camelCase")]
pub struct OutgoingRef {
    /// Property path within the resource where the reference occurs.
    pub source_path: String,
    /// Logical ID of the referenced resource or parameter.
    pub target: String,
    /// How the reference is made, such as Ref, GetAtt, Sub, or DependsOn.
    pub kind: String,
    /// For a GetAtt or Sub reference, the attribute or variable name being referenced.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[cfg_attr(feature = "uniffi-bindings", uniffi(default))]
    pub attr: Option<String>,
    /// Name of the condition under which this reference is active, if it is inside a conditional branch.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[cfg_attr(feature = "uniffi-bindings", uniffi(default))]
    pub condition_context: Option<String>,
}

/// A reference made to this resource by another resource.
#[derive(Debug, Clone, Serialize)]
#[cfg_attr(feature = "wasm-bindings", derive(tsify::Tsify))]
#[cfg_attr(feature = "uniffi-bindings", derive(uniffi::Record))]
#[serde(rename_all = "camelCase")]
pub struct IncomingRef {
    /// Logical ID of the resource that makes the reference.
    pub source: String,
    /// Property path within the source where the reference occurs.
    pub source_path: String,
    /// How the reference is made, such as Ref, GetAtt, Sub, or DependsOn.
    pub kind: String,
    /// For a GetAtt or Sub reference, the attribute or variable name being referenced.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[cfg_attr(feature = "uniffi-bindings", uniffi(default))]
    pub attr: Option<String>,
}

/// A resource after intrinsic resolution, with its properties, references, and detected findings.
#[derive(Debug, Clone, Serialize)]
#[cfg_attr(feature = "wasm-bindings", derive(tsify::Tsify))]
#[cfg_attr(feature = "uniffi-bindings", derive(uniffi::Record))]
#[serde(rename_all = "camelCase")]
pub struct DiagnosticResource {
    pub resource_type: String,
    /// Name of the condition gating whether this resource is created, if any.
    #[cfg_attr(feature = "wasm-bindings", tsify(optional))]
    #[cfg_attr(feature = "uniffi-bindings", uniffi(default))]
    pub condition: Option<String>,
    pub depends_on: Vec<String>,
    #[cfg_attr(feature = "wasm-bindings", tsify(optional))]
    #[cfg_attr(feature = "uniffi-bindings", uniffi(default))]
    pub deletion_policy: Option<JsonValue>,
    #[cfg_attr(feature = "wasm-bindings", tsify(optional))]
    #[cfg_attr(feature = "uniffi-bindings", uniffi(default))]
    pub update_replace_policy: Option<JsonValue>,
    #[cfg_attr(feature = "wasm-bindings", tsify(optional))]
    #[cfg_attr(feature = "uniffi-bindings", uniffi(default))]
    pub creation_policy: Option<JsonValue>,
    #[cfg_attr(feature = "wasm-bindings", tsify(optional))]
    #[cfg_attr(feature = "uniffi-bindings", uniffi(default))]
    pub update_policy: Option<JsonValue>,
    /// The resource's properties with intrinsics resolved where possible.
    #[cfg_attr(feature = "wasm-bindings", tsify(type = "Record<string, JsonValue>"))]
    pub properties: HashMap<String, JsonValue>,
    pub outgoing_refs: Vec<OutgoingRef>,
    pub incoming_refs: Vec<IncomingRef>,
    /// Mapping names referenced by Fn::FindInMap within this resource.
    pub find_in_map_refs: Vec<String>,
    /// Fn::Sub uses whose template is a single variable with no surrounding text, which could be written as a plain reference.
    pub simple_subs: Vec<PathVariable>,
    /// Property paths where Fn::Sub has no variables to substitute.
    pub redundant_subs: Vec<String>,
    /// Property paths where Fn::Join uses an empty delimiter, concatenating its elements directly.
    pub empty_joins: Vec<String>,
    /// Property paths where an ARN hardcodes the aws partition instead of using AWS::Partition.
    pub hardcoded_partition_arns: Vec<String>,
    /// Properties that resolve to null in one branch of a condition.
    pub conditionally_null_props: Vec<ConditionalNull>,
    /// Names of conditions referenced within this resource's properties.
    pub condition_refs: Vec<String>,
    /// Fn::ForEach loops in this resource, each with its iteration variable and collection source.
    pub for_each_expansions: Vec<DiagnosticForEachExpansion>,
    /// Property paths containing ${...} text that is not an Fn::Sub variable and is left as a literal.
    pub unsubstituted_variables: Vec<PathVariable>,
    /// Fn::Sub map keys not referenced in the template string, each with its path and the unused key name.
    pub unused_sub_keys: Vec<PathVariable>,
    /// Property values that are a raw pseudo-parameter string instead of using Ref, each with its path and the pseudo-parameter name.
    pub raw_pseudo_params: Vec<PathVariable>,
    /// Property paths containing a {{resolve:secretsmanager:...}} dynamic reference.
    pub secretsmanager_ref_paths: Vec<String>,
    /// References whose target does not resolve to any resource or parameter, each with its path and unresolved target.
    pub invalid_refs: Vec<PathTarget>,
}

/// A property path paired with a variable name referenced there.
#[derive(Debug, Clone, Serialize)]
#[cfg_attr(feature = "wasm-bindings", derive(tsify::Tsify))]
#[cfg_attr(feature = "uniffi-bindings", derive(uniffi::Record))]
pub struct PathVariable {
    pub path: String,
    pub variable: String,
}

/// A property that resolves to null in one branch of a condition.
#[derive(Debug, Clone, Serialize)]
#[cfg_attr(feature = "wasm-bindings", derive(tsify::Tsify))]
#[cfg_attr(feature = "uniffi-bindings", derive(uniffi::Record))]
#[serde(rename_all = "camelCase")]
pub struct ConditionalNull {
    pub path: String,
    pub condition: String,
    /// True if the property is null in the condition's true branch; false if null in the false branch.
    pub null_in_true: bool,
}

/// An Fn::ForEach loop within a resource.
#[derive(Debug, Clone, Serialize)]
#[cfg_attr(feature = "wasm-bindings", derive(tsify::Tsify))]
#[cfg_attr(feature = "uniffi-bindings", derive(uniffi::Record))]
pub struct DiagnosticForEachExpansion {
    /// Property path where the Fn::ForEach occurs.
    pub path: String,
    /// The loop's iteration variable name.
    pub identifier: String,
    /// A description of the collection the loop iterates over, such as a reference to a parameter, an inline list, or a dynamic value.
    pub collection: String,
}

/// A property path paired with the reference target found there.
#[derive(Debug, Clone, Serialize)]
#[cfg_attr(feature = "wasm-bindings", derive(tsify::Tsify))]
#[cfg_attr(feature = "uniffi-bindings", derive(uniffi::Record))]
pub struct PathTarget {
    pub path: String,
    pub target: String,
}

/// An Fn::GetAtt reference to a resource attribute.
#[derive(Debug, Clone, Serialize)]
#[cfg_attr(feature = "wasm-bindings", derive(tsify::Tsify))]
#[cfg_attr(feature = "uniffi-bindings", derive(uniffi::Record))]
#[serde(rename_all = "camelCase")]
pub struct GetAttRef {
    /// Logical ID of the resource whose attribute is referenced.
    pub resource: String,
    pub attribute: String,
}

/// A template output after intrinsic resolution, with its references.
#[derive(Debug, Clone, Serialize)]
#[cfg_attr(feature = "wasm-bindings", derive(tsify::Tsify))]
#[cfg_attr(feature = "uniffi-bindings", derive(uniffi::Record))]
#[serde(rename_all = "camelCase")]
pub struct DiagnosticOutput {
    /// The output value with intrinsics resolved where possible.
    pub value: JsonValue,
    #[cfg_attr(feature = "wasm-bindings", tsify(optional))]
    #[cfg_attr(feature = "uniffi-bindings", uniffi(default))]
    pub description: Option<String>,
    /// Name of the condition gating whether this output is emitted, if any.
    #[cfg_attr(feature = "wasm-bindings", tsify(optional))]
    #[cfg_attr(feature = "uniffi-bindings", uniffi(default))]
    pub condition: Option<String>,
    #[cfg_attr(feature = "wasm-bindings", tsify(optional))]
    #[cfg_attr(feature = "uniffi-bindings", uniffi(default))]
    pub export_name: Option<JsonValue>,
    /// Fn::GetAtt references appearing in the output value.
    pub getatt_refs: Vec<GetAttRef>,
    /// Names of conditions referenced within the output value.
    pub condition_refs: Vec<String>,
}

/// An entry from the template's Rules section.
#[derive(Debug, Clone, Serialize)]
#[cfg_attr(feature = "wasm-bindings", derive(tsify::Tsify))]
#[cfg_attr(feature = "uniffi-bindings", derive(uniffi::Record))]
#[serde(rename_all = "camelCase")]
pub struct DiagnosticRule {
    pub name: String,
    /// The rule's RuleCondition expression, if present, that gates when the assertions apply.
    #[cfg_attr(feature = "wasm-bindings", tsify(optional))]
    #[cfg_attr(feature = "uniffi-bindings", uniffi(default))]
    pub condition: Option<JsonValue>,
    pub assertions: Vec<DiagnosticRuleAssertion>,
}

/// A single assertion within a template rule.
#[derive(Debug, Clone, Serialize)]
#[cfg_attr(feature = "wasm-bindings", derive(tsify::Tsify))]
#[cfg_attr(feature = "uniffi-bindings", derive(uniffi::Record))]
#[serde(rename_all = "camelCase")]
pub struct DiagnosticRuleAssertion {
    /// The assertion expression that must evaluate to true.
    pub assert_expr: JsonValue,
    #[serde(skip_serializing_if = "Option::is_none")]
    #[cfg_attr(feature = "uniffi-bindings", uniffi(default))]
    pub assert_description: Option<String>,
}

/// Records where a resolved resource property value came from.
#[derive(Debug, Clone, Serialize)]
#[cfg_attr(feature = "wasm-bindings", derive(tsify::Tsify))]
#[cfg_attr(feature = "uniffi-bindings", derive(uniffi::Record))]
#[serde(rename_all = "camelCase")]
pub struct ResolutionSource {
    pub resource_id: String,
    pub property_path: String,
    /// Origin of the resolved value, such as a parameter default, allowed values, an override, or an intrinsic.
    pub source: String,
}