| 
									
										
										
										
											2018-09-04 19:21:02 +08:00
										 |  |  | /** @ngInject */ | 
					
						
							| 
									
										
										
										
											2018-09-05 20:14:34 +08:00
										 |  |  | export default class StackdriverDatasource { | 
					
						
							| 
									
										
										
										
											2018-09-10 04:55:12 +08:00
										 |  |  |   id: number; | 
					
						
							| 
									
										
										
										
											2018-09-05 20:14:34 +08:00
										 |  |  |   url: string; | 
					
						
							|  |  |  |   baseUrl: string; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   constructor(instanceSettings, private backendSrv) { | 
					
						
							| 
									
										
										
										
											2018-09-05 22:18:03 +08:00
										 |  |  |     this.baseUrl = `/stackdriver/`; | 
					
						
							| 
									
										
										
										
											2018-09-05 20:14:34 +08:00
										 |  |  |     this.url = instanceSettings.url; | 
					
						
							| 
									
										
										
										
											2018-09-06 00:04:51 +08:00
										 |  |  |     this.doRequest = this.doRequest; | 
					
						
							| 
									
										
										
										
											2018-09-10 04:55:12 +08:00
										 |  |  |     this.id = instanceSettings.id; | 
					
						
							| 
									
										
										
										
											2018-09-05 20:14:34 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-10 04:55:12 +08:00
										 |  |  |   async query(options) { | 
					
						
							|  |  |  |     const queries = options.targets.filter(target => !target.hide).map(t => ({ | 
					
						
							|  |  |  |       refId: t.refId, | 
					
						
							|  |  |  |       datasourceId: this.id, | 
					
						
							| 
									
										
										
										
											2018-09-11 01:09:43 +08:00
										 |  |  |       metricType: `metric.type="${t.metricType}"`, | 
					
						
							| 
									
										
										
										
											2018-09-10 04:55:12 +08:00
										 |  |  |     })); | 
					
						
							| 
									
										
										
										
											2018-09-11 21:52:37 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     const result = []; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-10 04:55:12 +08:00
										 |  |  |     try { | 
					
						
							| 
									
										
										
										
											2018-09-11 01:09:43 +08:00
										 |  |  |       const { data } = await this.backendSrv.datasourceRequest({ | 
					
						
							| 
									
										
										
										
											2018-09-10 04:55:12 +08:00
										 |  |  |         url: '/api/tsdb/query', | 
					
						
							|  |  |  |         method: 'POST', | 
					
						
							|  |  |  |         data: { | 
					
						
							|  |  |  |           from: options.range.from.valueOf().toString(), | 
					
						
							|  |  |  |           to: options.range.to.valueOf().toString(), | 
					
						
							|  |  |  |           queries, | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2018-09-11 01:09:43 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       if (data.results) { | 
					
						
							|  |  |  |         Object['values'](data.results).forEach(queryRes => { | 
					
						
							|  |  |  |           queryRes.series.forEach(series => { | 
					
						
							|  |  |  |             result.push({ target: series.name, datapoints: series.points }); | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2018-09-10 04:55:12 +08:00
										 |  |  |     } catch (error) { | 
					
						
							|  |  |  |       console.log(error); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-09-11 21:52:37 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return { data: result }; | 
					
						
							| 
									
										
										
										
											2018-09-07 23:18:15 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-05 20:14:34 +08:00
										 |  |  |   testDatasource() { | 
					
						
							| 
									
										
										
										
											2018-09-05 22:18:03 +08:00
										 |  |  |     const path = `v3/projects/raintank-production/metricDescriptors`; | 
					
						
							| 
									
										
										
										
											2018-09-05 20:14:34 +08:00
										 |  |  |     return this.doRequest(`${this.baseUrl}${path}`) | 
					
						
							|  |  |  |       .then(response => { | 
					
						
							|  |  |  |         if (response.status === 200) { | 
					
						
							|  |  |  |           return { | 
					
						
							|  |  |  |             status: 'success', | 
					
						
							| 
									
										
										
										
											2018-09-06 00:04:51 +08:00
										 |  |  |             message: 'Successfully queried the Stackdriver API.', | 
					
						
							| 
									
										
										
										
											2018-09-05 20:14:34 +08:00
										 |  |  |             title: 'Success', | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-09-06 21:50:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return { | 
					
						
							|  |  |  |           status: 'error', | 
					
						
							|  |  |  |           message: 'Returned http status code ' + response.status, | 
					
						
							|  |  |  |         }; | 
					
						
							| 
									
										
										
										
											2018-09-05 20:14:34 +08:00
										 |  |  |       }) | 
					
						
							|  |  |  |       .catch(error => { | 
					
						
							| 
									
										
										
										
											2018-09-05 22:18:03 +08:00
										 |  |  |         let message = 'Stackdriver: '; | 
					
						
							| 
									
										
										
										
											2018-09-05 20:14:34 +08:00
										 |  |  |         message += error.statusText ? error.statusText + ': ' : ''; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (error.data && error.data.error && error.data.error.code) { | 
					
						
							| 
									
										
										
										
											2018-09-05 22:18:03 +08:00
										 |  |  |           // 400, 401
 | 
					
						
							| 
									
										
										
										
											2018-09-05 20:14:34 +08:00
										 |  |  |           message += error.data.error.code + '. ' + error.data.error.message; | 
					
						
							|  |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2018-09-05 22:18:03 +08:00
										 |  |  |           message += 'Cannot connect to Stackdriver API'; | 
					
						
							| 
									
										
										
										
											2018-09-05 20:14:34 +08:00
										 |  |  |         } | 
					
						
							|  |  |  |         return { | 
					
						
							|  |  |  |           status: 'error', | 
					
						
							|  |  |  |           message: message, | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-06 17:17:58 +08:00
										 |  |  |   async getProjects() { | 
					
						
							|  |  |  |     const response = await this.doRequest(`/cloudresourcemanager/v1/projects`); | 
					
						
							|  |  |  |     return response.data.projects.map(p => ({ id: p.projectId, name: p.name })); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-07 23:18:15 +08:00
										 |  |  |   async getMetricTypes(projectId: string) { | 
					
						
							|  |  |  |     try { | 
					
						
							|  |  |  |       const metricsApiPath = `v3/projects/${projectId}/metricDescriptors`; | 
					
						
							|  |  |  |       const { data } = await this.doRequest(`${this.baseUrl}${metricsApiPath}`); | 
					
						
							| 
									
										
										
										
											2018-09-11 01:09:43 +08:00
										 |  |  |       return data.metricDescriptors.map(m => ({ id: m.type, name: m.displayName })); | 
					
						
							| 
									
										
										
										
											2018-09-07 23:18:15 +08:00
										 |  |  |     } catch (error) { | 
					
						
							|  |  |  |       console.log(error); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-06 17:17:58 +08:00
										 |  |  |   async doRequest(url, maxRetries = 1) { | 
					
						
							| 
									
										
										
										
											2018-09-05 20:14:34 +08:00
										 |  |  |     return this.backendSrv | 
					
						
							|  |  |  |       .datasourceRequest({ | 
					
						
							|  |  |  |         url: this.url + url, | 
					
						
							|  |  |  |         method: 'GET', | 
					
						
							|  |  |  |       }) | 
					
						
							|  |  |  |       .catch(error => { | 
					
						
							|  |  |  |         if (maxRetries > 0) { | 
					
						
							|  |  |  |           return this.doRequest(url, maxRetries - 1); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         throw error; | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-09-04 19:21:02 +08:00
										 |  |  | } |