Commit 09fb1760 by Erik Sundell

stackdriver: only load default project from backend if it's not available on the…

stackdriver: only load default project from backend if it's not available on the target. this might happen when using gce authentication and provisioning
parent 835f1d78
...@@ -6,6 +6,7 @@ export default class StackdriverDatasource { ...@@ -6,6 +6,7 @@ export default class StackdriverDatasource {
url: string; url: string;
baseUrl: string; baseUrl: string;
projectName: string; projectName: string;
queryPromise: Promise<any>;
/** @ngInject */ /** @ngInject */
constructor(instanceSettings, private backendSrv, private templateSrv, private timeSrv) { constructor(instanceSettings, private backendSrv, private templateSrv, private timeSrv) {
...@@ -99,6 +100,7 @@ export default class StackdriverDatasource { ...@@ -99,6 +100,7 @@ export default class StackdriverDatasource {
} }
async query(options) { async query(options) {
this.queryPromise = new Promise(async resolve => {
const result = []; const result = [];
const data = await this.getTimeSeries(options); const data = await this.getTimeSeries(options);
if (data.results) { if (data.results) {
...@@ -106,7 +108,7 @@ export default class StackdriverDatasource { ...@@ -106,7 +108,7 @@ export default class StackdriverDatasource {
if (!queryRes.series) { if (!queryRes.series) {
return; return;
} }
this.projectName = queryRes.meta.defaultProject;
const unit = this.resolvePanelUnitFromTargets(options.targets); const unit = this.resolvePanelUnitFromTargets(options.targets);
queryRes.series.forEach(series => { queryRes.series.forEach(series => {
let timeSerie: any = { let timeSerie: any = {
...@@ -123,7 +125,9 @@ export default class StackdriverDatasource { ...@@ -123,7 +125,9 @@ export default class StackdriverDatasource {
}); });
} }
return { data: result }; resolve({ data: result });
});
return this.queryPromise;
} }
async annotationQuery(options) { async annotationQuery(options) {
...@@ -181,9 +185,9 @@ export default class StackdriverDatasource { ...@@ -181,9 +185,9 @@ export default class StackdriverDatasource {
data: { data: {
queries: [ queries: [
{ {
refId: 'metricDescriptors', refId: 'testDatasource',
datasourceId: this.id, datasourceId: this.id,
type: 'metricDescriptors', type: 'testDatasource',
}, },
], ],
}, },
...@@ -215,27 +219,10 @@ export default class StackdriverDatasource { ...@@ -215,27 +219,10 @@ export default class StackdriverDatasource {
} }
} }
async getProjects() {
const response = await this.doRequest(`/cloudresourcemanager/v1/projects`);
return response.data.projects.map(p => ({ id: p.projectId, name: p.name }));
}
async getDefaultProject() { async getDefaultProject() {
try { try {
if (this.projectName) { await this.queryPromise;
return { return this.projectName;
id: this.projectName,
name: this.projectName,
};
} else {
const projects = await this.getProjects();
if (projects && projects.length > 0) {
const test = projects.filter(p => p.id === this.projectName)[0];
return test;
} else {
throw new Error('No projects found');
}
}
} catch (error) { } catch (error) {
let message = 'Projects cannot be fetched: '; let message = 'Projects cannot be fetched: ';
message += error.statusText ? error.statusText + ': ' : ''; message += error.statusText ? error.statusText + ': ' : '';
...@@ -252,12 +239,13 @@ export default class StackdriverDatasource { ...@@ -252,12 +239,13 @@ export default class StackdriverDatasource {
message += 'Cannot connect to Stackdriver API'; message += 'Cannot connect to Stackdriver API';
} }
appEvents.emit('ds-request-error', message); appEvents.emit('ds-request-error', message);
return '';
} }
} }
async getMetricTypes(projectId: string) { async getMetricTypes(projectName: string) {
try { try {
const metricsApiPath = `v3/projects/${projectId}/metricDescriptors`; const metricsApiPath = `v3/projects/${projectName}/metricDescriptors`;
const { data } = await this.doRequest(`${this.baseUrl}${metricsApiPath}`); const { data } = await this.doRequest(`${this.baseUrl}${metricsApiPath}`);
const metrics = data.metricDescriptors.map(m => { const metrics = data.metricDescriptors.map(m => {
......
...@@ -15,8 +15,7 @@ ...@@ -15,8 +15,7 @@
<div class="gf-form-inline"> <div class="gf-form-inline">
<div class="gf-form"> <div class="gf-form">
<span class="gf-form-label width-9">Project</span> <span class="gf-form-label width-9">Project</span>
<input class="gf-form-input" disabled type="text" ng-model='ctrl.target.project.name' get-options="ctrl.getProjects()" <input class="gf-form-input" disabled type="text" ng-model='ctrl.target.defaultProject' css-class="min-width-12" />
css-class="min-width-12" />
</div> </div>
<div class="gf-form"> <div class="gf-form">
<label class="gf-form-label query-keyword" ng-click="ctrl.showHelp = !ctrl.showHelp"> <label class="gf-form-label query-keyword" ng-click="ctrl.showHelp = !ctrl.showHelp">
...@@ -40,8 +39,8 @@ ...@@ -40,8 +39,8 @@
<div class="gf-form" ng-show="ctrl.showLastQuery"> <div class="gf-form" ng-show="ctrl.showLastQuery">
<pre class="gf-form-pre">{{ctrl.lastQueryMeta.rawQueryString}}</pre> <pre class="gf-form-pre">{{ctrl.lastQueryMeta.rawQueryString}}</pre>
</div> </div>
<div class="grafana-info-box m-t-2 markdown-html" ng-show="ctrl.showHelp"> <div class="gf-form grafana-info-box" style="padding: 0" ng-show="ctrl.showHelp">
<h5>Alias Patterns</h5> <pre class="gf-form-pre alert alert-info" style="margin-right: 0"><h5>Alias Patterns</h5>Format the legend keys any way you want by using alias patterns.
Format the legend keys any way you want by using alias patterns.<br /> <br /> Format the legend keys any way you want by using alias patterns.<br /> <br />
......
...@@ -14,10 +14,7 @@ export interface QueryMeta { ...@@ -14,10 +14,7 @@ export interface QueryMeta {
export class StackdriverQueryCtrl extends QueryCtrl { export class StackdriverQueryCtrl extends QueryCtrl {
static templateUrl = 'partials/query.editor.html'; static templateUrl = 'partials/query.editor.html';
target: { target: {
project: { defaultProject: string;
id: string;
name: string;
};
unit: string; unit: string;
metricType: string; metricType: string;
service: string; service: string;
...@@ -38,10 +35,7 @@ export class StackdriverQueryCtrl extends QueryCtrl { ...@@ -38,10 +35,7 @@ export class StackdriverQueryCtrl extends QueryCtrl {
defaultServiceValue = 'All Services'; defaultServiceValue = 'All Services';
defaults = { defaults = {
project: { defaultProject: 'loading project...',
id: 'default',
name: 'loading project...',
},
metricType: this.defaultDropdownValue, metricType: this.defaultDropdownValue,
service: this.defaultServiceValue, service: this.defaultServiceValue,
metric: '', metric: '',
......
...@@ -79,12 +79,17 @@ export class StackdriverFilterCtrl { ...@@ -79,12 +79,17 @@ export class StackdriverFilterCtrl {
} }
async getCurrentProject() { async getCurrentProject() {
this.target.project = await this.datasource.getDefaultProject(); return new Promise(async resolve => {
if (!this.target.defaultProject || this.target.defaultProject === 'loading project...') {
this.target.defaultProject = await this.datasource.getDefaultProject();
}
resolve(this.target.defaultProject);
});
} }
async loadMetricDescriptors() { async loadMetricDescriptors() {
if (this.target.project.id !== 'default') { if (this.target.defaultProject !== 'loading project...') {
this.metricDescriptors = await this.datasource.getMetricTypes(this.target.project.id); this.metricDescriptors = await this.datasource.getMetricTypes(this.target.defaultProject);
this.services = this.getServicesList(); this.services = this.getServicesList();
this.metrics = this.getMetricsList(); this.metrics = this.getMetricsList();
return this.metricDescriptors; return this.metricDescriptors;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment