mirror of https://github.com/status-im/consul.git
ui: Metrics - Provide a fetch-like http client that automatically adds the current ACL token (#9094)
* Remove local httpGet and shim one in from options * Add custom httpGet to pass through to provider * Make a fetch wrapper that adds your token * Pass the fetch like fetchWithToken wrapper through to the provider * Fix up httpGet to encode query params again and use fetch-like
This commit is contained in:
parent
1a5d4cfe43
commit
0f6c0a5c13
|
@ -152,6 +152,17 @@ export default Service.extend({
|
|||
params.headers[CONTENT_TYPE] = 'application/json; charset=utf-8';
|
||||
return params;
|
||||
},
|
||||
fetchWithToken: function(path, params) {
|
||||
return this.settings.findBySlug('token').then(token => {
|
||||
return fetch(`${path}`, {
|
||||
...params,
|
||||
headers: {
|
||||
'X-Consul-Token': typeof token.SecretID === 'undefined' ? '' : token.SecretID,
|
||||
...params.headers,
|
||||
},
|
||||
});
|
||||
});
|
||||
},
|
||||
request: function(cb) {
|
||||
const client = this;
|
||||
return cb(function(strs, ...values) {
|
||||
|
|
|
@ -11,6 +11,7 @@ const meta = {
|
|||
|
||||
export default RepositoryService.extend({
|
||||
cfg: service('ui-config'),
|
||||
client: service('client/http'),
|
||||
error: null,
|
||||
|
||||
init: function() {
|
||||
|
@ -20,6 +21,9 @@ export default RepositoryService.extend({
|
|||
// JSON options the user provided.
|
||||
const opts = uiCfg.metrics_provider_options || {};
|
||||
opts.metrics_proxy_enabled = uiCfg.metrics_proxy_enabled;
|
||||
// Inject a convenience function for dialing through the metrics proxy.
|
||||
opts.fetch = (path, params) =>
|
||||
this.client.fetchWithToken(`/v1/internal/ui/metrics-proxy${path}`, params);
|
||||
// Inject the base app URL
|
||||
const provider = uiCfg.metrics_provider || 'prometheus';
|
||||
|
||||
|
|
|
@ -11,8 +11,14 @@
|
|||
* options.providerOptions contains any operator configured parameters
|
||||
* specified in the Consul agent config that is serving the UI.
|
||||
*
|
||||
* Consul will provider a boolean options.metrics_proxy_enabled to indicate
|
||||
* whether the agent has a metrics proxy configured.
|
||||
* Consul will provide:
|
||||
*
|
||||
* 1. A boolean options.metrics_proxy_enabled to indicate whether the agent
|
||||
* has a metrics proxy configured.
|
||||
* 2. A fetch-like options.fetch which is a thin fetch wrapper that prefixes
|
||||
* any url with the url of Consul's proxy endpoint and adds your current
|
||||
* Consul ACL token to the request headers. Otherwise it functions like the
|
||||
* browsers native fetch
|
||||
*
|
||||
* The provider should throw an Exception if the options are not valid for
|
||||
* example because it requires a metrics proxy and one is not configured.
|
||||
|
@ -24,6 +30,34 @@
|
|||
}
|
||||
},
|
||||
|
||||
// simple httpGet function that also encodes query parameters
|
||||
// before passing the constructed url through to native fetch
|
||||
// any errors should throw an error with a statusCode property
|
||||
httpGet: function(url, queryParams, headers) {
|
||||
if (queryParams) {
|
||||
var separator = url.indexOf('?') !== -1 ? '&' : '?';
|
||||
var qs = Object.keys(queryParams).
|
||||
map(function(key) {
|
||||
return encodeURIComponent(key) + "=" + encodeURIComponent(queryParams[key]);
|
||||
}).
|
||||
join("&");
|
||||
url = url + separator + qs;
|
||||
}
|
||||
// fetch the url along with any headers
|
||||
return this.options.fetch(url, {headers: headers || {}}).then(
|
||||
function(response) {
|
||||
if(response.ok) {
|
||||
return response.json();
|
||||
} else {
|
||||
// throw a statusCode error if any errors are received
|
||||
var e = new Error('HTTP Error: ' + response.statusText);
|
||||
e.statusCode = response.status;
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* serviceRecentSummarySeries should return time series for a recent time
|
||||
* period summarizing the usage of the named service in the indicated
|
||||
|
@ -656,42 +690,6 @@
|
|||
return this.httpGet("/api/v1/query_range", params)
|
||||
},
|
||||
|
||||
httpGet: function(path, params) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
var self = this
|
||||
return new Promise(function(resolve, reject){
|
||||
xhr.onreadystatechange = function(){
|
||||
if (xhr.readyState !== 4) return;
|
||||
|
||||
if (xhr.status == 200) {
|
||||
// Attempt to parse response as JSON and return the object
|
||||
var o = JSON.parse(xhr.responseText)
|
||||
resolve(o)
|
||||
}
|
||||
const e = new Error(xhr.statusText);
|
||||
e.statusCode = xhr.status;
|
||||
reject(e);
|
||||
}
|
||||
|
||||
var url = self.baseURL()+path;
|
||||
if (params) {
|
||||
var qs = Object.keys(params).
|
||||
map(function(key){
|
||||
return encodeURIComponent(key)+"="+encodeURIComponent(params[key])
|
||||
}).
|
||||
join("&")
|
||||
url = url+"?"+qs
|
||||
}
|
||||
xhr.open("GET", url, true);
|
||||
xhr.send();
|
||||
});
|
||||
},
|
||||
|
||||
baseURL: function() {
|
||||
// TODO support configuring a direct Prometheus via
|
||||
// metrics_provider_options_json.
|
||||
return "/v1/internal/ui/metrics-proxy"
|
||||
}
|
||||
}
|
||||
|
||||
// Helper functions
|
||||
|
|
Loading…
Reference in New Issue