29 public class GoogleCloud
35 if (
null == credentials)
37 GPAL.
PublishSimpleEvent(GPALEventType.ERROR,
"No credentials provided for GoogleCloud operations.",
null, GPALObjectType.None);
38 throw new ArgumentNullException(nameof(credentials));
40 _credentials = credentials;
41 if (CredentialServiceType.Google != ((
Credentials)_credentials).ServiceType)
43 GPAL.
PublishSimpleEvent(GPALEventType.ERROR,
"Credentials must be for Google service.",
null, GPALObjectType.None);
44 throw new ArgumentException(
"Credentials must be for Google service.");
48 public string GetProjectName(
string projectId)
50 if (
true ==
string.IsNullOrEmpty(projectId))
57 .WithAPIBase(
"https://cloudresourcemanager.googleapis.com")
58 .WithEndpoint($
"/v1/projects/{projectId}")
59 .WithHeader(
"Authorization", $
"Bearer {((Credentials)_credentials).AccessToken}")
61 var projectData = JsonSerializer.Deserialize<Dictionary<string, object>>(client);
62 return true == projectData.ContainsKey(
"name") ? projectData[
"name"].ToString() :
"Unknown";
65 public string CreateProject(
string projectName,
string projectId =
null)
67 string googleProjectId =
"";
72 if (
true ==
string.IsNullOrEmpty(projectId))
74 projectId = $
"myproject{DateTime.Now.Year}{DateTime.Now.Ticks}".Substring(0, 30).ToLower();
75 if (
false ==
string.IsNullOrEmpty(projectName))
77 projectId = $
"{projectName}{DateTime.Now.Year}{DateTime.Now.Ticks}".Substring(0, 29).ToLower();
80 string effectiveProjectName = projectName ?? projectId;
81 string googleProjectName = GetProjectName(projectId);
83 if (
true ==
"Unknown".Equals(googleProjectName))
85 var projectPayload = JsonSerializer.Serialize(
new { projectId, name = effectiveProjectName });
87 .WithAPIBase(
"https://cloudresourcemanager.googleapis.com")
88 .WithEndpoint(
"/v1/projects")
89 .WithParameters(projectPayload)
90 .WithHeader(
"Authorization", $
"Bearer {((Credentials)_credentials).AccessToken}")
93 var projectData = JsonSerializer.Deserialize<Dictionary<string, object>>(projectClient);
94 if (
true == projectData.ContainsKey(
"projectId"))
96 googleProjectId = projectData[
"projectId"].ToString();
98 else if (
true == projectData.ContainsKey(
"name"))
100 operationName = projectData[
"name"].ToString();
102 while (timeout > elapsed)
105 .WithAPIBase(
"https://cloudresourcemanager.googleapis.com")
106 .WithEndpoint($
"/v1/{operationName}")
107 .WithHeader(
"Authorization", $
"Bearer {((Credentials)_credentials).AccessToken}")
109 var opData = JsonSerializer.Deserialize<Dictionary<string, object>>(opClient);
110 if (
true == opData.ContainsKey(
"error"))
112 GPAL.
PublishSimpleEvent(GPALEventType.ERROR, $
"Project creation failed: [{opData["error
"]}]",
null, GPALObjectType.None);
115 if (
true == opData.ContainsKey(
"done") &&
true == ((JsonElement)opData[
"done"]).GetBoolean())
117 var responseJson = opData[
"response"].ToString();
118 var response = JsonSerializer.Deserialize<Dictionary<string, object>>(responseJson);
119 googleProjectId = response[
"projectId"].ToString();
125 if (timeout <= elapsed ||
true ==
string.IsNullOrEmpty(googleProjectId))
127 GPAL.
PublishSimpleEvent(GPALEventType.ERROR,
"Project creation timeout or no projectId.",
null, GPALObjectType.None);
133 GPAL.
PublishSimpleEvent(GPALEventType.ERROR,
"No projectId or operation name returned.",
null, GPALObjectType.None);
139 googleProjectId = projectId;
140 GPAL.
PublishSimpleEvent(GPALEventType.INFO, $
"Using existing project: ProjectId [{googleProjectId}], Name [{googleProjectName}]",
null, GPALObjectType.None);
143 return googleProjectId;
146 public bool EnableApi(
string googleProjectId,
string serviceId)
148 if (
true ==
string.IsNullOrEmpty(googleProjectId) ||
true ==
string.IsNullOrEmpty(serviceId))
150 GPAL.
PublishSimpleEvent(GPALEventType.ERROR,
"Project ID or service ID cannot be empty.",
null, GPALObjectType.None);
156 var servicePayload = JsonSerializer.Serialize(
new { serviceIds =
new[] { serviceId } });
158 .WithAPIBase(
"https://serviceusage.googleapis.com")
159 .WithEndpoint($
"/v1/projects/{googleProjectId}/services:batchEnable")
160 .WithParameters(servicePayload)
161 .WithHeader(
"Authorization", $
"Bearer {((Credentials)_credentials).AccessToken}")
164 var opData = JsonSerializer.Deserialize<Dictionary<string, object>>(client);
165 if (
true == opData.ContainsKey(
"done") &&
true == ((JsonElement)opData[
"done"]).GetBoolean())
169 else if (
true == opData.ContainsKey(
"name"))
171 var operationName = opData[
"name"].ToString();
173 while (timeout > elapsed)
176 .WithAPIBase(
"https://serviceusage.googleapis.com")
177 .WithEndpoint($
"/v1/{operationName}")
178 .WithHeader(
"Authorization", $
"Bearer {((Credentials)_credentials).AccessToken}")
180 var data = JsonSerializer.Deserialize<Dictionary<string, object>>(opClient);
181 if (
true == data.ContainsKey(
"error"))
183 GPAL.
PublishSimpleEvent(GPALEventType.ERROR, $
"[{serviceId}] enable failed: [{data["error
"]}]",
null, GPALObjectType.None);
186 if (
true == data.ContainsKey(
"done") &&
true == ((JsonElement)data[
"done"]).GetBoolean())
193 GPAL.
PublishSimpleEvent(GPALEventType.ERROR, $
"[{serviceId}] enable timeout.",
null, GPALObjectType.None);
199 public bool EnableApi(
string googleProjectId, GoogleApi api)
201 string serviceId = api
switch
203 GoogleApi.ServiceUsage =>
"serviceusage.googleapis.com",
204 GoogleApi.ApiKeys =>
"apikeys.googleapis.com",
205 GoogleApi.Sheets =>
"sheets.googleapis.com",
206 GoogleApi.Drive =>
"drive.googleapis.com",
207 GoogleApi.Scripts =>
"script.googleapis.com",
208 _ =>
throw new ArgumentException(
"Invalid Google API type.")
210 return EnableApi(googleProjectId, serviceId);
213 public string GenerateApiKey(
string googleProjectId)
215 if (
true ==
string.IsNullOrEmpty(googleProjectId))
217 GPAL.
PublishSimpleEvent(GPALEventType.ERROR,
"Project ID cannot be empty for API key generation.",
null, GPALObjectType.None);
221 var apiKeyPayload = JsonSerializer.Serialize(
new { displayName = $
"gpal-api-key-{Guid.NewGuid().ToString().Substring(0, 8)}" });
223 .WithAPIBase(
"https://apikeys.googleapis.com")
224 .WithEndpoint($
"/v2/projects/{googleProjectId}/locations/global/keys")
225 .WithParameters(apiKeyPayload)
226 .WithHeader(
"Authorization", $
"Bearer {((Credentials)_credentials).AccessToken}")
229 var apiKeyOpData = JsonSerializer.Deserialize<Dictionary<string, object>>(apiKeyClient);
230 if (
true == apiKeyOpData.ContainsKey(
"keyString"))
232 return apiKeyOpData[
"keyString"].ToString();
234 else if (
true == apiKeyOpData.ContainsKey(
"name"))
236 var operationName = apiKeyOpData[
"name"].ToString();
238 while (30000 > elapsed)
241 .WithAPIBase(
"https://apikeys.googleapis.com")
242 .WithEndpoint($
"/v2/{operationName}")
243 .WithHeader(
"Authorization", $
"Bearer {((Credentials)_credentials).AccessToken}")
245 var opData = JsonSerializer.Deserialize<Dictionary<string, object>>(opClient);
246 if (
true == opData.ContainsKey(
"error"))
248 GPAL.
PublishSimpleEvent(GPALEventType.ERROR, $
"API key creation failed: [{opData["error
"]}]",
null, GPALObjectType.None);
251 if (
true == opData.ContainsKey(
"done") &&
true == ((JsonElement)opData[
"done"]).GetBoolean())
253 var responseJson = opData[
"response"].ToString();
254 var response = JsonSerializer.Deserialize<Dictionary<string, object>>(responseJson);
255 return response[
"keyString"].ToString();
260 GPAL.
PublishSimpleEvent(GPALEventType.ERROR,
"API key creation timeout or failed.",
null, GPALObjectType.None);