diff --git a/ui/app/components/client-subnav.js b/ui/app/components/client-subnav.js new file mode 100644 index 000000000..b7b2caffb --- /dev/null +++ b/ui/app/components/client-subnav.js @@ -0,0 +1,5 @@ +import Component from '@ember/component'; +import { tagName } from '@ember-decorators/component'; + +@tagName('') +export default class ClientSubnav extends Component {} diff --git a/ui/app/controllers/clients/client.js b/ui/app/controllers/clients/client/index.js similarity index 100% rename from ui/app/controllers/clients/client.js rename to ui/app/controllers/clients/client/index.js diff --git a/ui/app/router.js b/ui/app/router.js index 51e162268..6fdfc058b 100644 --- a/ui/app/router.js +++ b/ui/app/router.js @@ -26,7 +26,9 @@ Router.map(function() { }); this.route('clients', function() { - this.route('client', { path: '/:node_id' }); + this.route('client', { path: '/:node_id' }, function() { + this.route('monitor'); + }); }); this.route('servers', function() { diff --git a/ui/app/routes/clients/client.js b/ui/app/routes/clients/client.js index 64cf7d087..b10d57e0f 100644 --- a/ui/app/routes/clients/client.js +++ b/ui/app/routes/clients/client.js @@ -1,11 +1,8 @@ import { inject as service } from '@ember/service'; import Route from '@ember/routing/route'; -import { collect } from '@ember/object/computed'; import notifyError from 'nomad-ui/utils/notify-error'; -import { watchRecord, watchRelationship } from 'nomad-ui/utils/properties/watch'; -import WithWatchers from 'nomad-ui/mixins/with-watchers'; -export default class ClientRoute extends Route.extend(WithWatchers) { +export default class ClientRoute extends Route { @service store; model() { @@ -28,34 +25,4 @@ export default class ClientRoute extends Route.extend(WithWatchers) { } return model && model.get('allocations'); } - - setupController(controller, model) { - controller.set('flagAsDraining', model && model.isDraining); - - return super.setupController(...arguments); - } - - resetController(controller) { - controller.setProperties({ - eligibilityError: null, - stopDrainError: null, - drainError: null, - flagAsDraining: false, - showDrainNotification: false, - showDrainUpdateNotification: false, - showDrainStoppedNotification: false, - }); - } - - startWatchers(controller, model) { - if (model) { - controller.set('watchModel', this.watch.perform(model)); - controller.set('watchAllocations', this.watchAllocations.perform(model)); - } - } - - @watchRecord('node') watch; - @watchRelationship('allocations') watchAllocations; - - @collect('watch', 'watchAllocations') watchers; } diff --git a/ui/app/routes/clients/client/index.js b/ui/app/routes/clients/client/index.js new file mode 100644 index 000000000..04f66faa6 --- /dev/null +++ b/ui/app/routes/clients/client/index.js @@ -0,0 +1,39 @@ +import { inject as service } from '@ember/service'; +import Route from '@ember/routing/route'; +import { collect } from '@ember/object/computed'; +import { watchRecord, watchRelationship } from 'nomad-ui/utils/properties/watch'; +import WithWatchers from 'nomad-ui/mixins/with-watchers'; + +export default class ClientRoute extends Route.extend(WithWatchers) { + @service store; + + setupController(controller, model) { + controller.set('flagAsDraining', model && model.isDraining); + + return super.setupController(...arguments); + } + + resetController(controller) { + controller.setProperties({ + eligibilityError: null, + stopDrainError: null, + drainError: null, + flagAsDraining: false, + showDrainNotification: false, + showDrainUpdateNotification: false, + showDrainStoppedNotification: false, + }); + } + + startWatchers(controller, model) { + if (model) { + controller.set('watchModel', this.watch.perform(model)); + controller.set('watchAllocations', this.watchAllocations.perform(model)); + } + } + + @watchRecord('node') watch; + @watchRelationship('allocations') watchAllocations; + + @collect('watch', 'watchAllocations') watchers; +} diff --git a/ui/app/templates/allocations/allocation/index.hbs b/ui/app/templates/allocations/allocation/index.hbs index 5f02af788..db0f89c98 100644 --- a/ui/app/templates/allocations/allocation/index.hbs +++ b/ui/app/templates/allocations/allocation/index.hbs @@ -1,5 +1,5 @@ {{title "Allocation " model.name}} -{{allocation-subnav allocation=model}} +
{{#if error}}
diff --git a/ui/app/templates/clients/client.hbs b/ui/app/templates/clients/client.hbs index 470d66e2b..c24cd6895 100644 --- a/ui/app/templates/clients/client.hbs +++ b/ui/app/templates/clients/client.hbs @@ -1,478 +1 @@ -{{title "Client " (or model.name model.shortId)}} -
- {{#if eligibilityError}} -
-
-
-

Eligibility Error

-

{{eligibilityError}}

-
-
-
- -
-
- {{/if}} - {{#if stopDrainError}} -
-
-
-

Stop Drain Error

-

{{stopDrainError}}

-
-
-
- -
-
- {{/if}} - {{#if drainError}} -
-
-
-

Drain Error

-

{{drainError}}

-
-
-
- -
-
- {{/if}} - {{#if showDrainStoppedNotification}} -
-
-
-

Drain Stopped

-

The drain has been stopped and the node has been set to ineligible.

-
-
- -
-
-
- {{/if}} - {{#if showDrainUpdateNotification}} -
-
-
-

Drain Updated

-

The new drain specification has been applied.

-
-
- -
-
-
- {{/if}} - {{#if showDrainNotification}} -
-
-
-

Drain Complete

-

Allocations have been drained and the node has been set to ineligible.

-
-
- -
-
-
- {{/if}} -
-
- - - {{x-icon model.compositeStatusIcon}} - - -
-
-

- {{or model.name model.shortId}} -

-

- - - {{model.id}} - - -

-
-
- {{#if model.isDraining}} - - {{/if}} -
-
- -
-
- -
-
- Client Details - - Status - {{model.status}} - - - Address - {{model.httpAddr}} - - - Datacenter - {{model.datacenter}} - - - Drivers - {{#if model.unhealthyDrivers.length}} - {{x-icon "warning" class="is-text is-warning"}} - {{model.unhealthyDrivers.length}} of {{model.detectedDrivers.length}} {{pluralize "driver" model.detectedDrivers.length}} unhealthy - {{else}} - All healthy - {{/if}} - -
-
- - {{#if model.drainStrategy}} -
-
-
Drain Strategy
-
-
- {{#if (not model.drainStrategy.hasNoDeadline)}} - - Duration - {{#if model.drainStrategy.isForced}} - -- - {{else}} - - {{format-duration model.drainStrategy.deadline}} - - {{/if}} - - {{/if}} - - {{if model.drainStrategy.hasNoDeadline "Deadline" "Remaining"}} - {{#if model.drainStrategy.hasNoDeadline}} - No deadline - {{else if model.drainStrategy.isForced}} - -- - {{else}} - - {{moment-from-now model.drainStrategy.forceDeadline interval=1000 hideAffix=true}} - - {{/if}} - - - Force Drain - {{#if model.drainStrategy.isForced}} - {{x-icon "warning" class="is-text is-warning"}} Yes - {{else}} - No - {{/if}} - - - Drain System Jobs - {{if model.drainStrategy.ignoreSystemJobs "No" "Yes"}} - -
- {{#if (not model.drainStrategy.isForced)}} -
- -
- {{/if}} -
-
-
-
-
-
-
-

Complete

-

{{model.completeAllocations.length}}

-
-
-
-
-

Migrating

-

{{model.migratingAllocations.length}}

-
-
-
-
-

Remaining

-

{{model.runningAllocations.length}}

-
-
-
-
-

Status

- {{#if model.lastMigrateTime}} -

{{moment-to-now model.lastMigrateTime interval=1000 hideAffix=true}} since an allocation was successfully migrated.

- {{else}} -

No allocations migrated.

- {{/if}} -
-
-
-
- {{/if}} - -
-
- Resource Utilization -
-
-
-
- -
-
- -
-
-
-
- -
-
-
- Allocations - - {{#if preemptions.length}} - - {{/if}} -
- -
-
- - - - - ID - Modified - Created - Status - Job - Version - Volume - CPU - Memory - - - - - -
- -
-
-
-
- -
-
- Client Events -
-
- - - Time - Subsystem - Message - - - - {{format-ts row.model.time}} - {{row.model.subsystem}} - - {{#if row.model.message}} - {{#if row.model.driver}} - {{row.model.driver}} - {{/if}} - {{row.model.message}} - {{else}} - No message - {{/if}} - - - - -
-
- - {{#if sortedHostVolumes.length}} -
-
- Host Volumes -
-
- - - Name - Source - Permissions - - - - {{row.model.name}} - {{row.model.path}} - {{if row.model.readOnly "Read" "Read/Write"}} - - - -
-
- {{/if}} - -
-
- Driver Status -
-
- - -
-
- {{a.item.name}} -
-
- {{#if a.item.detected}} - - - {{if a.item.healthy "Healthy" "Unhealthy"}} - - {{/if}} -
-
- - Detected - {{if a.item.detected "Yes" "No"}} - - - - Last Updated - - {{moment-from-now a.item.updateTime interval=1000}} - - - -
-
-
- -

{{a.item.healthDescription}}

-
-
- {{capitalize a.item.name}} Attributes -
- {{#if a.item.attributes.attributesStructured}} -
- -
- {{else}} -
-
-

No Driver Attributes

-
-
- {{/if}} -
-
-
-
-
- -
-
- Attributes -
-
- -
-
- Meta -
- {{#if model.meta.attributesStructured}} -
- -
- {{else}} -
-
-

No Meta Attributes

-

This client is configured with no meta attributes.

-
-
- {{/if}} -
-
+{{outlet}} diff --git a/ui/app/templates/clients/client/index.hbs b/ui/app/templates/clients/client/index.hbs new file mode 100644 index 000000000..fc3026f7a --- /dev/null +++ b/ui/app/templates/clients/client/index.hbs @@ -0,0 +1,479 @@ +{{title "Client " (or model.name model.shortId)}} + +
+ {{#if eligibilityError}} +
+
+
+

Eligibility Error

+

{{eligibilityError}}

+
+
+
+ +
+
+ {{/if}} + {{#if stopDrainError}} +
+
+
+

Stop Drain Error

+

{{stopDrainError}}

+
+
+
+ +
+
+ {{/if}} + {{#if drainError}} +
+
+
+

Drain Error

+

{{drainError}}

+
+
+
+ +
+
+ {{/if}} + {{#if showDrainStoppedNotification}} +
+
+
+

Drain Stopped

+

The drain has been stopped and the node has been set to ineligible.

+
+
+ +
+
+
+ {{/if}} + {{#if showDrainUpdateNotification}} +
+
+
+

Drain Updated

+

The new drain specification has been applied.

+
+
+ +
+
+
+ {{/if}} + {{#if showDrainNotification}} +
+
+
+

Drain Complete

+

Allocations have been drained and the node has been set to ineligible.

+
+
+ +
+
+
+ {{/if}} +
+
+ + + {{x-icon model.compositeStatusIcon}} + + +
+
+

+ {{or model.name model.shortId}} +

+

+ + + {{model.id}} + + +

+
+
+ {{#if model.isDraining}} + + {{/if}} +
+
+ +
+
+ +
+
+ Client Details + + Status + {{model.status}} + + + Address + {{model.httpAddr}} + + + Datacenter + {{model.datacenter}} + + + Drivers + {{#if model.unhealthyDrivers.length}} + {{x-icon "warning" class="is-text is-warning"}} + {{model.unhealthyDrivers.length}} of {{model.detectedDrivers.length}} {{pluralize "driver" model.detectedDrivers.length}} unhealthy + {{else}} + All healthy + {{/if}} + +
+
+ + {{#if model.drainStrategy}} +
+
+
Drain Strategy
+
+
+ {{#if (not model.drainStrategy.hasNoDeadline)}} + + Duration + {{#if model.drainStrategy.isForced}} + -- + {{else}} + + {{format-duration model.drainStrategy.deadline}} + + {{/if}} + + {{/if}} + + {{if model.drainStrategy.hasNoDeadline "Deadline" "Remaining"}} + {{#if model.drainStrategy.hasNoDeadline}} + No deadline + {{else if model.drainStrategy.isForced}} + -- + {{else}} + + {{moment-from-now model.drainStrategy.forceDeadline interval=1000 hideAffix=true}} + + {{/if}} + + + Force Drain + {{#if model.drainStrategy.isForced}} + {{x-icon "warning" class="is-text is-warning"}} Yes + {{else}} + No + {{/if}} + + + Drain System Jobs + {{if model.drainStrategy.ignoreSystemJobs "No" "Yes"}} + +
+ {{#if (not model.drainStrategy.isForced)}} +
+ +
+ {{/if}} +
+
+
+
+
+
+
+

Complete

+

{{model.completeAllocations.length}}

+
+
+
+
+

Migrating

+

{{model.migratingAllocations.length}}

+
+
+
+
+

Remaining

+

{{model.runningAllocations.length}}

+
+
+
+
+

Status

+ {{#if model.lastMigrateTime}} +

{{moment-to-now model.lastMigrateTime interval=1000 hideAffix=true}} since an allocation was successfully migrated.

+ {{else}} +

No allocations migrated.

+ {{/if}} +
+
+
+
+ {{/if}} + +
+
+ Resource Utilization +
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+
+ Allocations + + {{#if preemptions.length}} + + {{/if}} +
+ +
+
+ + + + + ID + Modified + Created + Status + Job + Version + Volume + CPU + Memory + + + + + +
+ +
+
+
+
+ +
+
+ Client Events +
+
+ + + Time + Subsystem + Message + + + + {{format-ts row.model.time}} + {{row.model.subsystem}} + + {{#if row.model.message}} + {{#if row.model.driver}} + {{row.model.driver}} + {{/if}} + {{row.model.message}} + {{else}} + No message + {{/if}} + + + + +
+
+ + {{#if sortedHostVolumes.length}} +
+
+ Host Volumes +
+
+ + + Name + Source + Permissions + + + + {{row.model.name}} + {{row.model.path}} + {{if row.model.readOnly "Read" "Read/Write"}} + + + +
+
+ {{/if}} + +
+
+ Driver Status +
+
+ + +
+
+ {{a.item.name}} +
+
+ {{#if a.item.detected}} + + + {{if a.item.healthy "Healthy" "Unhealthy"}} + + {{/if}} +
+
+ + Detected + {{if a.item.detected "Yes" "No"}} + + + + Last Updated + + {{moment-from-now a.item.updateTime interval=1000}} + + + +
+
+
+ +

{{a.item.healthDescription}}

+
+
+ {{capitalize a.item.name}} Attributes +
+ {{#if a.item.attributes.attributesStructured}} +
+ +
+ {{else}} +
+
+

No Driver Attributes

+
+
+ {{/if}} +
+
+
+
+
+ +
+
+ Attributes +
+
+ +
+
+ Meta +
+ {{#if model.meta.attributesStructured}} +
+ +
+ {{else}} +
+
+

No Meta Attributes

+

This client is configured with no meta attributes.

+
+
+ {{/if}} +
+
diff --git a/ui/app/templates/clients/client/monitor.hbs b/ui/app/templates/clients/client/monitor.hbs new file mode 100644 index 000000000..b43640d02 --- /dev/null +++ b/ui/app/templates/clients/client/monitor.hbs @@ -0,0 +1,4 @@ +{{title "Client " (or model.name model.shortId)}} + +
+
diff --git a/ui/app/templates/components/client-subnav.hbs b/ui/app/templates/components/client-subnav.hbs new file mode 100644 index 000000000..23370e522 --- /dev/null +++ b/ui/app/templates/components/client-subnav.hbs @@ -0,0 +1,6 @@ +
+
    +
  • {{#link-to "clients.client.index" client activeClass="is-active"}}Overview{{/link-to}}
  • +
  • {{#link-to "clients.client.monitor" client activeClass="is-active"}}Monitor{{/link-to}}
  • +
+