diff --git a/lib/shared/addon/components/form-affinity-k8s/component.js b/lib/shared/addon/components/form-affinity-k8s/component.js
index 642c0e904..11e421737 100644
--- a/lib/shared/addon/components/form-affinity-k8s/component.js
+++ b/lib/shared/addon/components/form-affinity-k8s/component.js
@@ -154,12 +154,15 @@ export default Component.extend({
}
}),
- nodeAffinity: computed('value.nodeAffinity.{preferredDuringSchedulingIgnoredDuringExecution,requiredDuringSchedulingIgnoredDuringExecution}', {
+ nodeAffinity: computed('value.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution', 'value.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms', {
get(){
if (!this.value?.nodeAffinity){
set(this.value, 'nodeAffinity', {})
}
- this.initPreferredRequired(this.value.nodeAffinity)
+ this.initPreferredRequired(this.value.nodeAffinity, true)
+ if (!this.value.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms){
+ set(this.value, 'nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms', [])
+ }
return get(this.value, 'nodeAffinity')
},
@@ -170,11 +173,13 @@ export default Component.extend({
return term
}),
- requiredDuringSchedulingIgnoredDuringExecution: (val.requiredDuringSchedulingIgnoredDuringExecution || []).map((term) => {
- delete term._id;
+ requiredDuringSchedulingIgnoredDuringExecution: {
+ nodeSelectorTerms: (val?.requiredDuringSchedulingIgnoredDuringExecution?.nodeSelectorTerms || []).map((term) => {
+ delete term._id;
- return term
- })
+ return term
+ })
+ }
}
set(this.value, 'nodeAffinity', withoutId)
@@ -184,11 +189,13 @@ export default Component.extend({
}
}),
- initPreferredRequired: (val) => {
+ initPreferredRequired: (val, isNode) => {
if (!val.preferredDuringSchedulingIgnoredDuringExecution){
set(val, 'preferredDuringSchedulingIgnoredDuringExecution', [])
}
- if (!val.requiredDuringSchedulingIgnoredDuringExecution){
+ if (!val.requiredDuringSchedulingIgnoredDuringExecution && isNode){
+ set(val, 'requiredDuringSchedulingIgnoredDuringExecution', { nodeSelectorTerms: [] })
+ } else {
set(val, 'requiredDuringSchedulingIgnoredDuringExecution', [])
}
}
diff --git a/lib/shared/addon/components/form-affinity-k8s/template.hbs b/lib/shared/addon/components/form-affinity-k8s/template.hbs
index 537cde67f..4ac83c91a 100644
--- a/lib/shared/addon/components/form-affinity-k8s/template.hbs
+++ b/lib/shared/addon/components/form-affinity-k8s/template.hbs
@@ -2,7 +2,7 @@
@@ -11,6 +11,7 @@
@value={{podAffinity}}
@podAffinity={{podAffinity}}
@podAntiAffinity={{podAntiAffinity}}
+ {{!-- //TODO nb used? --}}
@update={{action "affinityChanged"}}
/>
diff --git a/lib/shared/addon/components/form-node-affinity-k8s/component.js b/lib/shared/addon/components/form-node-affinity-k8s/component.js
index 48f81b364..d8c014b2e 100644
--- a/lib/shared/addon/components/form-node-affinity-k8s/component.js
+++ b/lib/shared/addon/components/form-node-affinity-k8s/component.js
@@ -1,4 +1,137 @@
import Component from '@ember/component';
import layout from './template';
+import {
+ computed,
+ get,
+ set,
+ observer
+} from '@ember/object';
+import { randomStr } from '../../utils/util';
+import { TERM_PRIORITY } from '../form-pod-affinity-k8s/component';
+/**
+ * nodeAffinity: {
+ * preferredDuringSchedulingIgnoredDuringExecution:
+ * - {
+ * preference: nodeselectorterm,
+ * weight: int
+ * }
+ * requiredDuringSchedulingIgnoredDuringExecution:
+ * nodeSelectorTerms:
+ * - nodeselectorterm
+ * }
+ *
+ *
+ * nodeselectorterm: {
+ * matchexpressions:
+ * - {
+ * key: string,
+ * operator: string, one of: [In, NotIn, Exists, DoesNotExist Gt, Lt]
+ * value: string array ... If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer.
+ * }
+ * matchfields: same as match expressions but matches fields instead of labels
+ * }
+ */
-export default Component.extend({ layout })
\ No newline at end of file
+
+export default Component.extend({
+ layout,
+
+ TERM_PRIORITY,
+ nodeAffinity: null,
+ mode: 'new',
+ allTerms: [],
+
+ /**
+ * this component renders one list for required & preferred arrays of node selector terms
+ * each nodeaffinitytermk8s component can change between required and perferred
+ * the overall list shouldn't re-order when a term is moved to a different underlying array so rather than computing this off the arrays in spec
+ * this list will track which array a term should belong to and the arrays in spec will be computed off this
+ *
+ * list of all terms:
+ * - {
+ * priority: preferred/required
+ * term:preferred or required term
+ * }
+ *
+ */
+ init(){
+ // TODO nb why is required... an array navigating back from view as yaml?
+ this._super(...arguments);
+ const allTerms = []
+ const addTerms = function(terms = [], priority){
+ terms.forEach((term) => {
+ allTerms.push({
+ priority,
+ term
+ })
+ })
+ }
+
+ addTerms(this.nodeAffinity?.preferredDuringSchedulingIgnoredDuringExecution, TERM_PRIORITY.PREFERRED)
+ addTerms(this.nodeAffinity?.requiredDuringSchedulingIgnoredDuringExecution?.nodeSelectorTerms, TERM_PRIORITY.REQUIRED)
+ set(this, 'allTerms', allTerms)
+ },
+
+ actions: {
+ addTerm(){
+ const neu = {
+ priority: TERM_PRIORITY.REQUIRED,
+ term: { _id: randomStr() }
+ }
+
+ this.allTerms.push(neu)
+ get(this.nodeAffinity, 'requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms').addObject(neu.term)
+ this.notifyPropertyChange('allTerms')
+ this.notifyPropertyChange('nodeAffinity')
+ },
+
+ removeTerm(term){
+ // TODO nb does removeObject work here? Will it work in typeChanged?
+ get(this, 'allTerms').removeObject(term)
+
+ if (term.priority === TERM_PRIORITY.REQUIRED){
+ const removeFrom = get(this.nodeAffinity, 'requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms')
+
+ removeFrom.removeObject(term.term)
+ } else {
+ const removeFrom = get(this.nodeAffinity, 'preferredDuringSchedulingIgnoredDuringExecution')
+
+ removeFrom.removeObject(term.term)
+ }
+ this.notifyPropertyChange('nodeAffinity')
+ },
+
+
+ typeChanged(term, old){
+ // TODO nb add weight
+ if (old === TERM_PRIORITY.REQUIRED){
+ const removeFrom = get(this.nodeAffinity, 'requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms')
+ const addTo = get(this.nodeAffinity, 'preferredDuringSchedulingIgnoredDuringExecution')
+
+ set(this.nodeAffinity, 'requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms', this.removeFromSpec(term.term, removeFrom))
+
+ addTo.pushObject(term.term)
+ } else {
+ // TODO nb remove weight
+ const removeFrom = get(this.nodeAffinity, 'preferredDuringSchedulingIgnoredDuringExecution')
+ const addTo = get(this.nodeAffinity, 'requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms')
+
+ set(this.nodeAffinity, 'preferredDuringSchedulingIgnoredDuringExecution', this.removeFromSpec(term.term, removeFrom))
+ addTo.pushObject(term.term)
+ }
+ this.notifyPropertyChange('nodeAffinity')
+ },
+
+ },
+
+ editing: computed('mode', function() {
+ const mode = get(this, 'mode')
+
+ return mode === 'new' || mode === 'edit'
+ }),
+
+ removeFromSpec: (term, array) => {
+ return array.filter((each) => each._id !== term._id)
+ },
+
+})
\ No newline at end of file
diff --git a/lib/shared/addon/components/form-node-affinity-k8s/template.hbs b/lib/shared/addon/components/form-node-affinity-k8s/template.hbs
index b02b2a118..aeeb26037 100644
--- a/lib/shared/addon/components/form-node-affinity-k8s/template.hbs
+++ b/lib/shared/addon/components/form-node-affinity-k8s/template.hbs
@@ -1,3 +1,29 @@
-
- node affinity component
+
+
+
+
+
+
+
+ {{#each allTerms as |term|}}
+
+ {{/each}}
+
+ {{#if editing}}
+
+ {{/if}}
+
+
\ No newline at end of file
diff --git a/lib/shared/addon/components/form-node-selector-term-k8s/component.js b/lib/shared/addon/components/form-node-selector-term-k8s/component.js
index 48f81b364..5cffd6967 100644
--- a/lib/shared/addon/components/form-node-selector-term-k8s/component.js
+++ b/lib/shared/addon/components/form-node-selector-term-k8s/component.js
@@ -1,4 +1,21 @@
import Component from '@ember/component';
import layout from './template';
+import { priorityOptions } from '../form-pod-affinity-term-k8s/component';
-export default Component.extend({ layout })
\ No newline at end of file
+export default Component.extend({
+ layout,
+
+ value: null,
+ mode: 'new',
+
+ priorityOptions,
+
+ actions: {
+ removeTerm(){
+ if (this.remove){
+ this.remove()
+ }
+ }
+ },
+
+})
\ No newline at end of file
diff --git a/lib/shared/addon/components/form-node-selector-term-k8s/template.hbs b/lib/shared/addon/components/form-node-selector-term-k8s/template.hbs
index e69de29bb..9bd151df4 100644
--- a/lib/shared/addon/components/form-node-selector-term-k8s/template.hbs
+++ b/lib/shared/addon/components/form-node-selector-term-k8s/template.hbs
@@ -0,0 +1,42 @@
+
+ {{#if editing}}
+
+
+
+ {{/if }}
+
+
+ {{!-- --}}
+
+
+
+
+ {{#if (eq value.priority TERM_PRIORITY.PREFERRED)}}
+
+
+ {{#input-or-display
+ editable=editing
+ value=toplogyKey
+ }}
+ {{input
+ type="text"
+ class="form-control input-sm"
+ value=weight
+ placeholder=(t "clusterNew.agentConfig.overrideAffinity.podAffinity.weight.placeholder")
+ }}
+ {{/input-or-display}}
+
+ {{/if}}
+
+
\ No newline at end of file
diff --git a/lib/shared/addon/components/form-pod-affinity-k8s/component.js b/lib/shared/addon/components/form-pod-affinity-k8s/component.js
index f27544f72..279305af6 100644
--- a/lib/shared/addon/components/form-pod-affinity-k8s/component.js
+++ b/lib/shared/addon/components/form-pod-affinity-k8s/component.js
@@ -33,7 +33,6 @@ export default Component.extend({
podAntiAffinity: null,
value: null,
mode: 'new',
- anti: false,
allTerms: [],
/**
* this component renders one list for required & preferred arrays of terms in affinity & antiAffinity
@@ -70,13 +69,6 @@ export default Component.extend({
},
actions: {
- addRequired(){
- this.requiredDuringSchedulingIgnoredDuringExecution.pushObject({})
- },
- addPreferred(){
- this.preferredDuringSchedulingIgnoredDuringExecution.pushObject({})
- },
-
addTerm(){
const neu = {
priority: TERM_PRIORITY.REQUIRED,
@@ -92,6 +84,7 @@ export default Component.extend({
removeTerm(term){
// TODO nb update relevent spec array
+ // TODO nb does removeObject work here? Will it work in typeChanged and antiChanged?
get(this, 'allTerms').removeObject(term)
if (term.anti){
if (term.priority === TERM_PRIORITY.REQUIRED){
@@ -118,44 +111,48 @@ export default Component.extend({
}
},
- affinityChanged(){
- // TODO nb this.update()
- // needed?
- },
-
-
-
typeChanged(term, old){
if (term.anti){
+ // TODO nb add 'weight'
if (old === TERM_PRIORITY.REQUIRED){
const removeFrom = get(this.podAntiAffinity, 'requiredDuringSchedulingIgnoredDuringExecution')
const addTo = get(this.podAntiAffinity, 'preferredDuringSchedulingIgnoredDuringExecution')
set(this.podAntiAffinity, 'requiredDuringSchedulingIgnoredDuringExecution', this.removeFromSpec(term.term, removeFrom))
+ // preferred terms are an object with weight and podAffinityTerm fields; required terms are just the contents of podAffinityTerm
+ set(term, 'term', this.addWeight(term.term))
addTo.pushObject(term.term)
} else {
+ // TODO nb remove weight
const removeFrom = get(this.podAntiAffinity, 'preferredDuringSchedulingIgnoredDuringExecution')
const addTo = get(this.podAntiAffinity, 'requiredDuringSchedulingIgnoredDuringExecution')
set(this.podAntiAffinity, 'preferredDuringSchedulingIgnoredDuringExecution', this.removeFromSpec(term.term, removeFrom))
+ set(term, 'term', this.removeWeight(term))
+
addTo.pushObject(term.term)
}
this.notifyPropertyChange('podAntiAffinity')
} else {
+ // TODO nb add 'weight'
if (old === TERM_PRIORITY.REQUIRED){
const removeFrom = get(this.podAffinity, 'requiredDuringSchedulingIgnoredDuringExecution')
const addTo = get(this.podAffinity, 'preferredDuringSchedulingIgnoredDuringExecution')
set(this.podAffinity, 'requiredDuringSchedulingIgnoredDuringExecution', this.removeFromSpec(term.term, removeFrom))
+ set(term, 'term', this.addWeight(term.term))
addTo.pushObject(term.term)
} else {
+ // TODO nb remove weight
const removeFrom = get(this.podAffinity, 'preferredDuringSchedulingIgnoredDuringExecution')
const addTo = get(this.podAffinity, 'requiredDuringSchedulingIgnoredDuringExecution')
set(this.podAffinity, 'preferredDuringSchedulingIgnoredDuringExecution', this.removeFromSpec(term.term, removeFrom))
+ set(term, 'term', this.removeWeight(term))
+
addTo.pushObject(term.term)
}
this.notifyPropertyChange('podAffinity')
@@ -211,4 +208,25 @@ export default Component.extend({
return array.filter((each) => each._id !== term._id)
},
+ addWeight: (term) => {
+ const out = {
+ // weight: null,
+ podAffinityTerm: term,
+ _id: term._id
+ }
+
+ delete out.podAffinityTerm._id
+
+ return out
+ },
+
+ removeWeight: (term) => {
+ const out = {
+ _id: term._id,
+ ...term.podAffinityTerm
+ }
+
+ return out
+ }
+
})
\ No newline at end of file
diff --git a/lib/shared/addon/components/form-pod-affinity-k8s/template.hbs b/lib/shared/addon/components/form-pod-affinity-k8s/template.hbs
index ce0411b03..87fc1fd70 100644
--- a/lib/shared/addon/components/form-pod-affinity-k8s/template.hbs
+++ b/lib/shared/addon/components/form-pod-affinity-k8s/template.hbs
@@ -1,11 +1,7 @@
diff --git a/lib/shared/addon/components/form-pod-affinity-term-k8s/component.js b/lib/shared/addon/components/form-pod-affinity-term-k8s/component.js
index f3756fd1e..4f88bce49 100644
--- a/lib/shared/addon/components/form-pod-affinity-term-k8s/component.js
+++ b/lib/shared/addon/components/form-pod-affinity-term-k8s/component.js
@@ -42,11 +42,20 @@ const namespaceModes = {
IN_LIST: 'inList'
}
+export const priorityOptions = [{
+ value: TERM_PRIORITY.REQUIRED,
+ label: 'clusterNew.agentConfig.overrideAffinity.podAffinity.typeOptions.required'
+}, {
+ value: TERM_PRIORITY.PREFERRED,
+ label: 'clusterNew.agentConfig.overrideAffinity.podAffinity.typeOptions.preferred'
+}]
+
export default Component.extend({
layout,
namespaceModes,
-
+ priorityOptions,
+ TERM_PRIORITY,
/**
* {
* priority: preferred or required
@@ -64,13 +73,6 @@ export default Component.extend({
typeChanged: null,
antiChanged: null,
- priorityOptions: [{
- value: TERM_PRIORITY.REQUIRED,
- label: 'clusterNew.agentConfig.overrideAffinity.podAffinity.typeOptions.required'
- }, {
- value: TERM_PRIORITY.PREFERRED,
- label: 'clusterNew.agentConfig.overrideAffinity.podAffinity.typeOptions.preferred'
- }],
affinityOptions: [{
value: 'true',
@@ -88,27 +90,44 @@ export default Component.extend({
}
},
- // namespaceModeObserver: observer('namespaceMode', () => {
-
- // }),
-
editing: computed('mode', function() {
const mode = get(this, 'mode')
return mode === 'new' || mode === 'edit'
}),
- term: computed('value.term', function(){
- return get(this.value, 'term') || {}
+
+ // TODO nb acccount for weight if value.priority === 'preferred'
+ podAffintyTerm: computed('value.term', 'value.priority', function() {
+ return get(this.value, 'priority') === TERM_PRIORITY.REQUIRED ? get(this.value, 'term') : get(this.value, 'term.podAffinityTerm')
}),
- topologyKey: computed('value.topologyKey', function(){
- return get(this.value, 'topologyKey') || ''
- }),
-
- namespaces: computed('term.namespaces', 'namespaceMode', {
+ weight: computed('value.term', 'value.priority', {
get(){
- const namespaces = get(this.term, 'namespaces') || [];
+ return get(this.value, 'priority') === TERM_PRIORITY.REQUIRED ? null : get(this.value, 'term.weight')
+ },
+ set(key, val){
+ if (val || val === 0) {
+ try {
+ const toInt = parseInt(val, 10)
+
+ set(this.value.term, 'weight', toInt)
+ } catch (e){
+ // TODO nb handle bad weight value better
+ console.error(e)
+ }
+ } else if (this.value?.term?.weight){
+ delete this.value.term.weight
+ this.notifyPropertyChange('value')
+ }
+
+ return val
+ }
+ }),
+
+ namespaces: computed('podAffintyTerm.namespaces', 'namespaceMode', {
+ get(){
+ const namespaces = get(this.podAffintyTerm, 'namespaces') || [];
return namespaces.join(', ')
},
@@ -117,9 +136,9 @@ export default Component.extend({
// a,b,c or a, b, c
const parsed = val.split(/,\s*/g).map((ns) => ns.trim()).filter((ns) => !!ns)
- set(this.term, 'namespaces', parsed)
- } else if (this.term.namespaces){
- delete this.term.namespaces
+ set(this.podAffintyTerm, 'namespaces', parsed)
+ } else if (this.podAffintyTerm.namespaces){
+ delete this.podAffintyTerm.namespaces
this.notifyPropertyChange('value')
}
@@ -127,15 +146,15 @@ export default Component.extend({
}
}),
- namespaceSelector: computed('namespaceMode', 'term.namespaceSelector', {
+ namespaceSelector: computed('namespaceMode', 'podAffintyTerm.namespaceSelector', {
get(){
- return this.term.namespaceSelector || {}
+ return this.podAffintyTerm.namespaceSelector || {}
},
set(key, val){
if (val){
- set(this.term, 'namespaceSelector', val)
- } else if (this.term.namespaceSelector){
- delete this.term.namespaceSelector
+ set(this.podAffintyTerm, 'namespaceSelector', val)
+ } else if (this.podAffintyTerm.namespaceSelector){
+ delete this.podAffintyTerm.namespaceSelector
this.notifyPropertyChange('value')
}
@@ -178,19 +197,17 @@ export default Component.extend({
// null or empty namespaces and null selector = 'this pod's namespace'
// null or empty namespaces and empty object selector = 'all namespaces'
- namespaceMode: computed('term.namespaceSelector', 'term.namespaces.length', {
+ namespaceMode: computed('podAffintyTerm.namespaceSelector', 'podAffintyTerm.namespaces.length', {
get(){
- if (this.term.namespaceSelector){
+ if (this.podAffintyTerm.namespaceSelector){
return namespaceModes.ALL
- } else if (this.term.namespaces){
+ } else if (this.podAffintyTerm.namespaces){
return namespaceModes.IN_LIST
}
return namespaceModes.THIS_POD
},
set(key, val){
- // const namespaceMode = get(this, 'namespaceMode');
-
switch (val){
case namespaceModes.ALL:
set(this, 'namespaceSelector', {})
@@ -208,7 +225,6 @@ export default Component.extend({
return val
}
- })
-
+ }),
})
\ No newline at end of file
diff --git a/lib/shared/addon/components/form-pod-affinity-term-k8s/template.hbs b/lib/shared/addon/components/form-pod-affinity-term-k8s/template.hbs
index 0b590d640..0d4a25084 100644
--- a/lib/shared/addon/components/form-pod-affinity-term-k8s/template.hbs
+++ b/lib/shared/addon/components/form-pod-affinity-term-k8s/template.hbs
@@ -36,7 +36,7 @@
-
+
-
+
+
+
{{#input-or-display
editable=editing
- value=toplogyKey
+ value=podAffintyTerm.topologyKey
}}
{{input
type="text"
class="form-control input-sm"
- value=topologyKey
+ value=podAffintyTerm.topologyKey
placeholder=(t "clusterNew.agentConfig.overrideAffinity.podAffinity.topologyKey.placeholder")
}}
{{/input-or-display}}
+ {{#if (eq value.priority TERM_PRIORITY.PREFERRED)}}
+
+
+ {{#input-or-display
+ editable=editing
+ value=weight
+ }}
+ {{input
+ type="number"
+ class="form-control input-sm"
+ value=weight
+ placeholder=(t "clusterNew.agentConfig.overrideAffinity.podAffinity.weight.placeholder")
+ }}
+ {{/input-or-display}}
+
+ {{/if}}
\ No newline at end of file
diff --git a/translations/en-us.yaml b/translations/en-us.yaml
index 1a87ff05c..3592d193a 100644
--- a/translations/en-us.yaml
+++ b/translations/en-us.yaml
@@ -3374,9 +3374,13 @@ clusterNew:
all: All Namespaces
thisPod: This pod's namespace
inList: 'Namespaces in this list:'
+ weight:
+ placeholder: e.g. 1
+ label: Weight
priority: Priority
nodeAffinity:
title: Node Affinity
+ addTerm: Add Node Selector
aliyunack:
shortLabel: Alibaba ACK
amazoneks: