@@ -2,6 +2,8 @@ package cloudamqp
22
33import  (
44	"context" 
5+ 	"encoding/base64" 
6+ 	"encoding/json" 
57	"fmt" 
68	"strconv" 
79	"strings" 
@@ -33,7 +35,7 @@ func resourceIntegrationMetricPrometheus() *schema.Resource {
3335				Type :          schema .TypeSet ,
3436				Optional :      true ,
3537				MaxItems :      1 ,
36- 				ConflictsWith : []string {"datadog_v3" , "azure_monitor" , "splunk_v2" , "dynatrace" , "cloudwatch_v3" },
38+ 				ConflictsWith : []string {"datadog_v3" , "azure_monitor" , "splunk_v2" , "dynatrace" , "cloudwatch_v3" ,  "stackdriver_v2" },
3739				Elem : & schema.Resource {
3840					Schema : map [string ]* schema.Schema {
3941						"api_key" : {
@@ -53,7 +55,7 @@ func resourceIntegrationMetricPrometheus() *schema.Resource {
5355				Type :          schema .TypeSet ,
5456				Optional :      true ,
5557				MaxItems :      1 ,
56- 				ConflictsWith : []string {"newrelic_v3" , "azure_monitor" , "splunk_v2" , "dynatrace" , "cloudwatch_v3" },
58+ 				ConflictsWith : []string {"newrelic_v3" , "azure_monitor" , "splunk_v2" , "dynatrace" , "cloudwatch_v3" ,  "stackdriver_v2" },
5759				Elem : & schema.Resource {
5860					Schema : map [string ]* schema.Schema {
5961						"api_key" : {
@@ -79,7 +81,7 @@ func resourceIntegrationMetricPrometheus() *schema.Resource {
7981				Type :          schema .TypeSet ,
8082				Optional :      true ,
8183				MaxItems :      1 ,
82- 				ConflictsWith : []string {"newrelic_v3" , "datadog_v3" , "splunk_v2" , "dynatrace" , "cloudwatch_v3" },
84+ 				ConflictsWith : []string {"newrelic_v3" , "datadog_v3" , "splunk_v2" , "dynatrace" , "cloudwatch_v3" ,  "stackdriver_v2" },
8385				Elem : & schema.Resource {
8486					Schema : map [string ]* schema.Schema {
8587						"connection_string" : {
@@ -95,7 +97,7 @@ func resourceIntegrationMetricPrometheus() *schema.Resource {
9597				Type :          schema .TypeSet ,
9698				Optional :      true ,
9799				MaxItems :      1 ,
98- 				ConflictsWith : []string {"newrelic_v3" , "datadog_v3" , "azure_monitor" , "dynatrace" , "cloudwatch_v3" },
100+ 				ConflictsWith : []string {"newrelic_v3" , "datadog_v3" , "azure_monitor" , "dynatrace" , "cloudwatch_v3" ,  "stackdriver_v2" },
99101				Elem : & schema.Resource {
100102					Schema : map [string ]* schema.Schema {
101103						"token" : {
@@ -121,7 +123,7 @@ func resourceIntegrationMetricPrometheus() *schema.Resource {
121123				Type :          schema .TypeSet ,
122124				Optional :      true ,
123125				MaxItems :      1 ,
124- 				ConflictsWith : []string {"newrelic_v3" , "datadog_v3" , "azure_monitor" , "splunk_v2" , "cloudwatch_v3" },
126+ 				ConflictsWith : []string {"newrelic_v3" , "datadog_v3" , "azure_monitor" , "splunk_v2" , "cloudwatch_v3" ,  "stackdriver_v2" },
125127				Elem : & schema.Resource {
126128					Schema : map [string ]* schema.Schema {
127129						"environment_id" : {
@@ -147,7 +149,7 @@ func resourceIntegrationMetricPrometheus() *schema.Resource {
147149				Type :          schema .TypeSet ,
148150				Optional :      true ,
149151				MaxItems :      1 ,
150- 				ConflictsWith : []string {"newrelic_v3" , "datadog_v3" , "azure_monitor" , "splunk_v2" , "dynatrace" },
152+ 				ConflictsWith : []string {"newrelic_v3" , "datadog_v3" , "azure_monitor" , "splunk_v2" , "dynatrace" ,  "stackdriver_v2" },
151153				Elem : & schema.Resource {
152154					Schema : map [string ]* schema.Schema {
153155						"iam_role" : {
@@ -173,6 +175,69 @@ func resourceIntegrationMetricPrometheus() *schema.Resource {
173175					},
174176				},
175177			},
178+ 			"stackdriver_v2" : {
179+ 				Type :          schema .TypeList ,
180+ 				Optional :      true ,
181+ 				MaxItems :      1 ,
182+ 				ConflictsWith : []string {"newrelic_v3" , "datadog_v3" , "azure_monitor" , "splunk_v2" , "dynatrace" , "cloudwatch_v3" },
183+ 				Elem : & schema.Resource {
184+ 					Schema : map [string ]* schema.Schema {
185+ 						"credentials_file" : {
186+ 							Type :        schema .TypeString ,
187+ 							Required :    true ,
188+ 							Sensitive :   true ,
189+ 							Description : "Base64-encoded Google service account key JSON file" ,
190+ 							DiffSuppressFunc : func (k , old , new  string , d  * schema.ResourceData ) bool  {
191+ 								// Only suppress for existing resources 
192+ 								if  d .Id () ==  ""  {
193+ 									return  false 
194+ 								}
195+ 
196+ 								if  stackdriver  :=  d .Get ("stackdriver_v2" ).([]any ); len (stackdriver ) >  0  {
197+ 									config  :=  stackdriver [0 ].(map [string ]any )
198+ 									newCredentials , err  :=  extractStackdriverCredentials (new )
199+ 									if  err  !=  nil  {
200+ 										return  false 
201+ 									}
202+ 									// Suppress diff if new credentials match current state 
203+ 									return  newCredentials ["project_id" ] ==  config ["project_id" ] && 
204+ 										newCredentials ["client_email" ] ==  config ["client_email" ] && 
205+ 										newCredentials ["private_key_id" ] ==  config ["private_key_id" ] && 
206+ 										newCredentials ["private_key" ] ==  config ["private_key" ]
207+ 								}
208+ 								return  false 
209+ 							},
210+ 						},
211+ 						"project_id" : {
212+ 							Type :        schema .TypeString ,
213+ 							Computed :    true ,
214+ 							Description : "Google Cloud project ID (computed from credentials file)" ,
215+ 						},
216+ 						"client_email" : {
217+ 							Type :        schema .TypeString ,
218+ 							Computed :    true ,
219+ 							Description : "Google service account client email (computed from credentials file)" ,
220+ 						},
221+ 						"private_key" : {
222+ 							Type :        schema .TypeString ,
223+ 							Computed :    true ,
224+ 							Sensitive :   true ,
225+ 							Description : "Google service account private key (computed from credentials file)" ,
226+ 						},
227+ 						"private_key_id" : {
228+ 							Type :        schema .TypeString ,
229+ 							Computed :    true ,
230+ 							Sensitive :   true ,
231+ 							Description : "Google service account private key ID (computed from credentials file)" ,
232+ 						},
233+ 						"tags" : {
234+ 							Type :        schema .TypeString ,
235+ 							Optional :    true ,
236+ 							Description : "tags. E.g. env=prod,service=web" ,
237+ 						},
238+ 					},
239+ 				},
240+ 			},
176241		},
177242	}
178243}
@@ -230,6 +295,23 @@ func resourceIntegrationMetricPrometheusCreate(ctx context.Context, d *schema.Re
230295		if  tags  :=  cloudwatchConfig ["tags" ]; tags  !=  nil  &&  tags  !=  ""  {
231296			params ["tags" ] =  tags 
232297		}
298+ 	} else  if  stackdriverList  :=  d .Get ("stackdriver_v2" ).([]any ); len (stackdriverList ) >  0  {
299+ 		intName  =  "stackdriver_v2" 
300+ 		stackdriverConfig  :=  stackdriverList [0 ].(map [string ]any )
301+ 		credentials  :=  stackdriverConfig ["credentials_file" ].(string )
302+ 
303+ 		extractedCredentials , err  :=  extractStackdriverCredentials (credentials )
304+ 		if  err  !=  nil  {
305+ 			return  diag .FromErr (err )
306+ 		}
307+ 
308+ 		for  key , value  :=  range  extractedCredentials  {
309+ 			params [key ] =  value 
310+ 		}
311+ 
312+ 		if  tags  :=  stackdriverConfig ["tags" ]; tags  !=  nil  &&  tags  !=  ""  {
313+ 			params ["tags" ] =  tags 
314+ 		}
233315	}
234316
235317	if  intName  ==  ""  {
@@ -247,6 +329,32 @@ func resourceIntegrationMetricPrometheusCreate(ctx context.Context, d *schema.Re
247329	return  resourceIntegrationMetricPrometheusRead (ctx , d , meta )
248330}
249331
332+ func  extractStackdriverCredentials (credentials  string ) (map [string ]string , error ) {
333+ 	decoded , err  :=  base64 .StdEncoding .DecodeString (credentials )
334+ 	if  err  !=  nil  {
335+ 		return  nil , fmt .Errorf ("failed to decode stackdriver credentials: %s" , err )
336+ 	}
337+ 
338+ 	var  jsonMap  map [string ]any 
339+ 	if  err  :=  json .Unmarshal (decoded , & jsonMap ); err  !=  nil  {
340+ 		return  nil , fmt .Errorf ("failed to parse stackdriver credentials JSON: %s" , err )
341+ 	}
342+ 
343+ 	requiredFields  :=  []string {"client_email" , "private_key_id" , "private_key" , "project_id" }
344+ 	for  _ , field  :=  range  requiredFields  {
345+ 		if  jsonMap [field ] ==  nil  ||  jsonMap [field ] ==  ""  {
346+ 			return  nil , fmt .Errorf ("required field '%s' is missing from credentials JSON" , field )
347+ 		}
348+ 	}
349+ 
350+ 	return  map [string ]string {
351+ 		"client_email" :   jsonMap ["client_email" ].(string ),
352+ 		"private_key_id" : jsonMap ["private_key_id" ].(string ),
353+ 		"private_key" :    jsonMap ["private_key" ].(string ),
354+ 		"project_id" :     jsonMap ["project_id" ].(string ),
355+ 	}, nil 
356+ }
357+ 
250358func  resourceIntegrationMetricPrometheusRead (ctx  context.Context , d  * schema.ResourceData , meta  any ) diag.Diagnostics  {
251359	if  strings .Contains (d .Id (), "," ) {
252360		tflog .Info (ctx , fmt .Sprintf ("import resource with identifier: %s" , d .Id ()))
@@ -279,6 +387,7 @@ func resourceIntegrationMetricPrometheusRead(ctx context.Context, d *schema.Reso
279387	d .Set ("splunk_v2" , nil )
280388	d .Set ("dynatrace" , nil )
281389	d .Set ("cloudwatch_v3" , nil )
390+ 	d .Set ("stackdriver_v2" , nil )
282391
283392	name  :=  strings .ToLower (data ["type" ].(string ))
284393	if  name  ==  "newrelic_v3"  {
@@ -359,6 +468,28 @@ func resourceIntegrationMetricPrometheusRead(ctx context.Context, d *schema.Reso
359468		if  err  :=  d .Set ("cloudwatch_v3" , cloudwatchV3 ); err  !=  nil  {
360469			return  diag .Errorf ("error setting cloudwatch_v3 for resource %s: %s" , d .Id (), err )
361470		}
471+ 	} else  if  name  ==  "stackdriver_v2"  {
472+ 		stackdriverV2  :=  []map [string ]any {{}}
473+ 
474+ 		if  project_id , ok  :=  data ["project_id" ]; ok  {
475+ 			stackdriverV2 [0 ]["project_id" ] =  project_id 
476+ 		}
477+ 		if  client_email , ok  :=  data ["client_email" ]; ok  {
478+ 			stackdriverV2 [0 ]["client_email" ] =  client_email 
479+ 		}
480+ 		if  private_key , ok  :=  data ["private_key" ]; ok  {
481+ 			stackdriverV2 [0 ]["private_key" ] =  private_key 
482+ 		}
483+ 		if  private_key_id , ok  :=  data ["private_key_id" ]; ok  {
484+ 			stackdriverV2 [0 ]["private_key_id" ] =  private_key_id 
485+ 		}
486+ 		if  tags , ok  :=  data ["tags" ]; ok  {
487+ 			stackdriverV2 [0 ]["tags" ] =  tags 
488+ 		}
489+ 
490+ 		if  err  :=  d .Set ("stackdriver_v2" , stackdriverV2 ); err  !=  nil  {
491+ 			return  diag .Errorf ("error setting stackdriver_v2 for resource %s: %s" , d .Id (), err )
492+ 		}
362493	}
363494
364495	return  nil 
@@ -410,6 +541,22 @@ func resourceIntegrationMetricPrometheusUpdate(ctx context.Context, d *schema.Re
410541		if  tags  :=  cloudwatchConfig ["tags" ]; tags  !=  nil  &&  tags  !=  ""  {
411542			params ["tags" ] =  tags 
412543		}
544+ 	} else  if  stackdriverList  :=  d .Get ("stackdriver_v2" ).([]interface {}); len (stackdriverList ) >  0  {
545+ 		stackdriverConfig  :=  stackdriverList [0 ].(map [string ]any )
546+ 
547+ 		credentials  :=  stackdriverConfig ["credentials_file" ].(string )
548+ 		extractedCreds , err  :=  extractStackdriverCredentials (credentials )
549+ 		if  err  !=  nil  {
550+ 			return  diag .FromErr (err )
551+ 		}
552+ 
553+ 		for  key , value  :=  range  extractedCreds  {
554+ 			params [key ] =  value 
555+ 		}
556+ 
557+ 		if  tags  :=  stackdriverConfig ["tags" ]; tags  !=  nil  &&  tags  !=  ""  {
558+ 			params ["tags" ] =  tags 
559+ 		}
413560	}
414561
415562	err  :=  api .UpdateIntegration (ctx , d .Get ("instance_id" ).(int ), "metrics" , d .Id (), params )
0 commit comments