vantage_aws/models/lambda/
function.rs1use ciborium::Value as CborValue;
2use serde::{Deserialize, Serialize};
3use vantage_expressions::Expression;
4use vantage_expressions::expr_any;
5use vantage_expressions::traits::expressive::{DeferredFn, ExpressiveEnum};
6use vantage_table::any::AnyTable;
7use vantage_table::table::Table;
8use vantage_table::traits::table_source::TableSource;
9
10use crate::condition::AwsCondition;
11use crate::types::{Arn, AwsDateTime};
12use crate::{AwsAccount, eq};
13
14use super::alias::{Alias, aliases_table};
15use super::version::{Version, versions_table};
16use crate::models::logs::group::{LogGroup, groups_table as log_groups_table};
17
18#[derive(Debug, Clone, Serialize, Deserialize)]
23pub struct Function {
24 #[serde(rename = "FunctionName")]
25 pub function_name: String,
26 #[serde(rename = "FunctionArn", default)]
27 pub function_arn: String,
28 #[serde(rename = "Runtime", default)]
29 pub runtime: String,
30 #[serde(rename = "Role", default)]
31 pub role: String,
32 #[serde(rename = "Handler", default)]
33 pub handler: String,
34 #[serde(rename = "Description", default)]
35 pub description: String,
36 #[serde(rename = "Timeout", default)]
37 pub timeout: i64,
38 #[serde(rename = "MemorySize", default)]
39 pub memory_size: i64,
40 #[serde(rename = "LastModified", default)]
41 pub last_modified: String,
42 #[serde(rename = "Version", default)]
43 pub version: String,
44 #[serde(rename = "PackageType", default)]
45 pub package_type: String,
46}
47
48pub fn functions_table(aws: AwsAccount) -> Table<AwsAccount, Function> {
67 Table::new("restjson/Functions:lambda/GET /2015-03-31/functions/", aws)
68 .with_id_column("FunctionName")
69 .with_column_of::<Arn>("FunctionArn")
70 .with_title_column_of::<String>("Runtime")
71 .with_title_column_of::<String>("Handler")
72 .with_column_of::<String>("Description")
73 .with_column_of::<Arn>("Role")
74 .with_column_of::<i64>("Timeout")
75 .with_column_of::<i64>("MemorySize")
76 .with_column_of::<AwsDateTime>("LastModified")
77 .with_column_of::<String>("Version")
78 .with_column_of::<String>("PackageType")
79 .with_many("aliases", "FunctionName", aliases_table)
80 .with_many("versions", "FunctionName", versions_table)
81 .with_foreign(
82 "log_group",
83 std::any::type_name::<Table<AwsAccount, LogGroup>>(),
84 log_group_relation,
85 )
86}
87
88fn log_group_relation(functions: &Table<AwsAccount, Function>) -> vantage_core::Result<AnyTable> {
100 let aws = functions.data_source().clone();
101 let mut groups = log_groups_table(aws.clone());
102
103 let table = functions.clone();
104 let aws_for_fn = aws.clone();
105 let inner: DeferredFn<CborValue> = DeferredFn::new(move || {
106 let aws = aws_for_fn.clone();
107 let table = table.clone();
108 Box::pin(async move {
109 let records = aws.list_table_values(&table).await?;
110 let names: Vec<CborValue> = records
111 .values()
112 .filter_map(|r| match r.get("FunctionName") {
113 Some(CborValue::Text(s)) => Some(CborValue::Text(format!("/aws/lambda/{s}"))),
114 _ => None,
115 })
116 .collect();
117 Ok(ExpressiveEnum::Scalar(CborValue::Array(names)))
118 })
119 });
120
121 let source: Expression<CborValue> = expr_any!("{}", { inner });
122
123 groups.add_condition(AwsCondition::Deferred {
124 field: "logGroupNamePrefix".to_string(),
125 source,
126 });
127
128 Ok(AnyTable::from_table(groups))
129}
130
131impl Function {
132 pub fn from_arn(arn: &str, aws: AwsAccount) -> Option<Table<AwsAccount, Function>> {
137 let after = arn.split(":function:").nth(1)?;
138 let name = after.split(':').next().unwrap_or(after);
140 if name.is_empty() {
141 return None;
142 }
143 let mut t = functions_table(aws);
144 t.add_condition(eq("FunctionName", name.to_string()));
145 Some(t)
146 }
147
148 pub fn ref_aliases(&self, aws: AwsAccount) -> Table<AwsAccount, Alias> {
150 let mut t = aliases_table(aws);
151 t.add_condition(eq("FunctionName", self.function_name.clone()));
152 t
153 }
154
155 pub fn ref_versions(&self, aws: AwsAccount) -> Table<AwsAccount, Version> {
158 let mut t = versions_table(aws);
159 t.add_condition(eq("FunctionName", self.function_name.clone()));
160 t
161 }
162
163 pub fn ref_log_group(&self, aws: AwsAccount) -> Table<AwsAccount, LogGroup> {
167 let mut t = log_groups_table(aws);
168 t.add_condition(eq(
169 "logGroupNamePrefix",
170 format!("/aws/lambda/{}", self.function_name),
171 ));
172 t
173 }
174}