diff --git a/app/authenticated/project/route.js b/app/authenticated/project/route.js
index 3cdece11b..c2a7084be 100644
--- a/app/authenticated/project/route.js
+++ b/app/authenticated/project/route.js
@@ -10,7 +10,8 @@ const VALID_ROUTES = ['apps-tab', 'authenticated.project.security.members.index'
'authenticated.project.ns', 'authenticated.project.certificates',
'authenticated.project.secrets', 'authenticated.project.config-maps',
'authenticated.project.registries', 'authenticated.project.alert',
- 'authenticated.project.logging', 'authenticated.project.pipeline.settings'];
+ 'authenticated.project.logging', 'authenticated.project.pipeline.settings',
+ 'authenticated.project.monitoring.project-setting'];
export default Route.extend(Preload, {
access: service(),
diff --git a/app/components/accordion-container/component.js b/app/components/accordion-container/component.js
new file mode 100644
index 000000000..4e9e5abc3
--- /dev/null
+++ b/app/components/accordion-container/component.js
@@ -0,0 +1,35 @@
+import Component from '@ember/component';
+import layout from './template';
+
+export default Component.extend({
+ layout,
+ model: null,
+ expandOnInit: true,
+ sortBy: 'displayState',
+ descending: true,
+ initExpand: true,
+ headers: [
+ {
+ name: 'displayState',
+ sort: ['displayState'],
+ translationKey: 'generic.state',
+ width: 120
+ },
+ {
+ name: 'name',
+ sort: ['name'],
+ translationKey: 'generic.name',
+ },
+ {
+ name: 'image',
+ sort: ['image'],
+ translationKey: 'generic.image',
+ },
+ {
+ name: 'restarts',
+ sort: ['restarts'],
+ translationKey: 'generic.restarts',
+ width: 100
+ },
+ ],
+});
diff --git a/app/components/accordion-container/template.hbs b/app/components/accordion-container/template.hbs
new file mode 100644
index 000000000..c28fc9a09
--- /dev/null
+++ b/app/components/accordion-container/template.hbs
@@ -0,0 +1,62 @@
+{{#accordion-list-item
+ title=(t 'containersSection.title')
+ detail=(t 'containersSection.detail')
+ expandAll=expandAll
+ expand=(action expandFn)
+ expandOnInit=expandOnInit
+ componentName='sortable-table'
+ as | parent |
+}}
+ {{#sortable-table
+ tableClassNames="double-rows"
+ body=containers
+ bulkActions=false
+ descending=descending
+ sortBy=sortBy
+ stickyHeader=stickyHeader
+ fullRows=true
+ search=search
+ headers=headers as |sortable kind inst dt|
+ }}
+ {{#if (eq kind "row")}}
+
+ {{/if}}
+ {{/sortable-table}}
+{{/accordion-list-item}}
diff --git a/app/components/accordion-pod/component.js b/app/components/accordion-pod/component.js
index dec415e63..ef7824caf 100644
--- a/app/components/accordion-pod/component.js
+++ b/app/components/accordion-pod/component.js
@@ -5,7 +5,7 @@ import layout from './template';
export default Component.extend(ManageLabels, {
layout,
model: null,
- initExpandAll: true,
+ expandOnInit: true,
sortBy: 'displayState',
showKind: true,
descending: true,
@@ -21,6 +21,7 @@ export default Component.extend(ManageLabels, {
name: 'name',
sort: ['name'],
translationKey: 'generic.name',
+ width: 400
},
{
name: 'displayImage',
@@ -31,18 +32,7 @@ export default Component.extend(ManageLabels, {
name: 'node',
sort: ['displayName'],
translationKey: 'generic.node',
- },
- {
- name: 'displayIp',
- sort: ['displayIp'],
- translationKey: 'generic.ipAddress',
width: 180
},
],
-
- expandAllObserve: function() {
- let expandAll = this.get('expandAll');
-
- this.set('initExpandAll', expandAll);
- }.observes('expandAll')
});
diff --git a/app/components/accordion-pod/template.hbs b/app/components/accordion-pod/template.hbs
index 08168b210..bf06ce194 100644
--- a/app/components/accordion-pod/template.hbs
+++ b/app/components/accordion-pod/template.hbs
@@ -1,8 +1,9 @@
{{#accordion-list-item
title=(t 'podsSection.title')
detail=(t 'podsSection.detail')
- expandAll=initExpandAll
+ expandAll=expandAll
expand=(action expandFn)
+ expandOnInit=expandOnInit
componentName='sortable-table'
as | parent |
}}
@@ -28,25 +29,25 @@
{{badge-state model=inst}}
-
+
{{#each inst.containers as |container|}}
{{#if container.showTransitioningMessage}}
diff --git a/app/components/cluster-dashboard/component.js b/app/components/cluster-dashboard/component.js
deleted file mode 100644
index 5c77293c4..000000000
--- a/app/components/cluster-dashboard/component.js
+++ /dev/null
@@ -1,82 +0,0 @@
-import C from 'ui/utils/constants';
-import Component from '@ember/component';
-import { set, get, computed, observer } from '@ember/object';
-import { alias } from '@ember/object/computed';
-import { inject as service } from '@ember/service';
-import layout from './template';
-
-export default Component.extend({
- intl: service(),
- scope: service(),
-
- layout,
-
- nodes: null,
- components: null,
- componentStatuses: alias('scope.currentCluster.componentStatuses'),
-
- init() {
- this._super(...arguments);
- this.setComponents();
- },
-
- updateComponentsStatus: observer('componentStatuses.@each.conditions', 'nodes.@each.{state}', function() {
- this.setComponents();
- }),
-
- showDashboard: computed('scope.currentCluster.isReady', 'nodes.[]', function() {
- return get(this, 'nodes').length && get(this, 'scope.currentCluster.isReady')
- }),
-
- inactiveNodes: computed('nodes.@each.state', function() {
- return get(this, 'nodes').filter( (n) => C.ACTIVEISH_STATES.indexOf(get(n, 'state')) === -1 );
- }),
-
- unhealthyComponents: computed('componentStatuses.@each.conditions', function() {
- return (get(this, 'componentStatuses') || [])
- .filter((s) => !s.conditions.any((c) => c.status === 'True'));
- }),
-
- setComponents() {
- const etcd = this.getEtcdComponent();
- const controller = this.getControllerComponent();
- const scheduler = this.getSchedulerComponent();
- const node = this.getNodeComponent();
-
- set(this, 'components', [etcd, controller, scheduler, node]);
- },
-
- getEtcdComponent() {
- return {
- name: get(this, 'intl').t('clusterDashboard.etcd'),
- healthy: this.isHealthy('etcd'),
- };
- },
-
- getControllerComponent() {
- return {
- name: get(this, 'intl').t('clusterDashboard.controllerManager'),
- healthy: this.isHealthy('controller-manager'),
- };
- },
-
- getSchedulerComponent() {
- return {
- name: get(this, 'intl').t('clusterDashboard.scheduler'),
- healthy: this.isHealthy('scheduler'),
- };
- },
-
- getNodeComponent() {
- return {
- name: get(this, 'intl').t('clusterDashboard.node'),
- healthy: get(this, 'inactiveNodes.length') === 0,
- };
- },
-
- isHealthy(field) {
- return (get(this, 'componentStatuses') || [])
- .filter((s) => s.name.startsWith(field))
- .any((s) => s.conditions.any((c) => c.status === 'True'));
- },
-});
diff --git a/app/components/cluster-dashboard/template.hbs b/app/components/cluster-dashboard/template.hbs
deleted file mode 100644
index 966815db8..000000000
--- a/app/components/cluster-dashboard/template.hbs
+++ /dev/null
@@ -1,45 +0,0 @@
-{{#if showDashboard}}
- {{node-gauges nodes=nodes}}
-
- {{#each components as |c|}}
-
- {{/each}}
-
-
- {{#each unhealthyComponents as |component|}}
-
-
-
-
-
-
{{t 'clusterDashboard.alert.component' component=component.name}}
-
-
- {{/each}}
- {{#each inactiveNodes as |node|}}
-
-
-
-
-
-
{{t 'clusterDashboard.alert.node' node=node.displayName}}
-
-
- {{/each}}
-
-{{else}}
- {{empty-table
- resource="container"
- showNew=scope.currentCluster.canAddNode
- newRoute="authenticated.cluster.nodes.templates"
- newTranslationKey="nodesPage.addNode"
- disabled=(rbac-prevents resource="machine" scope="global" permission="create")
- ctx=""
- }}
-{{/if}}
diff --git a/app/components/container-dot/component.js b/app/components/container-dot/component.js
index 8dad08aeb..951d4ef43 100644
--- a/app/components/container-dot/component.js
+++ b/app/components/container-dot/component.js
@@ -31,7 +31,7 @@ export default Component.extend({
},
details(/* event*/) {
- var route = 'container';
+ var route = 'pod';
if ( this.get('model.isVm') ) {
route = 'virtualmachine';
diff --git a/app/components/container-metrics/component.js b/app/components/container-metrics/component.js
new file mode 100644
index 000000000..2d17a74de
--- /dev/null
+++ b/app/components/container-metrics/component.js
@@ -0,0 +1,20 @@
+import Component from '@ember/component';
+import Metrics from 'shared/mixins/metrics';
+import layout from './template';
+import { get, set } from '@ember/object';
+
+export default Component.extend(Metrics, {
+ layout,
+
+ filters: { resourceType: 'container' },
+
+ projectScope: true,
+
+ init() {
+ this._super(...arguments);
+ set(this, 'metricParams', {
+ podName: get(this, 'podId'),
+ containerName: get(this, 'resourceId')
+ });
+ },
+});
\ No newline at end of file
diff --git a/app/components/container-metrics/template.hbs b/app/components/container-metrics/template.hbs
new file mode 100644
index 000000000..602886c31
--- /dev/null
+++ b/app/components/container-metrics/template.hbs
@@ -0,0 +1,8 @@
+
+ {{metrics-action
+ queryAction="query"
+ allowDetail=false
+ state=state
+ }}
+ {{metrics-graph graphs=graphs loading=state.loading noGraphs=state.noGraphs}}
+
\ No newline at end of file
diff --git a/app/components/container/form-container-links/component.js b/app/components/container/form-container-links/component.js
deleted file mode 100644
index 9f3fdb9b0..000000000
--- a/app/components/container/form-container-links/component.js
+++ /dev/null
@@ -1,103 +0,0 @@
-import { alias } from '@ember/object/computed';
-import { inject as service } from '@ember/service';
-import Component from '@ember/component';
-import ContainerChoices from 'ui/mixins/container-choices';
-import {
- STATUS,
- STATUS_INTL_KEY,
- classForStatus
-} from 'shared/components/accordion-list-item/component';
-import layout from './template';
-
-const headers = [
- {
- name: 'name',
- translationKey: 'formContainerLinks.name.label',
- },
- {
- name: 'alias',
- translationKey: 'formContainerLinks.alias.label',
- },
-];
-
-export default Component.extend(ContainerChoices, {
- router: service(),
- growl: service(),
-
- layout,
- // Inputs
- editing: null,
- instance: null,
-
- tagName: '',
- errors: null,
-
- headers,
-
- statusClass: null,
- linksArray: alias('instance.instanceLinks'),
-
- actions: {
- addLink() {
- let links = this.get('linksArray');
-
- if ( !links ) {
- links = [];
- this.set('linksArray', links);
- }
-
- links.pushObject(this.get('store').createRecord({
- type: 'link',
- name: '',
- alias: '',
- }));
- },
-
- removeLink(obj) {
- this.get('linksArray').removeObject(obj);
- },
-
- followLink(str) {
- let stack, stackName, containerName;
-
- if ( str.includes('/')) {
- [stackName, containerName] = name.split('/');
- let stacks = this.get('store').all('stack');
-
- stack = stacks.findBy('name', stackName);
- } else {
- stack = this.get('stack');
- containerName = str;
- }
-
- if ( stack ) {
- let container = stack.get('instances').findBy('name', containerName);
-
- if ( container ) {
- this.get('router').transitionTo('container', container.get('id'));
-
- return;
- }
- }
-
- this.get('growl').fromError(`Unable to find container for "${ name }"`);
- },
- },
-
- status: function() {
- let k = STATUS.NONE;
- let count = (this.get('linksArray') || []).filterBy('name').get('length') || 0;
-
- if ( count ) {
- if ( this.get('errors.length') ) {
- k = STATUS.INCOMPLETE;
- } else {
- k = STATUS.COUNTCONFIGURED;
- }
- }
-
- this.set('statusClass', classForStatus(k));
-
- return this.get('intl').t(`${ STATUS_INTL_KEY }.${ k }`, { count });
- }.property('linksArray.@each.name'),
-});
diff --git a/app/components/container/form-container-links/template.hbs b/app/components/container/form-container-links/template.hbs
deleted file mode 100644
index 4fdba4df8..000000000
--- a/app/components/container/form-container-links/template.hbs
+++ /dev/null
@@ -1,66 +0,0 @@
-{{#accordion-list-item
- title=(t 'formContainerLinks.title')
- detail=(t 'formContainerLinks.detail' appName=settings.appName)
- status=status
- statusClass=statusClass
- expandAll=expandAll
- expand=(action expandFn)
-}}
- {{#if editing}}
-
-
- {{t 'formContainerLinks.addActionLabel'}}
-
-
-
-
- {{t 'formContainerLinks.name.label'}}
-
- {{t 'formContainerLinks.alias.label'}}
-
-
- {{#each linksArray as |link|}}
-
-
- {{schema/input-container
- value=link.name
- exclude=launchConfig.id
- stack=stack
- }}
-
-
-
-
-
- {{input class="form-control input-sm" type="text" value=link.alias placeholder=(t 'formContainerLinks.alias.placeholder')}}
-
-
- {{#unless link.existing}}
- {{t 'generic.remove'}}
- {{/unless}}
-
-
- {{/each}}
-
- {{else}}
- {{#sortable-table
- classNames="grid sortable-table"
- body=linksArray
- descending=descending
- bulkActions=false
- pagingLabel="pagination.link"
- headers=headers as |sortable kind row dt|}}
- {{#if (eq kind "row")}}
-
- {{row.name}}
- {{row.alias}}
-
- {{else if (eq kind "nomatch")}}
-
{{t 'formContainerLinks.noMatch'}}
- {{else if (eq kind "norows")}}
-
{{t 'formContainerLinks.noData'}}
- {{/if}}
- {{/sortable-table}}
- {{/if}}
-
-{{/accordion-list-item}}
diff --git a/app/components/container/form-custom-metrics/component.js b/app/components/container/form-custom-metrics/component.js
new file mode 100644
index 000000000..4c75e9b92
--- /dev/null
+++ b/app/components/container/form-custom-metrics/component.js
@@ -0,0 +1,52 @@
+import { inject as service } from '@ember/service';
+import { get, set, observer } from '@ember/object';
+import Component from '@ember/component';
+import layout from './template';
+
+const HTTPS = 'HTTPS';
+const HTTP = 'HTTP'
+
+const OPTIONS = [
+ {
+ label: HTTP,
+ value: HTTP
+ },
+ {
+ label: HTTPS,
+ value: HTTPS
+ }
+];
+
+export default Component.extend({
+ scope: service(),
+
+ layout,
+
+ editing: false,
+
+ protocolOptions: OPTIONS,
+
+ init() {
+ this._super(...arguments);
+
+ set(this, 'metrics', get(this, 'workload.workloadMetrics') || []);
+ },
+
+ actions: {
+ add() {
+ get(this, 'metrics').pushObject({
+ path: '',
+ port: '',
+ schema: HTTP
+ });
+ },
+
+ remove(obj) {
+ get(this, 'metrics').removeObject(obj);
+ },
+ },
+
+ metricsChanged: observer('metrics.@each.{port,path,schema}', function() {
+ set(this, 'workload.workloadMetrics', get(this, 'metrics').filter((metric) => get(metric, 'port')));
+ })
+});
\ No newline at end of file
diff --git a/app/components/container/form-custom-metrics/template.hbs b/app/components/container/form-custom-metrics/template.hbs
new file mode 100644
index 000000000..4ff18a539
--- /dev/null
+++ b/app/components/container/form-custom-metrics/template.hbs
@@ -0,0 +1,77 @@
+{{#accordion-list-item
+ title=(t 'formCustomMetrics.title')
+ detail=(t 'formCustomMetrics.detail')
+ expandAll=expandAll
+ expand=(action expandFn)
+}}
+
+ {{#if metrics.length}}
+
+
+
+ {{t 'formCustomMetrics.port.label'}}{{#if editing}}{{field-required}}{{/if}}
+
+ {{t 'formCustomMetrics.path.label'}}
+
+ {{t 'formCustomMetrics.protocol.label'}}
+
+
+
+
+ {{#each metrics as |metric|}}
+
+
+ {{#if editing}}
+ {{input-integer class="form-control input-sm public" min="1" max="65535" value=metric.port placeholder=(t 'formCustomMetrics.port.placeholder')}}
+ {{else}}
+ {{metric.port}}
+ {{/if}}
+
+
+
+
+ {{#input-or-display editable=editing value=metric.path}}
+ {{input class="form-control input-sm" type="text" value=metric.path placeholder=(t 'formCustomMetrics.path.placeholder')}}
+ {{/input-or-display}}
+
+
+
+ {{#if editing}}
+ {{new-select
+ class="form-control input-sm"
+ content=protocolOptions
+ value=metric.schema
+ }}
+ {{else}}
+ {{metric.schema}}
+ {{/if}}
+
+
+
+ {{#if editing}}
+
+ {{t 'generic.remove'}}
+
+ {{/if}}
+
+
+ {{/each}}
+
+
+ {{else}}
+ {{#unless editing}}
+
{{t 'formCustomMetrics.noPorts'}}
+ {{/unless}}
+ {{/if}}
+
+
+
+ {{#if editing}}
+
+
+ {{t 'formCustomMetrics.addActionLabel'}}
+
+ {{/if}}
+
+
+{{/accordion-list-item}}
\ No newline at end of file
diff --git a/app/components/container/new-edit/component.js b/app/components/container/new-edit/component.js
index 2e7c060d1..778bb7d32 100644
--- a/app/components/container/new-edit/component.js
+++ b/app/components/container/new-edit/component.js
@@ -15,6 +15,7 @@ export default Component.extend(NewOrEdit, ChildHook, {
clusterStore: service(),
intl: service(),
prefs: service(),
+ scope: service(),
settings: service(),
layout,
diff --git a/app/components/container/new-edit/template.hbs b/app/components/container/new-edit/template.hbs
index c7a3294a2..30c769824 100644
--- a/app/components/container/new-edit/template.hbs
+++ b/app/components/container/new-edit/template.hbs
@@ -248,6 +248,18 @@
expandFn=expandFn
expanded=securitySectionExpanded
}}
+
+ {{#unless isSidekick}}
+ {{#if scope.currentCluster.enableClusterMonitoring}}
+ {{container/form-custom-metrics
+ classNames="accordion-wrapper"
+ workload=service
+ editing=true
+ expandAll=al.expandAll
+ expandFn=expandFn
+ }}
+ {{/if}}
+ {{/unless}}
{{/advanced-section}}
{{/accordion-list}}
diff --git a/app/components/info-multi-stats/component.js b/app/components/info-multi-stats/component.js
deleted file mode 100644
index 2f66d0e3a..000000000
--- a/app/components/info-multi-stats/component.js
+++ /dev/null
@@ -1,45 +0,0 @@
-import Component from '@ember/component';
-import layout from './template';
-
-export default Component.extend({
- layout,
- model: null,
- mode: 'small',
- smallWidth: 60,
- smallHeight: 25,
- largeTargetId: null,
- linkName: 'containerStats',
-
- tagName: '',
- cpuFields: [{
- key: 'cpuUser',
- displayName: 'infoMultiStats.cpuSection.user'
- }, {
- key: 'cpuSystem',
- displayName: 'infoMultiStats.cpuSection.system'
- }],
- memoryFields: [{
- key: 'memory',
- displayName: 'infoMultiStats.memorySection.used'
- }],
- networkFields: [{
- key: 'networkTx',
- displayName: 'infoMultiStats.networkSection.transmit'
- }, {
- key: 'networkRx',
- displayName: 'infoMultiStats.networkSection.receive'
- }],
- storageFields: [{
- key: 'storageWrite',
- displayName: 'infoMultiStats.storageSection.write'
- }, {
- key: 'storageRead',
- displayName: 'infoMultiStats.storageSection.read'
- }],
-
- actions: {
- toggle() {
- this.set('mode', (this.get('mode') === 'small' ? 'large' : 'small'));
- },
- },
-});
diff --git a/app/components/info-multi-stats/template.hbs b/app/components/info-multi-stats/template.hbs
deleted file mode 100644
index 9fe6a35d9..000000000
--- a/app/components/info-multi-stats/template.hbs
+++ /dev/null
@@ -1,112 +0,0 @@
-{{#multi-container-stats model=model linkName=linkName emitMaps=true as |stats|}}
- {{#liquid-if (eq mode "small") class=(if stats.loading 'child-loading')}}
- {{#if stats.loading}}
-
Connecting…
- {{else if stats.active}}
- {{spark-line
- data=stats.cpuTotal
- width=smallWidth height=smallHeight
- prefix="containersPage.table.sparkPrefixCpu"
- formatter="percent"
- gradient="cpu"
- minMax=100
- }}
-
- {{spark-line
- data=stats.memory
- width=smallWidth height=smallHeight
- prefix="containersPage.table.sparkPrefixMemory"
- formatter="mib"
- gradient="memory"
- maxDoubleInital=true
- }}
-
- {{spark-line
- data=stats.networkTotal
- width=smallWidth height=smallHeight
- prefix="containersPage.table.sparkPrefixNetwork"
- formatter="kbps"
- gradient="network"
- minMax=100
- }}
-
- {{spark-line
- data=stats.storageTotal
- width=smallWidth height=smallHeight
- prefix="containersPage.table.sparkPrefixStorage"
- formatter="kbps"
- gradient="storage"
- minMax=100
- }}
-
-
- {{else}}
-
Stats not available
- {{/if}}
- {{/liquid-if}}
- {{#if (eq mode "large")}}
- {{#ember-wormhole to=largeTargetId}}
-
- {{#if stats.loading}}
-
- {{else if stats.active}}
-
-
-
{{t 'infoMultiStats.cpuSection.labelText'}}
- {{graph-area
- model=stats
- fields=cpuFields
- formatter="percent"
- gradient="cpu"
- minMax=100
- }}
-
-
-
{{t 'infoMultiStats.memorySection.labelText'}}
- {{graph-area
- model=stats
- fields=memoryFields
- formatter="mib"
- gradient="memory"
- maxDoubleInital=true
- }}
-
-
-
-
-
{{t 'infoMultiStats.networkSection.labelText'}}
- {{graph-area
- model=stats
- fields=networkFields
- formatter="kbps"
- gradient="network"
- minMax=100
- }}
-
-
-
{{t 'infoMultiStats.storageSection.labelText'}}
- {{graph-area
- model=stats
- fields=storageFields
- formatter="kbps"
- gradient="storage"
- minMax=100
- }}
-
-
-
- {{else}}
-
- {{/if}}
-
- {{/ember-wormhole}}
- {{/if}}
-{{/multi-container-stats}}
diff --git a/app/components/new-catalog/template.hbs b/app/components/new-catalog/template.hbs
index 626efe717..e47982804 100644
--- a/app/components/new-catalog/template.hbs
+++ b/app/components/new-catalog/template.hbs
@@ -20,7 +20,7 @@
{{marked-down markdown=appReadmeContent}}
{{else if (not noAppReadme)}}
-
+
{{else if noAppReadme}}
@@ -122,7 +122,7 @@
{{#if getTemplate.isRunning}}
{{else}}
@@ -167,7 +167,7 @@
{{#if decoding}}
{{else}}
diff --git a/app/components/node-conditions/template.hbs b/app/components/node-conditions/template.hbs
deleted file mode 100644
index 93d9dc64a..000000000
--- a/app/components/node-conditions/template.hbs
+++ /dev/null
@@ -1,14 +0,0 @@
-
- {{#each conditions as |c|}}
-
- {{/each}}
-
diff --git a/app/components/node-gauges/template.hbs b/app/components/node-gauges/template.hbs
deleted file mode 100644
index 13be3637e..000000000
--- a/app/components/node-gauges/template.hbs
+++ /dev/null
@@ -1,5 +0,0 @@
-
- {{#each gauges as |gauge|}}
-
{{percent-gauge value=gauge.value title=gauge.title subtitle=gauge.subtitle ticks=gauge.ticks}}
- {{/each}}
-
\ No newline at end of file
diff --git a/app/components/node-group/template.hbs b/app/components/node-group/template.hbs
index 4ac39d7b5..db8fa001f 100644
--- a/app/components/node-group/template.hbs
+++ b/app/components/node-group/template.hbs
@@ -1,7 +1,7 @@
{{#if (and model.id model.clusterId)}}
-
+
{{t 'nodeGroup.label' name=model.displayName}}
{{else}}
diff --git a/app/components/node-row/template.hbs b/app/components/node-row/template.hbs
index 4d21465ec..cb8c3a396 100644
--- a/app/components/node-row/template.hbs
+++ b/app/components/node-row/template.hbs
@@ -10,12 +10,12 @@
{{#if (eq view "global")}}
{{#if model.clusterId}}
- {{model.displayName}}
+ {{model.displayName}}
{{else}}
{{model.displayName}}
{{/if}}
{{else}}
- {{model.displayName}}
+ {{model.displayName}}
{{/if}}
{{#if (or model.externalIpAddress model.ipAddress)}}
{{node-ip model=model}}
diff --git a/app/components/pod-metrics/component.js b/app/components/pod-metrics/component.js
new file mode 100644
index 000000000..656915a2e
--- /dev/null
+++ b/app/components/pod-metrics/component.js
@@ -0,0 +1,17 @@
+import Component from '@ember/component';
+import Metrics from 'shared/mixins/metrics';
+import layout from './template';
+import { get, set } from '@ember/object';
+
+export default Component.extend(Metrics, {
+ layout,
+
+ filters: { resourceType: 'pod' },
+
+ projectScope: true,
+
+ init() {
+ this._super(...arguments);
+ set(this, 'metricParams', { podName: get(this, 'resourceId') });
+ },
+});
\ No newline at end of file
diff --git a/app/components/pod-metrics/template.hbs b/app/components/pod-metrics/template.hbs
new file mode 100644
index 000000000..36099f6a6
--- /dev/null
+++ b/app/components/pod-metrics/template.hbs
@@ -0,0 +1,7 @@
+
+ {{metrics-action
+ queryAction="query"
+ state=state
+ }}
+ {{metrics-graph graphs=graphs loading=state.loading noGraphs=state.noGraphs}}
+
\ No newline at end of file
diff --git a/app/components/pod-row/template.hbs b/app/components/pod-row/template.hbs
index b4d3932cd..283bb74e7 100644
--- a/app/components/pod-row/template.hbs
+++ b/app/components/pod-row/template.hbs
@@ -16,7 +16,7 @@
{{badge-state model=model}}
- {{model.displayName}}
+ {{model.displayName}}
{{#if model.showTransitioningMessage}}
{{uc-first model.transitioningMessage}}
{{else if model.displayEndpoints}}
@@ -32,7 +32,7 @@
{{#copy-inline clipboardText=model.displayIp}}{{format-ip model.displayIp}}{{/copy-inline}} /
{{/if}}
{{#if (and showNode model.node)}}
- {{model.node.displayName}} /
+ {{model.node.displayName}} /
{{/if}}
{{t 'generic.createdDate' date=(date-from-now model.created) htmlSafe=true}} /
{{t 'generic.restarts'}} {{model.restarts}}
diff --git a/app/components/progress-bar-multi/component.js b/app/components/progress-bar-multi/component.js
index beeea5165..e248f4dfa 100644
--- a/app/components/progress-bar-multi/component.js
+++ b/app/components/progress-bar-multi/component.js
@@ -76,7 +76,7 @@ export default Component.extend({
obj.css = (`width: ${ obj.percent }%`).htmlSafe();
});
- return out;
+ return out.filter((obj) => obj.percent);
}));
valueDep = `tooltipValues.@each.{${ labelKey },${ valueKey }}`;
diff --git a/app/components/progress-bar-multi/template.hbs b/app/components/progress-bar-multi/template.hbs
index c90df43ec..3e9ff0688 100644
--- a/app/components/progress-bar-multi/template.hbs
+++ b/app/components/progress-bar-multi/template.hbs
@@ -9,9 +9,7 @@
}}
{{~#each pieces as |obj|~}}
- {{#if obj.percent}}
-
- {{/if}}
+
{{~/each~}}
{{/tooltip-element}}
diff --git a/app/components/progress-bar/component.js b/app/components/progress-bar/component.js
deleted file mode 100644
index 5f7b0efe9..000000000
--- a/app/components/progress-bar/component.js
+++ /dev/null
@@ -1,49 +0,0 @@
-import Component from '@ember/component';
-import layout from './template';
-
-export default Component.extend({
- layout,
- tagName: 'div',
- classNames: ['progress'],
-
- color: '',
- min: 0,
- value: 0,
- max: 100,
- zIndex: null,
-
- didInsertElement() {
- this.percentDidChange();
- this.zIndexDidChange();
- },
- percent: function() {
- var min = this.get('min');
- var max = this.get('max');
- var value = Math.max(min, Math.min(max, this.get('value')));
-
- var per = value / (max - min) * 100; // Percent 0-100
-
- per = Math.round(per * 100) / 100; // Round to 2 decimal places
-
- return per;
- }.property('min', 'max', 'value'),
-
- colorClass: function() {
- var color = this.get('color');
-
- if ( !color ) {
- return;
- }
-
- return `progress-bar-${ color.replace(/^progress-bar-/, '') }`;
- }.property('color'),
-
- percentDidChange: function() {
- this.$('.progress-bar').css('width', `${ this.get('percent') }%`);
- }.observes('percent'),
-
- zIndexDidChange: function() {
- this.$().css('zIndex', this.get('zIndex') || 'inherit');
- }.observes('zIndex'),
-
-});
diff --git a/app/components/progress-bar/template.hbs b/app/components/progress-bar/template.hbs
deleted file mode 100644
index 9ec88ff88..000000000
--- a/app/components/progress-bar/template.hbs
+++ /dev/null
@@ -1,2 +0,0 @@
-
-{{textLabel}}
diff --git a/app/components/resource-event-list/template.hbs b/app/components/resource-event-list/template.hbs
index 0c8149276..187d15bf7 100644
--- a/app/components/resource-event-list/template.hbs
+++ b/app/components/resource-event-list/template.hbs
@@ -48,7 +48,7 @@
{{/component}}
{{else}}
-
+
{{/if}}
{{/accordion-list-item}}
diff --git a/app/components/spark-line/component.js b/app/components/spark-line/component.js
deleted file mode 100644
index 7e92a49cc..000000000
--- a/app/components/spark-line/component.js
+++ /dev/null
@@ -1,213 +0,0 @@
-import { htmlSafe } from '@ember/string';
-import { inject as service } from '@ember/service';
-import Component from '@ember/component';
-import { GRADIENT_COLORS } from 'shared/components/svg-gradients/component';
-import { formatPercent, formatMib, formatKbps }
- from 'ui/utils/util';
-import {
- select,
- scale,
- min as d3Min,
- max as d3Max,
-} from 'd3';
-import layout from './template';
-
-const FORMATTERS = {
- value: (value) => value,
- percent: formatPercent,
- mib: formatMib,
- kbps: formatKbps
-};
-
-export default Component.extend({
- intl: service(),
- layout,
- tagName: 'svg',
- classNames: ['spark-line'],
- attributeBindings: ['cssSize:style'],
-
- data: null,
- width: null,
- height: 20,
- margin: 2,
-
- min: 0,
-
- minMax: null, // lower bound on how small automatic max can be
- max: null, // set an explicit max
- maxDoubleInital: false, // if true, set max to double the initial non-zero data point
- scaleDown: false, // if true, max is allowed to go back down. If false it can only go up.
-
- gradient: null,
- colorIdx: 0,
- interpolation: 'basis', // 'step-after',
- formatter: 'value',
-
- svg: null,
- line: null,
- dot: null,
- text: null,
- textBg: null,
- x: null,
- y: null,
- observedMax: null, // The largest max seen so far
-
- hasData: function() {
- if (this.get('data.length') > 0 && !this.get('svg')) {
- this.create();
- }
- }.observes('data.length'),
-
- cssSize: function() {
- let margin = parseInt(this.get('margin', 10));
- let width = (parseInt(this.get('width'), 10) + 2 * margin);
- let height = (parseInt(this.get('height'), 10) + 2 * margin);
-
- return new htmlSafe(`width: ${ width }px; height: ${ height }px`);
- }.property('width', 'height'),
-
- lastValue: function() {
- var data = this.get('data');
-
- if (data && data.get('length')) {
- return data.objectAt(data.get('length') - 1);
- }
- }.property('data.[]'),
-
- updateLine: function() {
- var line = this.get('line');
- var interp = this.get('interpolation');
-
- if (line) {
- line.interpolate(interp);
- }
- }.observes('interpolation'),
-
- update: function() {
- var svg = this.get('svg');
- var data = (this.get('data') || []).slice();
- var x = this.get('x');
- var y = this.get('y');
- var line = this.get('line');
- var text = this.get('text');
- var textBg = this.get('textBg');
- var width = this.get('width');
- var height = this.get('height');
- var margin = this.get('margin');
-
- if (svg && data && x && y && line) {
- x.domain([0, data.get('length') - 1]);
- x.range([0, width - margin]);
-
- var min = this.get('min') === null ? d3Min(data) : this.get('min');
- var max = this.adjustMax(d3Max(data));
-
- y.domain([min, max]);
- y.range([height - margin, margin]);
- y.rangeRound([height - margin, margin]);
-
- // console.log('update', data[data.length-2], data[data.length-1], x.domain(), x.range(), y.domain(), y.range());
- svg.selectAll('path')
- .data([data])
- .attr('d', line);
-
- this.get('dot')
- .attr('cx', x(data.length - 1) || 0 )
- .attr('cy', y(data[data.length - 1]) || 0);
-
- var str = FORMATTERS[this.get('formatter')](this.get('lastValue'));
-
- text.text(str);
- textBg.text(str);
-
- text
- .attr('x', width / 2)
- .attr('y', height)
-
- textBg
- .attr('x', width / 2)
- .attr('y', height);
- }
- }.observes('data', 'data.[]'),
- create() {
- let margin = this.get('margin');
- var svg = select(this.$()[0])
- .attr('transform', `translate(${ margin },${ margin })`);
-
- this.set('svg', svg);
- this.set('x', scale.linear());
- this.set('y', scale.linear());
-
- var line = svg.line()
- .defined((d) => (typeof d === 'number'))
- .x((d, i) => this.get('x')(i))
- .y((d) => this.get('y')(d));
-
- this.set('line', line);
-
- this.updateLine();
-
- let path = svg.append('path')
- .attr('class', `spark-path`)
- .attr('d', line(this.get('data')));
-
- if ( this.get('gradient') ) {
- path.style('stroke', GRADIENT_COLORS[this.get('gradient')][this.get('colorIdx')])
- }
-
- var dot = svg.append('circle')
- .attr('class', 'spark-dot')
- .attr('cx', 0)
- .attr('cy', 0)
- .attr('r', 2);
-
- this.set('dot', dot);
-
- var textBg = svg.append('text')
- .attr('class', `spark-text-bg`)
- .attr('alignment-baseline', 'middle')
- .attr('text-anchor', 'middle')
- .attr('x', 0)
- .attr('y', 0);
-
- this.set('textBg', textBg);
-
- var text = svg.append('text')
- .attr('class', `spark-text`)
- .attr('class', `spark-text`)
- .attr('alignment-baseline', 'middle')
- .attr('text-anchor', 'middle')
- .attr('x', 0)
- .attr('y', 0);
-
- this.set('text', text);
- },
-
- adjustMax(dataMax) {
- let optMinMax = this.get('minMax');
- let optMax = this.get('max');
- let optScaleDown = this.get('scaleDown');
- let observedMax = this.get('observedMax');
-
- let out = dataMax;
-
- if ( optMax ) {
- out = optMax;
- } else if ( optMinMax ) {
- out = Math.max(optMinMax, out);
- }
-
- if ( observedMax && !optScaleDown ) {
- out = Math.max(observedMax, out);
- }
-
- if ( !observedMax && out > 0 && this.get('maxDoubleInital') ) {
- out *= 2;
- }
-
- this.set('observedMax', out);
-
- return out;
- },
-
-});
diff --git a/app/components/spark-line/template.hbs b/app/components/spark-line/template.hbs
deleted file mode 100644
index fb5c4b157..000000000
--- a/app/components/spark-line/template.hbs
+++ /dev/null
@@ -1 +0,0 @@
-{{yield}}
\ No newline at end of file
diff --git a/app/components/svg-gradients/component.js b/app/components/svg-gradients/component.js
deleted file mode 100644
index 06dfe34b2..000000000
--- a/app/components/svg-gradients/component.js
+++ /dev/null
@@ -1,50 +0,0 @@
-import Component from '@ember/component';
-import { select } from 'd3';
-import layout from './template';
-
-export const GRADIENT_COLORS = {
- 'cpu': ['#2ECC71', '#DBE8B1'],
- 'memory': ['#00558B', '#AED6F1'],
- 'network': ['#E49701', '#F1C40F'],
- 'storage': ['#3A6F81', '#ABCED3'],
-};
-
-export default Component.extend({
- layout,
- tagName: '',
- didInsertElement() {
- var svg = select('body').append('svg:svg')
- .attr('id', 'svg-gradients')
- .attr('height', '0')
- .attr('height', '0')
- .attr('width', '0')
- .style('position', 'absolute');
-
- var defs = svg.append('svg:defs');
-
- Object.keys(GRADIENT_COLORS).forEach((name) => {
- GRADIENT_COLORS[name].forEach((val, idx) => {
- var gradient = defs.append('svg:linearGradient')
- .attr('id', `${ name }-${ idx }-gradient`)
- .attr('x1', '0%')
- .attr('y1', '0%')
- .attr('x2', '0%')
- .attr('y2', '100%')
- .attr('spreadMethod', 'pad');
-
- gradient.append('svg:stop')
- .attr('offset', '0%')
- .attr('stop-color', val)
- .attr('stop-opacity', '0.5');
- gradient.append('svg:stop')
- .attr('offset', '10%')
- .attr('stop-color', val)
- .attr('stop-opacity', '0.25');
- gradient.append('svg:stop')
- .attr('offset', '100%')
- .attr('stop-color', val)
- .attr('stop-opacity', '0.1');
- });
- });
- },
-});
diff --git a/app/components/svg-gradients/template.hbs b/app/components/svg-gradients/template.hbs
deleted file mode 100644
index fb5c4b157..000000000
--- a/app/components/svg-gradients/template.hbs
+++ /dev/null
@@ -1 +0,0 @@
-{{yield}}
\ No newline at end of file
diff --git a/app/components/workload-metrics/component.js b/app/components/workload-metrics/component.js
new file mode 100644
index 000000000..42e7eebb7
--- /dev/null
+++ b/app/components/workload-metrics/component.js
@@ -0,0 +1,18 @@
+import Component from '@ember/component';
+import Metrics from 'shared/mixins/metrics';
+import layout from './template';
+import { get, set } from '@ember/object';
+
+export default Component.extend(Metrics, {
+ layout,
+
+ filters: { resourceType: 'workload' },
+
+ projectScope: true,
+
+ init() {
+ this._super(...arguments);
+ set(this, 'metricParams', { workloadName: get(this, 'resourceId') });
+ },
+
+});
\ No newline at end of file
diff --git a/app/components/workload-metrics/template.hbs b/app/components/workload-metrics/template.hbs
new file mode 100644
index 000000000..36099f6a6
--- /dev/null
+++ b/app/components/workload-metrics/template.hbs
@@ -0,0 +1,7 @@
+
+ {{metrics-action
+ queryAction="query"
+ state=state
+ }}
+ {{metrics-graph graphs=graphs loading=state.loading noGraphs=state.noGraphs}}
+
\ No newline at end of file
diff --git a/app/container/controller.js b/app/container/controller.js
index 0c2f413ae..22dfe7c02 100644
--- a/app/container/controller.js
+++ b/app/container/controller.js
@@ -1,26 +1,18 @@
import { inject as service } from '@ember/service';
import Controller from '@ember/controller';
-import { get, set, observer, computed } from '@ember/object';
-import { once } from '@ember/runloop';
+import { get, computed, observer } from '@ember/object';
+import { alias } from '@ember/object/computed';
+import C from 'ui/utils/constants';
export default Controller.extend({
+ scope: service(),
router: service(),
- selectedContainer: null,
+ monitoringEnabled: alias('scope.currentCluster.isMonitoringReady'),
- actions: {
- select(container) {
- set(this, 'selectedContainer', container);
- }
- },
-
- containerDidChange: observer('model.containers.[]', function() {
- once(() => set(this, 'selectedContainer', get(this, 'model.containers.firstObject')));
- }),
-
- podStateDidChange: observer('model.state', function() {
- if ( get(this, 'model.state') === 'removed' && get(this, 'router.currentRouteName') === 'container' ) {
- const workloadId = get(this, 'model.workloadId');
+ podStateDidChange: observer('model.pod.state', function() {
+ if ( C.REMOVEDISH_STATES.includes(get(this, 'model.pod.state')) && get(this, 'router.currentRouteName') === 'container' ) {
+ const workloadId = get(this, 'model.pod.workloadId');
if ( workloadId ) {
this.transitionToRoute('workload', workloadId);
@@ -29,9 +21,10 @@ export default Controller.extend({
}
}
}),
- displayEnvironmentVars: computed('selectedContainer', function() {
+
+ displayEnvironmentVars: computed('model.environment', function() {
var envs = [];
- var environment = this.get('selectedContainer.environment') || {};
+ var environment = get(this, 'model.environment') || {};
Object.keys(environment).forEach((key) => {
envs.pushObject({
diff --git a/app/container/route.js b/app/container/route.js
index 2ecb6fc95..3e10468d4 100644
--- a/app/container/route.js
+++ b/app/container/route.js
@@ -1,5 +1,6 @@
import { get } from '@ember/object';
import Route from '@ember/routing/route';
+import { hash } from 'rsvp';
export default Route.extend({
beforeModel() {
@@ -14,12 +15,16 @@ export default Route.extend({
}
},
model(params) {
- const pod = get(this, 'store').find('pod', params.container_id);
+ const pod = get(this, 'store').find('pod', params.pod_id);
- if ( !pod ) {
- this.replaceWith('authenticated.project.index');
- }
+ return hash({ pod }).then((hash) => {
+ const container = get(hash, 'pod.containers').findBy('name', params.container_name);
- return pod;
+ if ( !container ) {
+ this.replaceWith('authenticated.project.index');
+ }
+
+ return container;
+ });
},
});
diff --git a/app/container/template.hbs b/app/container/template.hbs
index 039606fc6..de9968918 100644
--- a/app/container/template.hbs
+++ b/app/container/template.hbs
@@ -1,7 +1,7 @@
+
{{#if model.description}}
{{banner-message color='bg-secondary mb-0 mt-10' message=(linkify model.description)}}
{{/if}}
@@ -17,230 +18,144 @@
{{uc-first model.transitioningMessage}}
{{/if}}
-
-
- {{#if (eq model.containers.length 1)}}
-
- {{t 'podPage.image'}}:
- {{selectedContainer.image}} {{copy-to-clipboard clipboardText=container.image size="small"}}
-
-
+
+
+
{{t 'servicePage.multistat.namespace'}}:
+ {{#if model.pod.namespaceId}}
+ {{#copy-inline clipboardText=model.pod.namespaceId}}
+ {{model.pod.namespaceId}}
+ {{/copy-inline}}
+ {{else}}
+ {{t 'generic.none'}}
{{/if}}
-
- {{t 'servicePage.multistat.namespace'}}
- {{#if model.namespaceId}}
- {{#copy-inline clipboardText=model.namespaceId}}
- {{model.namespaceId}}
- {{/copy-inline}}
- {{else}}
- {{t 'generic.none'}}
- {{/if}}
-
-
- {{t 'dnsPage.type.workload'}}:
- {{#if model.workload}}
- {{#link-to "workload" model.workloadId}}{{model.workloadId}}{{/link-to}}
- {{else if model.workloadId}}
- {{model.workloadId}}
- {{else}}
- {{t 'generic.none'}}
- {{/if}}
-
-
-
- {{t 'podPage.podIp'}}:
- {{#if model.displayIp}}
- {{#copy-inline clipboardText=model.displayIp}}
- {{model.displayIp}}
- {{/copy-inline}}
- {{else}}
- {{t 'generic.none'}}
- {{/if}}
-
-
-
{{t 'podPage.nodeIp'}}:
- {{#if (and model.node.id model.node.clusterId)}}
-
-
{{model.node.displayName}}
- {{#if (or model.node.externalIpAddress model.node.ipAddress)}}
- {{node-ip model=model.node}}
- {{/if}}
-
- {{else}}
- {{t 'generic.unknown'}}
- {{/if}}
-
-
- {{t 'generic.created'}}:
- {{date-calendar model.created}} ({{t 'generic.restarts'}} {{model.restarts}})
-
+
+ {{t 'podPage.image'}}:
+ {{model.image}} {{copy-to-clipboard clipboardText=model.image size="small"}}
-
-
-
- {{#accordion-list as |al expandFn|}}
- {{#if model.workload}}
- {{container/form-scheduling
- initialHostId=model.workload.nodeId
- scheduling=model.workload.scheduling
- editing=false
- expandAll=al.expandAll
- expandFn=expandFn
- classNames="accordion"
- }}
+
+ {{t 'containerPage.pod'}}: {{#if model.pod}}
+ {{#link-to "pod" model.podId}}{{model.podId}}{{/link-to}}
+ {{else if model.podId}}
+ {{model.podId}}
+ {{else}}
+ {{t 'generic.none'}}
{{/if}}
+
+
- {{container/form-networking
- classNames="accordion-wrapper"
- service=model
- editing=false
- expandAll=al.expandAll
- expandFn=expandFn
- }}
-
- {{form-labels-annotations
- classNames="accordion-wrapper"
- model=model
- editing=false
- expandAll=al.expandAll
- expandFn=expandFn
- }}
-
- {{resource-condition-list
- resourceType=(t 'generic.pod')
- conditions=model.status.conditions
- expandAll=al.expandAll
- expandFn=expandFn
- }}
-
- {{resource-event-list
- resourceType=(t 'generic.pod')
- expandAll=al.expandAll
- expandFn=expandFn
- namespaceId=model.namespaceId
- name=model.name
- kind="Pod"
- }}
- {{/accordion-list}}
-
-
-
-
-{{#each model.containers as |container|}}
-
- {{#if container.showTransitioningMessage}}
- {{uc-first container.transitioningMessage}}
+
+
+ {{t 'containerPage.initContainer.label'}}:
+ {{#if model.initContainer}}
+ {{t 'generic.yes'}}
+ {{else}}
+ {{t 'generic.no'}}
{{/if}}
+
+
+ {{t 'generic.restarts'}}:
+ {{model.restarts}}
+
+
+ {{t 'generic.created'}}:
+ {{date-calendar model.pod.created}}
+
+
-