ui: Refactor topology components (#9339)

* Refactor Stats and Series components

* Refactor metrics error message for ingress-gateway

* Fix upLines icon positioning

* Remove unused variable from being passed down to Stats
This commit is contained in:
Kenia 2020-12-08 10:47:55 -05:00 committed by GitHub
parent 535ef33bac
commit 811703c302
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 53 additions and 60 deletions

View File

@ -48,25 +48,5 @@
</dl> </dl>
{{/if}} {{/if}}
</div> </div>
{{#if (and @hasMetricsProvider (not-eq @service.Kind 'ingress-gateway'))}} {{yield}}
{{#if (eq @type 'upstream')}}
<TopologyMetrics::Stats
@nspace={{or @item.Namespace 'default'}}
@dc={{@item.Datacenter}}
@endpoint='upstream-summary-for-service'
@service={{@service.Service}}
@item={{@item.Name}}
@noMetricsReason={{@noMetricsReason}}
/>
{{else}}
<TopologyMetrics::Stats
@nspace={{or @item.Namespace 'default'}}
@dc={{@item.Datacenter}}
@endpoint='downstream-summary-for-service'
@service={{@service.Service}}
@item={{@item.Name}}
@noMetricsReason={{@noMetricsReason}}
/>
{{/if}}
{{/if}}
</a> </a>

View File

@ -21,9 +21,19 @@
@dc={{@dc}} @dc={{@dc}}
@service={{@service.Service}} @service={{@service.Service}}
@item={{item}} @item={{item}}
@hasMetricsProvider={{this.hasMetricsProvider}} @hasMetricsProvider={{@hasMetricsProvider}}
@noMetricsReason={{this.noMetricsReason}}
>
{{#if (and @hasMetricsProvider (not-eq @service.Service.Kind 'ingress-gateway'))}}
<TopologyMetrics::Stats
@nspace={{or item.Namespace 'default'}}
@dc={{item.Datacenter}}
@endpoint='downstream-summary-for-service'
@service={{@service.Service.Service}}
@noMetricsReason={{this.noMetricsReason}} @noMetricsReason={{this.noMetricsReason}}
/> />
{{/if}}
</TopologyMetrics::Card>
{{/each}} {{/each}}
</div> </div>
{{/if}} {{/if}}
@ -31,7 +41,7 @@
<div class="metrics-header"> <div class="metrics-header">
{{@service.Service.Service}} {{@service.Service.Service}}
</div> </div>
{{#if this.hasMetricsProvider }} {{#if @hasMetricsProvider }}
<TopologyMetrics::Series <TopologyMetrics::Series
@nspace={{or @service.Service.Namespace 'default'}} @nspace={{or @service.Service.Namespace 'default'}}
@dc={{@dc}} @dc={{@dc}}
@ -76,14 +86,20 @@
<p>{{dc}}</p> <p>{{dc}}</p>
{{#each upstreams as |item|}} {{#each upstreams as |item|}}
<TopologyMetrics::Card <TopologyMetrics::Card
@nspace={{@nspace}}
@dc={{@dc}} @dc={{@dc}}
@item={{item}} @item={{item}}
@service={{@service.Service}} @service={{@service.Service}}
@type='upstream' >
@hasMetricsProvider={{this.hasMetricsProvider}} {{#if (and @hasMetricsProvider (not-eq @service.Service.Kind 'ingress-gateway'))}}
<TopologyMetrics::Stats
@nspace={{or item.Namespace 'default'}}
@dc={{item.Datacenter}}
@endpoint='upstream-summary-for-service'
@service={{@service.Service.Service}}
@noMetricsReason={{this.noMetricsReason}} @noMetricsReason={{this.noMetricsReason}}
/> />
{{/if}}
</TopologyMetrics::Card>
{{/each}} {{/each}}
</div> </div>
{{/each-in}} {{/each-in}}

View File

@ -1,38 +1,15 @@
import Component from '@glimmer/component'; import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking'; import { tracked } from '@glimmer/tracking';
import { action } from '@ember/object'; import { action } from '@ember/object';
import { inject as service } from '@ember/service';
export default class TopologyMetrics extends Component { export default class TopologyMetrics extends Component {
@service('ui-config') cfg;
@service('env') env;
// =attributes // =attributes
@tracked centerDimensions; @tracked centerDimensions;
@tracked downView; @tracked downView;
@tracked downLines = []; @tracked downLines = [];
@tracked upView; @tracked upView;
@tracked upLines = []; @tracked upLines = [];
@tracked hasMetricsProvider = false; @tracked noMetricsReason;
@tracked noMetricsReason = null;
constructor(owner, args) {
super(owner, args);
this.hasMetricsProvider = !!this.cfg.get().metrics_provider;
// Disable metrics fetching if we are not in the local DC since we don't
// currently support that for all providers.
//
// TODO we can make the configurable even before we have a full solution for
// multi-DC forwarding for Prometheus so providers that are global for all
// DCs like an external managed APM can still load in all DCs.
if (
this.env.var('CONSUL_DATACENTER_LOCAL') !== this.args.topology.get('Datacenter') ||
this.args.service.Service.Kind === 'ingress-gateway'
) {
this.noMetricsReason = 'Unable to fetch metrics for a remote datacenter';
}
}
// =methods // =methods
drawDownLines(items) { drawDownLines(items) {
@ -92,6 +69,14 @@ export default class TopologyMetrics extends Component {
// =actions // =actions
@action @action
calculate() { calculate() {
if (this.args.isRemoteDC) {
this.noMetricsReason = 'Unable to fetch metrics for a remote datacenter';
} else if (this.args.service.Service.Kind === 'ingress-gateway') {
this.noMetricsReason = 'Unable to fetch metrics for a ingress gateway';
} else {
this.noMetricsReason = null;
}
// Calculate viewBox dimensions // Calculate viewBox dimensions
this.downView = document.querySelector('#downstream-lines').getBoundingClientRect(); this.downView = document.querySelector('#downstream-lines').getBoundingClientRect();
this.upView = document.querySelector('#upstream-lines').getBoundingClientRect(); this.upView = document.querySelector('#upstream-lines').getBoundingClientRect();

View File

@ -1,12 +1,13 @@
{{#unless @noMetricsReason}} {{#if (not @noMetricsReason)}}
<DataSource <DataSource
@src={{uri @nspace @dc 'metrics' 'summary-for-service' @service @protocol}} @src={{uri @nspace @dc 'metrics' 'summary-for-service' @service @protocol}}
@onchange={{action 'change'}} @onchange={{action 'change'}}
@onerror={{action (mut error) value="error"}} @onerror={{action (mut error) value="error"}}
/> />
{{/unless}} {{/if}}
{{on-window 'resize' (action 'redraw')}} {{on-window 'resize' (action 'redraw')}}
{{did-insert (action 'redraw')}}
{{#if (not empty)}} {{#if (not empty)}}
{{#if data.labels}} {{#if data.labels}}

View File

@ -1,10 +1,10 @@
{{#unless @noMetricsReason}} {{#if (not @noMetricsReason)}}
<DataSource <DataSource
@src={{uri @nspace @dc 'metrics' @endpoint @service @protocol}} @src={{uri @nspace @dc 'metrics' @endpoint @service @protocol}}
@onchange={{action 'statsUpdate'}} @onchange={{action 'statsUpdate'}}
@onerror={{action (mut error) value="error"}} @onerror={{action (mut error) value="error"}}
/> />
{{/unless}} {{/if}}
<div class="stats"> <div class="stats">
{{#if hasLoaded }} {{#if hasLoaded }}

View File

@ -8,6 +8,7 @@ export default class TopologyMetricsUpLines extends Component {
@action @action
getIconPositions() { getIconPositions() {
const center = this.args.center; const center = this.args.center;
const view = this.args.view;
const lines = [...document.querySelectorAll('#upstream-lines path')]; const lines = [...document.querySelectorAll('#upstream-lines path')];
this.iconPositions = lines.map(item => { this.iconPositions = lines.map(item => {
@ -16,7 +17,7 @@ export default class TopologyMetricsUpLines extends Component {
return { return {
id: item.id, id: item.id,
x: Math.round(partLen.x - center.x), x: Math.round(partLen.x - center.x),
y: Math.round(partLen.y - center.y * 0.81), y: Math.round(partLen.y - view.y),
}; };
}); });
} }

View File

@ -1,12 +1,21 @@
import Route from '@ember/routing/route'; import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';
export default class TopologyRoute extends Route { export default class TopologyRoute extends Route {
@service('ui-config') config;
@service('env') env;
model() { model() {
const parent = this.routeName const parent = this.routeName
.split('.') .split('.')
.slice(0, -1) .slice(0, -1)
.join('.'); .join('.');
return this.modelFor(parent);
return {
...this.modelFor(parent),
hasMetricsProvider: !!this.config.get().metrics_provider,
isRemoteDC: this.env.var('CONSUL_DATACENTER_LOCAL') !== this.modelFor('dc').dc.Name,
};
} }
setupController(controller, model) { setupController(controller, model) {

View File

@ -13,7 +13,8 @@
Datacenter=dc Datacenter=dc
Service=items.firstObject Service=items.firstObject
)}} )}}
@isRemoteDC={{isRemoteDC}}
@hasMetricsProvider={{hasMetricsProvider}}
@oncreate={{route-action 'createIntention'}} @oncreate={{route-action 'createIntention'}}
/> />
{{else}} {{else}}