-
Notifications
You must be signed in to change notification settings - Fork 5.8k
/
Copy pathinstance.rs
151 lines (137 loc) · 4.77 KB
/
instance.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
use std::fmt::Display;
use aws_sdk_ec2::types::{Instance, InstanceType, KeyPairInfo, SecurityGroup};
use crate::ec2::{EC2Error, EC2};
/// InstanceManager wraps the lifecycle of an EC2 Instance.
#[derive(Debug, Default)]
pub struct InstanceManager {
instance: Option<Instance>,
}
impl InstanceManager {
pub fn instance_id(&self) -> &str {
if let Some(instance) = &self.instance {
if let Some(id) = instance.instance_id() {
return id;
}
}
"Unknown"
}
pub fn instance_name(&self) -> &str {
if let Some(instance) = &self.instance {
if let Some(tag) = instance.tags().iter().find(|e| e.key() == Some("Name")) {
if let Some(value) = tag.value() {
return value;
}
}
}
"Unknown"
}
pub fn instance_ip(&self) -> &str {
if let Some(instance) = &self.instance {
if let Some(public_ip_address) = instance.public_ip_address() {
return public_ip_address;
}
}
"0.0.0.0"
}
pub fn instance_display_name(&self) -> String {
format!("{} ({})", self.instance_name(), self.instance_id())
}
// snippet-start:[ec2.rust.create_instance.wrapper]
/// Create an EC2 instance with the given ID on a given type, using a
/// generated KeyPair and applying a list of security groups.
pub async fn create(
&mut self,
ec2: &EC2,
image_id: &str,
instance_type: InstanceType,
key_pair: &KeyPairInfo,
security_groups: Vec<&SecurityGroup>,
) -> Result<(), EC2Error> {
let instance_id = ec2
.create_instance(image_id, instance_type, key_pair, security_groups)
.await?;
let instance = ec2.describe_instance(&instance_id).await?;
self.instance = Some(instance);
Ok(())
}
// snippet-end:[ec2.rust.create_instance.wrapper]
/// Start the managed EC2 instance, if present.
pub async fn start(&self, ec2: &EC2) -> Result<(), EC2Error> {
if self.instance.is_some() {
ec2.start_instance(self.instance_id()).await?;
}
Ok(())
}
/// Stop the managed EC2 instance, if present.
pub async fn stop(&self, ec2: &EC2) -> Result<(), EC2Error> {
if self.instance.is_some() {
ec2.stop_instance(self.instance_id()).await?;
}
Ok(())
}
// snippet-start:[ec2.rust.reboot_instance.wrapper]
pub async fn reboot(&self, ec2: &EC2) -> Result<(), EC2Error> {
if self.instance.is_some() {
ec2.reboot_instance(self.instance_id()).await?;
ec2.wait_for_instance_stopped(self.instance_id(), None)
.await?;
ec2.wait_for_instance_ready(self.instance_id(), None)
.await?;
}
Ok(())
}
// snippet-end:[ec2.rust.reboot_instance.wrapper]
/// Terminate and delete the managed EC2 instance, if present.
pub async fn delete(self, ec2: &EC2) -> Result<(), EC2Error> {
if self.instance.is_some() {
ec2.delete_instance(self.instance_id()).await?;
}
Ok(())
}
}
impl Display for InstanceManager {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if let Some(instance) = &self.instance {
writeln!(f, "\tID: {}", instance.instance_id().unwrap_or("(Unknown)"))?;
writeln!(
f,
"\tImage ID: {}",
instance.image_id().unwrap_or("(Unknown)")
)?;
writeln!(
f,
"\tInstance type: {}",
instance
.instance_type()
.map(|it| format!("{it}"))
.unwrap_or("(Unknown)".to_string())
)?;
writeln!(
f,
"\tKey name: {}",
instance.key_name().unwrap_or("(Unknown)")
)?;
writeln!(f, "\tVPC ID: {}", instance.vpc_id().unwrap_or("(Unknown)"))?;
writeln!(
f,
"\tPublic IP: {}",
instance.public_ip_address().unwrap_or("(Unknown)")
)?;
let instance_state = instance
.state
.as_ref()
.map(|is| {
is.name()
.map(|isn| format!("{isn}"))
.unwrap_or("(Unknown)".to_string())
})
.unwrap_or("(Unknown)".to_string());
writeln!(f, "\tState: {instance_state}")?;
} else {
writeln!(f, "\tNo loaded instance")?;
}
Ok(())
}
}