gcloud_utils/sql/
process.rs1use tokio::process::Command;
2use console::style;
3use std::io;
4use regex::Regex;
5use std::str;
6
7fn regex(re_str: &str) -> Regex {
8 Regex::new(re_str).unwrap()
9}
10
11pub async fn process_create_sql(project_id: &str, service_name: &str, region: &str) {
12 println!(
13 "📝 {}",
14 style("Please input your DB Root Password:").white().bold()
15 );
16 let mut db_password = String::new();
17 io::stdin()
18 .read_line(&mut db_password)
19 .expect("Failed to read line");
20 let db_password: String = db_password
21 .trim()
22 .parse()
23 .expect("Please input DB Root Password:");
24 let zone = String::from(region) + "-b";
25 println!(
26 "⏰ {}",
27 style("Creating Cloud SQL ...\nThis process takes 5 to 10 min.").white().bold()
28 );
29 let instance_name = String::from(service_name) + "-db";
30 let db_version = String::from("--database-version=POSTGRES_14");
31 let output = Command::new("gcloud")
32 .args(&[
33 "sql",
34 "instances",
35 "create",
36 &instance_name,
37 &db_version,
38 "--cpu=1",
39 "--memory=4096MB",
40 "--zone",
41 &zone,
42 "--root-password",
43 &db_password,
44 "--database-flags",
45 "cloudsql.iam_authentication=on",
46 "--project",
47 project_id
48 ])
49 .output()
50 .await;
51 match &output {
52 Ok(val) => {
53 let err = str::from_utf8(&val.stderr);
54 let rt = regex("ERROR:");
55 match rt.is_match(err.unwrap()) {
56 true => {
57 panic!("{:?}", err.unwrap())
58 }
59 false => {
60 println!(
61 "✅ {}",
62 style("Successfully created Cloud SQL!").white().bold()
63 );
64 }
65 }
66 },
67 Err(err) => println!("error = {:?}", err)
68 }
69}
70
71pub async fn process_create_ip_range(project_id: &str, service_name: &str) {
72 println!(
73 "⏰ {}",
74 style("Creating IP range ...\nThis process takes 5 to 10 min.").white().bold()
75 );
76 let ip_range_name = String::from(service_name) + "-ip-range";
77 let network = String::from("--network=") + service_name;
78 let output = Command::new("gcloud")
79 .args(&[
80 "compute",
81 "addresses",
82 "create",
83 &ip_range_name,
84 "--global",
85 "--purpose=VPC_PEERING",
86 "--prefix-length=16",
87 "--description='peering range for Epics'",
88 &network,
89 "--project",
90 project_id
91 ])
92 .output()
93 .await;
94 match &output {
95 Ok(val) => {
96 let err = str::from_utf8(&val.stderr);
97 let rt = regex("ERROR:");
98 match rt.is_match(err.unwrap()) {
99 true => {
100 panic!("{:?}", err.unwrap())
101 }
102 false => {
103 println!(
104 "✅ {}",
105 style("Successfully created IP range!").white().bold()
106 );
107 }
108 }
109 },
110 Err(err) => println!("error = {:?}", err)
111 }
112}
113
114pub async fn process_connect_vpc_connector(project_id: &str, service_name: &str) {
115 println!(
116 "⏰ {}",
117 style("Connecting to VPC Connector ...\nThis process takes 5 to 10 min.").white().bold()
118 );
119 let ip_range_name = String::from(service_name) + "-ip-range";
120 let network = String::from("--network=") + service_name;
121 let output = Command::new("gcloud")
122 .args(&[
123 "services",
124 "vpc-peerings",
125 "connect",
126 "--service=servicenetworking.googleapis.com",
127 "--ranges",
128 &ip_range_name,
129 &network,
130 "--project",
131 project_id
132 ])
133 .output()
134 .await;
135 match &output {
136 Ok(val) => {
137 let err = str::from_utf8(&val.stderr);
138 let rt = regex("ERROR:");
139 match rt.is_match(err.unwrap()) {
140 true => {
141 panic!("{:?}", err.unwrap())
142 }
143 false => {
144 println!(
145 "✅ {}",
146 style("Successfully connected to VPC!").white().bold()
147 );
148 }
149 }
150 },
151 Err(err) => println!("error = {:?}", err)
152 }
153}
154
155pub async fn process_assign_network(project_id: &str, service_name: &str) {
156 println!(
157 "⏰ {}",
158 style("Assign network ...\nThis process takes 5 to 10 min.").white().bold()
159 );
160 let instance_name = String::from(service_name) + "-db";
161 let network = String::from("--network=") + service_name;
162 let output = Command::new("gcloud")
163 .args(&[
164 "beta",
165 "sql",
166 "instances",
167 "patch",
168 &instance_name,
169 &network,
170 "--project",
171 project_id
172 ])
173 .output()
174 .await;
175 match &output {
176 Ok(val) => {
177 let err = str::from_utf8(&val.stderr);
178 let rt = regex("ERROR:");
179 match rt.is_match(err.unwrap()) {
180 true => {
181 panic!("{:?}", err.unwrap())
182 }
183 false => {
184 println!(
185 "✅ {}",
186 style("Successfully setup your database!").white().bold()
187 );
188 }
189 }
190 },
191 Err(err) => println!("error = {:?}", err)
192 }
193}
194
195async fn region_to_timezone(region: &str) -> &str {
196 let asia = regex("asia");
197 let eu = regex("europe");
198 let zone = if asia.is_match(region) {
199 "Asia/Tokyo"
200 } else if eu.is_match(region) {
201 "Europe/Amsterdam"
202 } else {
203 "America/Los_Angeles"
204 };
205 zone
206}