winterbaume_ec2instanceconnect/
views.rs1use std::collections::HashMap;
4
5use serde::{Deserialize, Serialize};
6use winterbaume_core::{StateChangeNotifier, StateViewError, StatefulService};
7
8use crate::handlers::Ec2InstanceConnectService;
9use crate::state::{Ec2InstanceConnectEndpoint, Ec2InstanceConnectState};
10
11#[derive(Debug, Clone, Serialize, Deserialize, Default)]
13pub struct Ec2InstanceConnectStateView {
14 #[serde(default)]
16 pub endpoints: HashMap<String, EndpointView>,
17}
18
19#[derive(Debug, Clone, Serialize, Deserialize)]
20pub struct EndpointView {
21 pub instance_connect_endpoint_id: String,
22 pub subnet_id: String,
23 pub vpc_id: String,
24 pub security_group_ids: Vec<String>,
25 pub state: String,
26 #[serde(default)]
27 pub dns_name: Option<String>,
28 #[serde(default)]
29 pub fips_dns_name: Option<String>,
30 pub network_interface_ids: Vec<String>,
31 pub owner_id: String,
32 pub availability_zone: String,
33 pub created_at: String,
34 #[serde(default)]
35 pub tags: HashMap<String, String>,
36}
37
38impl From<&Ec2InstanceConnectState> for Ec2InstanceConnectStateView {
41 fn from(state: &Ec2InstanceConnectState) -> Self {
42 Ec2InstanceConnectStateView {
43 endpoints: state
44 .endpoints
45 .iter()
46 .map(|(k, v)| {
47 (
48 k.clone(),
49 EndpointView {
50 instance_connect_endpoint_id: v.instance_connect_endpoint_id.clone(),
51 subnet_id: v.subnet_id.clone(),
52 vpc_id: v.vpc_id.clone(),
53 security_group_ids: v.security_group_ids.clone(),
54 state: v.state.clone(),
55 dns_name: v.dns_name.clone(),
56 fips_dns_name: v.fips_dns_name.clone(),
57 network_interface_ids: v.network_interface_ids.clone(),
58 owner_id: v.owner_id.clone(),
59 availability_zone: v.availability_zone.clone(),
60 created_at: v.created_at.clone(),
61 tags: v.tags.clone(),
62 },
63 )
64 })
65 .collect(),
66 }
67 }
68}
69
70impl From<Ec2InstanceConnectStateView> for Ec2InstanceConnectState {
73 fn from(view: Ec2InstanceConnectStateView) -> Self {
74 Ec2InstanceConnectState {
75 endpoints: view
76 .endpoints
77 .into_iter()
78 .map(|(k, v)| {
79 (
80 k,
81 Ec2InstanceConnectEndpoint {
82 instance_connect_endpoint_id: v.instance_connect_endpoint_id,
83 subnet_id: v.subnet_id,
84 vpc_id: v.vpc_id,
85 security_group_ids: v.security_group_ids,
86 state: v.state,
87 dns_name: v.dns_name,
88 fips_dns_name: v.fips_dns_name,
89 network_interface_ids: v.network_interface_ids,
90 owner_id: v.owner_id,
91 availability_zone: v.availability_zone,
92 created_at: v.created_at,
93 tags: v.tags,
94 },
95 )
96 })
97 .collect(),
98 }
99 }
100}
101
102impl StatefulService for Ec2InstanceConnectService {
105 type StateView = Ec2InstanceConnectStateView;
106
107 async fn snapshot(&self, account_id: &str, region: &str) -> Self::StateView {
108 let state = self.state.get(account_id, region);
109 let guard = state.read().await;
110 Ec2InstanceConnectStateView::from(&*guard)
111 }
112
113 async fn restore(
114 &self,
115 account_id: &str,
116 region: &str,
117 view: Self::StateView,
118 ) -> Result<(), StateViewError> {
119 let state = self.state.get(account_id, region);
120 {
121 let mut guard = state.write().await;
122 *guard = Ec2InstanceConnectState::from(view);
123 }
124 self.notify_state_changed(account_id, region).await;
125 Ok(())
126 }
127
128 async fn merge(
129 &self,
130 account_id: &str,
131 region: &str,
132 view: Self::StateView,
133 ) -> Result<(), StateViewError> {
134 let state = self.state.get(account_id, region);
135 {
136 let mut guard = state.write().await;
137 let incoming = Ec2InstanceConnectState::from(view);
138 for (k, v) in incoming.endpoints {
139 guard.endpoints.insert(k, v);
140 }
141 }
142 self.notify_state_changed(account_id, region).await;
143 Ok(())
144 }
145
146 fn notifier(&self) -> &StateChangeNotifier<Self::StateView> {
147 &self.notifier
148 }
149}