mirror of https://github.com/rancher/ui.git
Containers back to an array
This commit is contained in:
parent
4fce6b95d6
commit
df1cf5f08e
|
|
@ -1,5 +1,6 @@
|
|||
import EmberObject from '@ember/object';
|
||||
import { inject as service } from '@ember/service';
|
||||
import { get } from '@ember/object';
|
||||
import Route from '@ember/routing/route';
|
||||
import Ember from 'ember';
|
||||
import C from 'ui/utils/constants';
|
||||
|
|
@ -55,7 +56,7 @@ export default Route.extend({
|
|||
}
|
||||
|
||||
const clone = _workload.clone();
|
||||
const containerNames = Object.keys(service.containers);
|
||||
const containerNames = service.containers.map(x => get(x, name));
|
||||
let containerName = params.containerName;
|
||||
|
||||
// Add a sidekick
|
||||
|
|
@ -90,10 +91,10 @@ export default Route.extend({
|
|||
let container;
|
||||
if ( containerName === "" ) {
|
||||
// The primary/only container
|
||||
container = service.containers[containerNames[0]];
|
||||
container = service.containers[0];
|
||||
} else {
|
||||
// Existing container
|
||||
container = service.containers[containerName];
|
||||
container = service.containers.findBy('name', containerName);
|
||||
}
|
||||
|
||||
if ( params.upgrade ) {
|
||||
|
|
@ -145,7 +146,7 @@ export default Route.extend({
|
|||
namespaceId: namespaceId,
|
||||
scale: 1,
|
||||
restart: 'Always',
|
||||
containers: {},
|
||||
containers: [],
|
||||
});
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { later, cancel } from '@ember/runloop';
|
||||
import { computed, get } from '@ember/object';
|
||||
import { alias } from '@ember/object/computed';
|
||||
import { alias, gt } from '@ember/object/computed';
|
||||
|
||||
import Resource from 'ember-api-store/models/resource';
|
||||
import C from 'ui/utils/constants';
|
||||
import { sortableNumericSuffix } from 'shared/utils/util';
|
||||
|
|
@ -365,9 +366,7 @@ var Workload = Resource.extend(DisplayImage, StateCounts, EndpointPorts, {
|
|||
return this.get('intl').t('servicePage.type.'+ type);
|
||||
}.property('lcType','isSelector','intl.locale'),
|
||||
|
||||
hasSidekicks: function() {
|
||||
return Object.keys(get(this,'containers')).length > 1;
|
||||
}.property('containers'),
|
||||
hasSidekicks: gt('containers.length', 1),
|
||||
|
||||
activeIcon: function() {
|
||||
return activeIcon(this);
|
||||
|
|
|
|||
|
|
@ -14,11 +14,11 @@ export default Route.extend({
|
|||
setupController(controller, model) {
|
||||
this._super(...arguments);
|
||||
|
||||
let containers = model.get('workload.containers');
|
||||
let keys = Object.keys(containers);
|
||||
let lc = model.get('workload.containers.firstObject');
|
||||
|
||||
controller.setProperties({
|
||||
fixedLaunchConfig: containers[keys[0]],
|
||||
activeLaunchConfig: containers[keys[0]],
|
||||
fixedLaunchConfig: lc,
|
||||
activeLaunchConfig: lc,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ export default Component.extend({
|
|||
type: 'googleKubernetesEngineConfig',
|
||||
diskSizeGb: 100,
|
||||
enableAlphaFeature: false,
|
||||
masterVersion: '1.8.4-gke.0',
|
||||
masterVersion: '1.8.4-gke.1',
|
||||
nodeCount: 3,
|
||||
machineType: 'n1-standard-1',
|
||||
zone: 'us-central1-f',
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
export const versions = {
|
||||
"defaultClusterVersion": "1.7.8-gke.0",
|
||||
"validNodeVersions": [
|
||||
"1.8.4-gke.0",
|
||||
"1.8.4-gke.1",
|
||||
"1.8.3-gke.0",
|
||||
"1.8.2-gke.0",
|
||||
"1.8.1-gke.1",
|
||||
|
|
@ -25,7 +25,7 @@ export const versions = {
|
|||
"UBUNTU"
|
||||
],
|
||||
"validMasterVersions": [
|
||||
"1.8.4-gke.0",
|
||||
"1.8.4-gke.1",
|
||||
"1.8.3-gke.0",
|
||||
"1.8.2-gke.0",
|
||||
"1.8.1-gke.1",
|
||||
|
|
|
|||
|
|
@ -46,7 +46,8 @@ export default Component.extend(NewOrEdit, {
|
|||
imageErrors: null,
|
||||
portErrors: null,
|
||||
namespaceErrors: null,
|
||||
metadataErrors: null,
|
||||
labelErrors: null,
|
||||
annotationErrors: null,
|
||||
|
||||
actions: {
|
||||
setImage(uuid) {
|
||||
|
|
@ -206,7 +207,8 @@ export default Component.extend(NewOrEdit, {
|
|||
errors.pushObjects(this.get('imageErrors')||[]);
|
||||
errors.pushObjects(this.get('portErrors')||[]);
|
||||
errors.pushObjects(this.get('namespaceErrors')||[]);
|
||||
errors.pushObjects(this.get('metadataErrors')||[]);
|
||||
errors.pushObjects(this.get('labelErrors')||[]);
|
||||
errors.pushObjects(this.get('annotationErrors')||[]);
|
||||
|
||||
errors = errors.uniq();
|
||||
|
||||
|
|
@ -287,10 +289,16 @@ export default Component.extend(NewOrEdit, {
|
|||
nameResource = pr;
|
||||
}
|
||||
|
||||
pr.containers[this.get('name')] = this.get('launchConfig').clone();
|
||||
const existing = pr.containers.findBy('name', name);
|
||||
if ( existing ) {
|
||||
pr.removeObject(existing);
|
||||
}
|
||||
|
||||
set(lc, 'name', name);
|
||||
pr.containers.push(lc);
|
||||
|
||||
nameResource.setProperties({
|
||||
name: this.get('name'),
|
||||
name: name,
|
||||
description: this.get('description'),
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -183,16 +183,17 @@
|
|||
|
||||
{{form-user-labels
|
||||
classNames="accordion-wrapper"
|
||||
errors=labelErrors
|
||||
initialLabels=launchConfig.labels
|
||||
setLabels=(action 'setLabels' 'user')
|
||||
expandAll=al.expandAll
|
||||
expandFn=expandFn
|
||||
}}
|
||||
|
||||
{{form-metadata
|
||||
{{form-annotations
|
||||
classNames="accordion-wrapper"
|
||||
instance=launchConfig
|
||||
errors=metadataErrors
|
||||
errors=annotationErrors
|
||||
expandAll=al.expandAll
|
||||
expandFn=expandFn
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ export default Component.extend({
|
|||
intl: service(),
|
||||
|
||||
instance: null,
|
||||
detailKey: 'formMetadata.detail',
|
||||
detailKey: 'formAnnotations.detail',
|
||||
errors: null,
|
||||
valid: true,
|
||||
|
||||
|
|
@ -30,22 +30,22 @@ export default Component.extend({
|
|||
validate: function () {
|
||||
let intl = this.get('intl');
|
||||
if ( this.get('valid') ) {
|
||||
if ( ['object', 'null'].indexOf(typeOf(this.get('instance.metadata'))) === -1 ) {
|
||||
this.set('errors', [intl.t('formMetadata.errors.topLevelValueInvalid')]);
|
||||
if ( ['object', 'null'].indexOf(typeOf(this.get('instance.annotations'))) === -1 ) {
|
||||
this.set('errors', [intl.t('formAnnotations.errors.topLevelValueInvalid')]);
|
||||
} else {
|
||||
this.set('errors', []);
|
||||
}
|
||||
} else {
|
||||
this.set('errors', [intl.t('formMetadata.errors.invalidJSON')]);
|
||||
this.set('errors', [intl.t('formAnnotations.errors.invalidJSON')]);
|
||||
}
|
||||
}.observes('valid', 'instance.metadata'),
|
||||
}.observes('valid', 'instance.annotations'),
|
||||
|
||||
statusClass: null,
|
||||
status: function () {
|
||||
let k;
|
||||
if (this.get('errors.length') ) {
|
||||
k = STATUS.ERROR;
|
||||
} else if (!isNone(this.get('instance.metadata')) && Object.keys(this.get('instance.metadata')).length > 0) {
|
||||
} else if (!isNone(this.get('instance.annotations')) && Object.keys(this.get('instance.annotations')).length > 0) {
|
||||
k = STATUS.CONFIGURED;
|
||||
} else {
|
||||
k = STATUS.NOTCONFIGURED;
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
{{#accordion-list-item
|
||||
title=(t 'formMetadata.title')
|
||||
title=(t 'formAnnotations.title')
|
||||
detail=(t detailKey appName=settings.appName)
|
||||
status=status
|
||||
statusClass=statusClass
|
||||
expandAll=expandAll
|
||||
expand=(action expandFn)
|
||||
}}
|
||||
{{json-editor json=instance.metadata isValid=valid}}
|
||||
{{json-editor json=instance.annotations isValid=valid}}
|
||||
{{/accordion-list-item}}
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
import { next } from '@ember/runloop';
|
||||
import { get, set } from '@ember/object';
|
||||
import { inject as service } from '@ember/service';
|
||||
import Component from '@ember/component';
|
||||
import ManageLabels from 'shared/mixins/manage-labels';
|
||||
|
|
@ -24,6 +25,13 @@ export default Component.extend(ManageLabels, {
|
|||
// Inputs
|
||||
initialLabels: null,
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
|
||||
this.initLabels(this.get('initialLabels'),'user', null, this.get('readonlyLabels'));
|
||||
this.labelsChanged();
|
||||
},
|
||||
|
||||
actions: {
|
||||
addUserLabel() {
|
||||
this._super();
|
||||
|
|
@ -45,16 +53,18 @@ export default Component.extend(ManageLabels, {
|
|||
}
|
||||
},
|
||||
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
|
||||
this.initLabels(this.get('initialLabels'),'user', null, this.get('readonlyLabels'));
|
||||
this.labelsChanged();
|
||||
},
|
||||
|
||||
updateLabels(labels) {
|
||||
this.sendAction('setLabels', labels);
|
||||
this.validate();
|
||||
},
|
||||
|
||||
validate() {
|
||||
let errors = [];
|
||||
|
||||
(this.get('labelArray')||[]).forEach((obj) => {
|
||||
});
|
||||
|
||||
set(this, 'errors', errors);
|
||||
},
|
||||
|
||||
statusClass: null,
|
||||
|
|
|
|||
|
|
@ -31,12 +31,12 @@ export default Component.extend({
|
|||
const out = [];
|
||||
get(this, 'pods').forEach((pod) => {
|
||||
const containers = get(pod, 'containers');
|
||||
Object.keys(containers).forEach((name) => {
|
||||
containers.forEach((container) => {
|
||||
out.push(EmberObject.create({
|
||||
pod: pod,
|
||||
name: name,
|
||||
name: get(container, 'name'),
|
||||
podId: get(pod, 'id'),
|
||||
container: containers[name],
|
||||
container: container,
|
||||
sortStr: get(pod,'name') + '_' + name,
|
||||
}));
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { inject as service } from '@ember/service';
|
||||
import { computed, get } from '@ember/object';
|
||||
import { alias } from '@ember/object/computed';
|
||||
import Component from '@ember/component';
|
||||
import C from 'ui/utils/constants';
|
||||
import layout from './template';
|
||||
|
|
@ -29,14 +30,12 @@ export default Component.extend({
|
|||
},
|
||||
|
||||
canExpand: computed('expandPlaceholder', 'model.containers', function() {
|
||||
return get(this,'expandPlaceholder') && Object.keys(get(this,'model.containers')).length > 1;
|
||||
return get(this,'expandPlaceholder') && get(this,'model.containers.length') > 1;
|
||||
}),
|
||||
|
||||
statsAvailable: computed('model.{state,healthState}', function() {
|
||||
return C.ACTIVEISH_STATES.indexOf(this.get('model.state')) >= 0 && this.get('model.healthState') !== 'started-once';
|
||||
}),
|
||||
|
||||
containers: computed('model.containers', function() {
|
||||
return Object.values(get(this,'model.containers'));
|
||||
}),
|
||||
containers: alias('model.containers'),
|
||||
});
|
||||
|
|
|
|||
|
|
@ -6,15 +6,15 @@ export default Mixin.create({
|
|||
intl: service(),
|
||||
|
||||
displayImage: computed('containers', function() {
|
||||
const containers = get(this, 'containers')||{};
|
||||
const names = Object.keys(containers);
|
||||
const containers = get(this, 'containers')||[];
|
||||
const count = get(containers, 'length');
|
||||
|
||||
if ( names.length > 1 ) {
|
||||
return get(this,'intl').t('pagination.image', {pages: 1, count: names.length});
|
||||
} else if ( names.length ) {
|
||||
return get(containers[names[0]], 'image');
|
||||
if ( count > 1 ) {
|
||||
return get(this,'intl').t('pagination.image', {pages: 1, count: count});
|
||||
} else if ( count ) {
|
||||
return get(containers, 'firstObject.image');
|
||||
} else {
|
||||
return 'Unknown';
|
||||
return get(this, 'intl').t('generic.unknown');
|
||||
}
|
||||
}),
|
||||
});
|
||||
|
|
|
|||
|
|
@ -0,0 +1,78 @@
|
|||
import { validateChars, validateHostname } from 'ember-api-store/utils/validate';
|
||||
|
||||
export function parseKey(str) {
|
||||
str = str||'';
|
||||
|
||||
const idx = str.indexOf('/');
|
||||
if ( idx > 0 ) {
|
||||
const prefix = str.substr(0,idx);
|
||||
const key = str.substr(idx+1);
|
||||
return {
|
||||
str,
|
||||
prefix,
|
||||
key
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
str,
|
||||
prefix: null,
|
||||
key: str,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const MIDDLE_ONLY = ['_','.','-'];
|
||||
export function validateIdentifier(str, displayKey, intl, errors=[]) {
|
||||
validateChars(str, {validChars: 'A-Za-z0-9_.-'}, displayKey, intl, errors);
|
||||
|
||||
// Indentifier cannot begin with a hyphen
|
||||
let chr = str.slice(0,1);
|
||||
if ( MIDDLE_ONLY.includes(chr) ) {
|
||||
errors.push(intl.t(`validation.k8s.identifier.startLetter`, {key: displayKey}));
|
||||
}
|
||||
|
||||
// Label cannot end with a hyphen
|
||||
chr = str.slice(-1);
|
||||
if ( MIDDLE_ONLY.includes(chr) ) {
|
||||
errors.push(intl.t(`validation.k8s.identifier.endLetter`, {key: displayKey}));
|
||||
}
|
||||
|
||||
// Label must be 1-63 characters
|
||||
const min = 1;
|
||||
const max = 63;
|
||||
if ( str.length < min ) {
|
||||
errors.push(intl.t(`validation.k8s.identifier.emptyKey`, {key: displayKey, min: min}));
|
||||
} else if ( str.length > max ) {
|
||||
errors.push(intl.t(`validation.k8s.identifier}.tooLongKey`, {key: displayKey, max: max}));
|
||||
}
|
||||
}
|
||||
|
||||
export function validatePrefix(str, displayKey, intl, errors=[]) {
|
||||
const intlKey = intl.t('generic.key');
|
||||
const min = 1;
|
||||
const max = 253;
|
||||
|
||||
if ( str.length < min ) {
|
||||
errors.push(intl.t(`validation.k8s.identifier.emptyPrefix`, {key: displayKey, min: min}));
|
||||
} else if ( str.length > max ) {
|
||||
errors.push(intl.t(`validation.k8s.identifier}.tooLongPRefix`, {key: displayKey, max: max}));
|
||||
} else {
|
||||
validateHostname(str, intlKey, intl, errors);
|
||||
}
|
||||
}
|
||||
|
||||
export function validateKey(str, intl, errors=[]) {
|
||||
const parts = parseKey(str);
|
||||
const intlKey = intl.t('generic.key');
|
||||
|
||||
if ( parts.prefix ) {
|
||||
validatePrefix(parts.prefix, intlKey, intl, errors);
|
||||
}
|
||||
|
||||
validateIdentifier(parts.key, intlKey, intl, errors);
|
||||
}
|
||||
|
||||
export function validateValue(str, intl, errors=[]) {
|
||||
const intlKey = intl.t('generic.value');
|
||||
validateIdentifier(str, intlKey, intl, errors);
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
export { default } from 'shared/components/form-annotations/component';
|
||||
|
|
@ -1 +0,0 @@
|
|||
export { default } from 'shared/components/form-metadata/component';
|
||||
|
|
@ -42,6 +42,7 @@ generic:
|
|||
image: Image
|
||||
internal: Internal
|
||||
ipAddress: IP Address
|
||||
key: Key
|
||||
limit: Limit
|
||||
limits: Limits
|
||||
loading: "Loading..."
|
||||
|
|
@ -78,6 +79,7 @@ generic:
|
|||
unknown: Unknown
|
||||
upload: Upload
|
||||
uuid: UUID
|
||||
value: Value
|
||||
yes: "Yes"
|
||||
|
||||
realmNames:
|
||||
|
|
@ -2415,12 +2417,12 @@ formUserLabels:
|
|||
placeholder: e.g. bar
|
||||
protip: "ProTip: Paste one or more lines of key=value pairs into any key field for easy bulk entry."
|
||||
|
||||
formMetadata:
|
||||
title: Metadata
|
||||
detail: Configure the metadata for the container.
|
||||
formAnnotations:
|
||||
title: Annotations
|
||||
detail: Configure annotations (key/value metadata) for the container.
|
||||
errors:
|
||||
invalidJSON: Metadata JSON format is invalid.
|
||||
topLevelValueInvalid: Metadata JSON top-level value should be an object.
|
||||
invalidJSON: Annotation JSON format is invalid.
|
||||
topLevelValueInvalid: Annotation JSON top-level value must be an object.
|
||||
|
||||
formUpgrade:
|
||||
title: Upgrade Policy
|
||||
|
|
@ -4106,15 +4108,23 @@ validation:
|
|||
startDot: '"{key}" cannot start with a dot'
|
||||
empty: '"{key}" must be at least one character'
|
||||
tooLong: '"{key}" cannot be longer than {max} characters'
|
||||
startHyphen: '"{key}" cannot have a section starting with a hyphen'
|
||||
endHyphen: '"{key}" cannot have a section ending with a hyphen'
|
||||
startHyphen: '"{key}" must start with a letter or number'
|
||||
endHyphen: '"{key}" must end with a letter or number'
|
||||
emptyLabel: '"{key}" cannot have two consecutive dots'
|
||||
labelTooLong: '"{key}" cannot have a section longer than {max} characters'
|
||||
tooLongLabel: '"{key}" cannot have a section longer than {max} characters'
|
||||
label:
|
||||
startHyphen: '"{key}" cannot start with a hyphen'
|
||||
endHyphen: '"{key}" cannot end with a hyphen'
|
||||
startHyphen: '"{key}" must start with a letter or number'
|
||||
endHyphen: '"{key}" must end with a letter or number'
|
||||
emptyLabel: '"{key}" cannot be empty'
|
||||
labelTooLong: '"{key}" cannot be more than {max} characters'
|
||||
tooLongLabel: '"{key}" cannot be more than {max} characters'
|
||||
k8s:
|
||||
identifier:
|
||||
startLetter: '"{key}" must start with a letter or number'
|
||||
endLetter: '"{key}" must end with a letter or number'
|
||||
emptyPrefix: '"{key}" cannot have an empty prefix'
|
||||
tooLongPrefix: '"{key}" cannot have a prefix longer than {max} characters'
|
||||
emptyLabel: '"{key}" cannot have an empty key'
|
||||
tooLongKey: '"{key}" cannot have a key longer than {max} characters'
|
||||
|
||||
##############################
|
||||
# Model Properties
|
||||
|
|
|
|||
Loading…
Reference in New Issue