1pub mod error;
2pub mod generators;
3pub mod registry;
4pub mod variables;
5
6pub use error::*;
7pub use registry::{get_permission_set, has_permission_set, list_permission_set_ids};
8pub use variables::VariableInterpolator;
9
10#[derive(Debug, Clone)]
14pub struct PermissionContext {
15 pub aws_account_id: Option<String>,
17 pub aws_region: Option<String>,
18
19 pub project_name: Option<String>,
21 pub region: Option<String>,
22
23 pub subscription_id: Option<String>,
25 pub resource_group: Option<String>,
26 pub storage_account_name: Option<String>,
27
28 pub stack_prefix: Option<String>,
30 pub resource_name: Option<String>,
31 pub service_account_name: Option<String>,
32 pub principal_id: Option<String>,
33 pub external_id: Option<String>,
34 pub managing_role_arn: Option<String>,
35 pub managing_account_id: Option<String>,
36}
37
38impl PermissionContext {
39 pub fn new() -> Self {
41 Self {
42 aws_account_id: None,
43 aws_region: None,
44 project_name: None,
45 region: None,
46 subscription_id: None,
47 resource_group: None,
48 storage_account_name: None,
49 stack_prefix: None,
50 resource_name: None,
51 service_account_name: None,
52 principal_id: None,
53 external_id: None,
54 managing_role_arn: None,
55 managing_account_id: None,
56 }
57 }
58
59 pub fn with_aws_account_id(mut self, aws_account_id: impl Into<String>) -> Self {
61 self.aws_account_id = Some(aws_account_id.into());
62 self
63 }
64
65 pub fn with_aws_region(mut self, aws_region: impl Into<String>) -> Self {
67 self.aws_region = Some(aws_region.into());
68 self
69 }
70
71 pub fn with_project_name(mut self, project_name: impl Into<String>) -> Self {
73 self.project_name = Some(project_name.into());
74 self
75 }
76
77 pub fn with_region(mut self, region: impl Into<String>) -> Self {
79 self.region = Some(region.into());
80 self
81 }
82
83 pub fn with_subscription_id(mut self, subscription_id: impl Into<String>) -> Self {
85 self.subscription_id = Some(subscription_id.into());
86 self
87 }
88
89 pub fn with_resource_group(mut self, resource_group: impl Into<String>) -> Self {
91 self.resource_group = Some(resource_group.into());
92 self
93 }
94
95 pub fn with_storage_account_name(mut self, storage_account_name: impl Into<String>) -> Self {
97 self.storage_account_name = Some(storage_account_name.into());
98 self
99 }
100
101 pub fn with_stack_prefix(mut self, stack_prefix: impl Into<String>) -> Self {
103 self.stack_prefix = Some(stack_prefix.into());
104 self
105 }
106
107 pub fn with_resource_name(mut self, resource_name: impl Into<String>) -> Self {
109 self.resource_name = Some(resource_name.into());
110 self
111 }
112
113 pub fn with_service_account_name(mut self, service_account_name: impl Into<String>) -> Self {
115 self.service_account_name = Some(service_account_name.into());
116 self
117 }
118
119 pub fn with_principal_id(mut self, principal_id: impl Into<String>) -> Self {
121 self.principal_id = Some(principal_id.into());
122 self
123 }
124
125 pub fn with_external_id(mut self, external_id: impl Into<String>) -> Self {
127 self.external_id = Some(external_id.into());
128 self
129 }
130
131 pub fn with_managing_role_arn(mut self, managing_role_arn: impl Into<String>) -> Self {
133 self.managing_role_arn = Some(managing_role_arn.into());
134 self
135 }
136
137 pub fn with_managing_account_id(mut self, managing_account_id: impl Into<String>) -> Self {
139 self.managing_account_id = Some(managing_account_id.into());
140 self
141 }
142
143 pub fn extract_account_id_from_role_arn(role_arn: &str) -> Option<String> {
146 let parts: Vec<&str> = role_arn.split(':').collect();
147 if parts.len() >= 5 && parts[0] == "arn" && parts[2] == "iam" {
148 Some(parts[4].to_string())
149 } else {
150 None
151 }
152 }
153
154 pub fn get_variable(&self, key: &str) -> Option<&str> {
156 match key {
157 "awsAccountId" => self.aws_account_id.as_deref(),
158 "awsRegion" => self.aws_region.as_deref(),
159 "projectName" => self.project_name.as_deref(),
160 "region" => self.region.as_deref(),
161 "subscriptionId" => self.subscription_id.as_deref(),
162 "resourceGroup" => self.resource_group.as_deref(),
163 "storageAccountName" => self.storage_account_name.as_deref(),
164 "stackPrefix" => self.stack_prefix.as_deref(),
165 "resourceName" => self.resource_name.as_deref(),
166 "serviceAccountName" => self.service_account_name.as_deref(),
167 "principalId" => self.principal_id.as_deref(),
168 "externalId" => self.external_id.as_deref(),
169 "managingRoleArn" => self.managing_role_arn.as_deref(),
170 "managingAccountId" => self.managing_account_id.as_deref(),
171 _ => None,
172 }
173 }
174}
175
176impl Default for PermissionContext {
177 fn default() -> Self {
178 Self::new()
179 }
180}
181
182#[derive(Debug, Clone, Copy, PartialEq, Eq)]
184pub enum BindingTarget {
185 Stack,
187 Resource,
189}
190
191impl std::fmt::Display for BindingTarget {
192 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
193 match self {
194 BindingTarget::Stack => write!(f, "stack"),
195 BindingTarget::Resource => write!(f, "resource"),
196 }
197 }
198}