gcloud_utils/iam/
process.rs

1use tokio::process::Command;
2use std::str;
3use console::style;
4use regex::Regex;
5
6fn regex(re_str: &str) -> Regex {
7  Regex::new(re_str).unwrap()
8}
9
10pub async fn process_create_service_account(project_id: &str, service_name: &str) {
11  let description = String::from("--description='") + service_name + " Service Account'";
12  let display_name = String::from("--display-name=") + service_name;
13  let output = Command::new("gcloud")
14    .args(&[
15      "iam",
16      "service-accounts",
17      "create",
18      service_name,
19      description.as_str(),
20      display_name.as_str(),
21      "--project",
22      project_id
23    ])
24    .output()
25    .await;
26  match &output {
27    Ok(val) => {
28      let err = str::from_utf8(&val.stderr);
29      let rt = regex("ERROR:");
30      match rt.is_match(err.unwrap()) {
31        true => {
32            panic!("{:?}", err.unwrap())
33        }
34        false => {
35          println!(
36              "✅ {}",
37              style("Successfully created service account!").white().bold()
38          );
39        }
40      }
41    },
42    Err(err) => println!("error = {:?}", err)
43  }
44}
45
46pub async fn process_create_service_account_key(project_id: &str, service_name: &str) {
47  let service_account = String::from(service_name) + "@" + project_id + ".iam.gserviceaccount.com";
48  let output = Command::new("gcloud")
49    .args(&[
50      "iam",
51      "service-accounts",
52      "keys",
53      "create",
54      "./keyfile.json",
55      "--iam-account",
56      service_account.as_str(),
57      "--project",
58      project_id 
59    ])
60    .output()
61    .await;
62  match &output {
63    Ok(val) => {
64      let err = str::from_utf8(&val.stderr);
65      let rt = regex("ERROR:");
66      match rt.is_match(err.unwrap()) {
67        true => {
68            panic!("{:?}", err.unwrap())
69        }
70        false => {
71          println!(
72              "✅ {}",
73              style("Successfully exported keyfile!").white().bold()
74          );
75        }
76      }
77    },
78    Err(err) => println!("error = {:?}", err)
79  }
80}
81
82pub async fn process_add_roles(project_id: &str, service_name: &str) {
83  let roles = [
84    "roles/cloudsql.editor",
85    "roles/containerregistry.ServiceAgent",
86    "roles/pubsub.editor",
87    "roles/datastore.user",
88    "roles/iam.serviceAccountUser",
89    "roles/run.admin",
90    "roles/storage.admin",
91    "roles/storage.objectAdmin",
92    "roles/cloudscheduler.admin",
93    "roles/appengine.appCreator",
94    "roles/logging.admin",
95    "roles/cloudtranslate.admin",
96  ];
97  for role in roles {
98    process_add_service_account_role(project_id, service_name, role).await;
99  }
100}
101
102pub async fn process_add_service_account_role(
103  project_id: &str,
104  service_name: &str,
105  role_arg: &str,
106) {
107  let member = String::from("--member=serviceAccount:")
108    + service_name
109    + "@"
110    + project_id
111    + ".iam.gserviceaccount.com";
112  let role = String::from("--role=") + role_arg;
113  let output = Command::new("gcloud")
114    .args(&[
115      "projects",
116      "add-iam-policy-binding",
117      project_id,
118      member.as_str(),
119      role.as_str(),
120      "--project",
121      project_id
122    ])
123    .output()
124    .await;
125  match &output {
126    Ok(val) => {
127      let err = str::from_utf8(&val.stderr);
128      let rt = regex("ERROR:");
129      match rt.is_match(err.unwrap()) {
130        true => {
131            panic!("{:?}", err.unwrap())
132        }
133        false => {
134          println!(
135              "✅ {} {}",
136              style("Successfully added role:").white().bold(),
137              role_arg
138          );
139        }
140      }
141    },
142    Err(err) => println!("error = {:?}", err)
143  }
144}
145
146pub async fn process_enable_permissions(project_id: &str) {
147  let service_urls = [
148    "compute.googleapis.com",
149    "iam.googleapis.com",
150    "dns.googleapis.com",
151    "sqladmin.googleapis.com",
152    "sql-component.googleapis.com",
153    "servicenetworking.googleapis.com",
154    "containerregistry.googleapis.com",
155    "run.googleapis.com",
156    "vpcaccess.googleapis.com",
157    "cloudscheduler.googleapis.com",
158    "cloudresourcemanager.googleapis.com",
159    "translate.googleapis.com",
160    "firestore.googleapis.com",
161    "cloudfunctions.googleapis.com",
162    "cloudbuild.googleapis.com",
163    "spanner.googleapis.com",
164  ];
165  for service_name in service_urls {
166    let output = Command::new("gcloud")
167      .args(
168        &[
169          "services",
170          "enable",
171          service_name,
172          "--project",
173          project_id
174          ])
175      .output()
176      .await;
177    match &output {
178      Ok(val) => {
179        let err = str::from_utf8(&val.stderr);
180        let rt = regex("ERROR:");
181        match rt.is_match(err.unwrap()) {
182          true => {
183              panic!("{:?}", err.unwrap())
184          }
185          false => {
186            println!(
187                "✅ {} {}",
188                style("Enabled API:").white().bold(),
189                service_name
190            );
191          }
192        }
193      },
194      Err(err) => println!("error = {:?}", err)
195    }
196  }
197}