diff --git a/lib/shared/addon/components/form-affinity-k8s/component.js b/lib/shared/addon/components/form-affinity-k8s/component.js index 71fa03515..642c0e904 100644 --- a/lib/shared/addon/components/form-affinity-k8s/component.js +++ b/lib/shared/addon/components/form-affinity-k8s/component.js @@ -86,15 +86,110 @@ export default Component.extend({ value: null, mode: 'new', - podAffinity: computed('value.podAffinity', function(){ - return get(this.value, 'podAffinity') || {} + actions: { + affinityChanged(key, val){ + // TODO nb update affinity + console.log('affinity ', key, ' changed to: ', val) + } + }, + + podAffinity: computed('value.podAffinity.{preferredDuringSchedulingIgnoredDuringExecution,requiredDuringSchedulingIgnoredDuringExecution}', { + get(){ + if (!this.value?.podAffinity){ + set(this.value, 'podAffinity', {}) + } + this.initPreferredRequired(this.value.podAffinity) + + return get(this.value, 'podAffinity') + }, + set(key, val){ + // TODO nb move withoutId to own function + const withoutId = { + preferredDuringSchedulingIgnoredDuringExecution: (val.preferredDuringSchedulingIgnoredDuringExecution || []).map((term) => { + delete term._id; + + return term + }), + requiredDuringSchedulingIgnoredDuringExecution: (val.requiredDuringSchedulingIgnoredDuringExecution || []).map((term) => { + delete term._id; + + return term + }) + } + + set(this.value, 'podAffinity', withoutId) + this.notifyPropertyChange('value') + + return val + } }), - podAntiAffinity: computed('value.podAntiAffinity', function(){ - return get(this.value, 'podAntiAffinity') || {} + podAntiAffinity: computed('value.podAntiAffinity.{preferredDuringSchedulingIgnoredDuringExecution,requiredDuringSchedulingIgnoredDuringExecution}', { + get(){ + if (!this.value?.podAntiAffinity){ + set(this.value, 'podAntiAffinity', {}) + } + this.initPreferredRequired(this.value.podAntiAffinity) + + return get(this.value, 'podAntiAffinity') + }, + set(key, val){ + const withoutId = { + preferredDuringSchedulingIgnoredDuringExecution: (val.preferredDuringSchedulingIgnoredDuringExecution || []).map((term) => { + delete term._id; + + return term + }), + requiredDuringSchedulingIgnoredDuringExecution: (val.requiredDuringSchedulingIgnoredDuringExecution || []).map((term) => { + delete term._id; + + return term + }) + } + + set(this.value, 'podAntiAffinity', withoutId) + this.notifyPropertyChange('value') + + return val + } }), - nodeAffinity: computed('value.nodeAffinity', function(){ - return get(this.value, 'nodeAffinity') || {} + nodeAffinity: computed('value.nodeAffinity.{preferredDuringSchedulingIgnoredDuringExecution,requiredDuringSchedulingIgnoredDuringExecution}', { + get(){ + if (!this.value?.nodeAffinity){ + set(this.value, 'nodeAffinity', {}) + } + this.initPreferredRequired(this.value.nodeAffinity) + + return get(this.value, 'nodeAffinity') + }, + set(key, val){ + const withoutId = { + preferredDuringSchedulingIgnoredDuringExecution: (val.preferredDuringSchedulingIgnoredDuringExecution || []).map((term) => { + delete term._id; + + return term + }), + requiredDuringSchedulingIgnoredDuringExecution: (val.requiredDuringSchedulingIgnoredDuringExecution || []).map((term) => { + delete term._id; + + return term + }) + } + + set(this.value, 'nodeAffinity', withoutId) + this.notifyPropertyChange('value') + + return val + } }), + + initPreferredRequired: (val) => { + if (!val.preferredDuringSchedulingIgnoredDuringExecution){ + set(val, 'preferredDuringSchedulingIgnoredDuringExecution', []) + } + if (!val.requiredDuringSchedulingIgnoredDuringExecution){ + set(val, 'requiredDuringSchedulingIgnoredDuringExecution', []) + } + } }) \ No newline at end of file diff --git a/lib/shared/addon/components/form-affinity-k8s/template.hbs b/lib/shared/addon/components/form-affinity-k8s/template.hbs index a690d74fa..537cde67f 100644 --- a/lib/shared/addon/components/form-affinity-k8s/template.hbs +++ b/lib/shared/addon/components/form-affinity-k8s/template.hbs @@ -9,13 +9,9 @@ - -
-
\ No newline at end of file diff --git a/lib/shared/addon/components/form-agent-config/component.js b/lib/shared/addon/components/form-agent-config/component.js index e1f91bc71..49782adb6 100644 --- a/lib/shared/addon/components/form-agent-config/component.js +++ b/lib/shared/addon/components/form-agent-config/component.js @@ -106,7 +106,8 @@ export default Component.extend({ return get(this, 'agentConfig.overrideAffinity') || {} }, set(key, val){ - // TODO nb update agentConfig + set(this.agentConfig, 'overrideAffinity', val) + return val } }), 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 b10576521..9d766c320 100644 --- a/lib/shared/addon/components/form-pod-affinity-k8s/component.js +++ b/lib/shared/addon/components/form-pod-affinity-k8s/component.js @@ -6,6 +6,7 @@ import { set, observer } from '@ember/object'; +import { randomStr } from '../../utils/util'; /** podAffinity: { * preferredDuringSchedulingIgnoredDuringExecution: @@ -16,13 +17,57 @@ import { * requiredDuringSchedulingIgnoredDuringExecution: * - podaffinityterm * } + * podAntiAffinity: same shape */ + +export const TERM_PRIORITY = { + PREFERRED: 'preferred', + REQUIRED: 'required' +} + export default Component.extend({ layout, - value: null, - mode: 'new', - anti: false, + TERM_PRIORITY, + podAffinity: null, + podAntiAffinity: null, + value: null, + mode: 'new', + anti: false, + allTerms: [], + /** + * this component renders one list for required & preferred arrays of terms in affinity & antiAffinity + * each podaffinitytermk8s component can change between affinity and antiaffinity and 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 + * anti: bool + * term:preferred or required term + * } + * + */ + init(){ + this._super(...arguments); + const allTerms = [] + const addTerms = function(terms = [], priority, isAnti){ + terms.forEach((term) => { + allTerms.push({ + priority, + anti: isAnti, + term + }) + }) + } + + addTerms(this.podAffinity?.preferredDuringSchedulingIgnoredDuringExecution, TERM_PRIORITY.PREFERRED, false) + addTerms(this.podAffinity?.requiredDuringSchedulingIgnoredDuringExecution, TERM_PRIORITY.REQUIRED, false) + addTerms(this.podAntiAffinity?.preferredDuringSchedulingIgnoredDuringExecution, TERM_PRIORITY.PREFERRED, true) + addTerms(this.podAntiAffinity?.requiredDuringSchedulingIgnoredDuringExecution, TERM_PRIORITY.REQUIRED, true) + + set(this, 'allTerms', allTerms) + }, actions: { addRequired(){ @@ -32,8 +77,137 @@ export default Component.extend({ this.preferredDuringSchedulingIgnoredDuringExecution.pushObject({}) }, - removeTerm(term, key){ - get(this, key).removeObject(term) + addTerm(){ + const neu = { + priority: TERM_PRIORITY.REQUIRED, + anti: false, + term: { _id: randomStr() } + } + + this.allTerms.push(neu) + get(this.podAffinity, 'requiredDuringSchedulingIgnoredDuringExecution').addObject(neu.term) + this.notifyPropertyChange('allTerms') + this.notifyPropertyChange('podAffinity') + + // TODO nb update relevent spec array + }, + + removeTerm(term){ + // TODO nb update relevent spec array + get(this, 'allTerms').removeObject(term) + if (term.anti){ + if (term.priority === TERM_PRIORITY.REQUIRED){ + const removeFrom = get(this.podAntiAffinity, 'requiredDuringSchedulingIgnoredDuringExecution') + + removeFrom.removeObject(term.term) + } else { + const removeFrom = get(this.podAntiAffinity, 'preferredDuringSchedulingIgnoredDuringExecution') + + removeFrom.removeObject(term.term) + } + this.notifyPropertyChange('podAntiAffinity') + } else { + if (term.priority === TERM_PRIORITY.REQUIRED){ + const removeFrom = get(this.podAffinity, 'requiredDuringSchedulingIgnoredDuringExecution') + + removeFrom.removeObject(term.term) + } else { + const removeFrom = get(this.podAffinity, 'preferredDuringSchedulingIgnoredDuringExecution') + + removeFrom.removeObject(term.term) + } + this.notifyPropertyChange('podAffinity') + } + }, + + affinityChanged(){ + // TODO nb this.update() + // needed? + }, + + + + typeChanged(term, old, neu){ + if (term.anti){ + if (old === TERM_PRIORITY.REQUIRED){ + const removeFrom = get(this.podAntiAffinity, 'requiredDuringSchedulingIgnoredDuringExecution') + const addTo = get(this.podAntiAffinity, 'preferredDuringSchedulingIgnoredDuringExecution') + + // removeFrom.removeObject(term.term) + set(this.podAntiAffinity, 'requiredDuringSchedulingIgnoredDuringExecution', this.removeFromSpec(term.term, removeFrom)) + + addTo.pushObject(term.term) + } else { + const removeFrom = get(this.podAntiAffinity, 'preferredDuringSchedulingIgnoredDuringExecution') + const addTo = get(this.podAntiAffinity, 'requiredDuringSchedulingIgnoredDuringExecution') + + // removeFrom.removeObject(term.term) + set(this.podAntiAffinity, 'preferredDuringSchedulingIgnoredDuringExecution', this.removeFromSpec(term.term, removeFrom)) + + addTo.pushObject(term.term) + } + this.notifyPropertyChange('podAntiAffinity') + } else { + if (old === TERM_PRIORITY.REQUIRED){ + const removeFrom = get(this.podAffinity, 'requiredDuringSchedulingIgnoredDuringExecution') + const addTo = get(this.podAffinity, 'preferredDuringSchedulingIgnoredDuringExecution') + + // removeFrom.removeObject(term.term) + set(this.podAffinity, 'requiredDuringSchedulingIgnoredDuringExecution', this.removeFromSpec(term.term, removeFrom)) + + addTo.pushObject(term.term) + } else { + const removeFrom = get(this.podAffinity, 'preferredDuringSchedulingIgnoredDuringExecution') + const addTo = get(this.podAffinity, 'requiredDuringSchedulingIgnoredDuringExecution') + + // removeFrom.removeObject(term.term) + set(this.podAffinity, 'preferredDuringSchedulingIgnoredDuringExecution', this.removeFromSpec(term.term, removeFrom)) + addTo.pushObject(term.term) + } + this.notifyPropertyChange('podAffinity') + } + }, + + antiChanged(term, old, neu){ + if (old){ + if (term.priority === TERM_PRIORITY.REQUIRED){ + const removeFrom = get(this.podAntiAffinity, 'requiredDuringSchedulingIgnoredDuringExecution') + const addTo = get(this.podAffinity, 'requiredDuringSchedulingIgnoredDuringExecution') + + // removeFrom.removeObject(term.term) + set(this.podAntiAffinity, 'requiredDuringSchedulingIgnoredDuringExecution', this.removeFromSpec(term.term, removeFrom)) + + addTo.pushObject(term.term) + } else { + const removeFrom = get(this.podAntiAffinity, 'preferredDuringSchedulingIgnoredDuringExecution') + const addTo = get(this.podAffinity, 'preferredDuringSchedulingIgnoredDuringExecution') + + // removeFrom.removeObject(term.term) + set(this.podAntiAffinity, 'preferredDuringSchedulingIgnoredDuringExecution', this.removeFromSpec(term.term, removeFrom)) + + addTo.pushObject(term.term) + } + } else { + if (term.priority === TERM_PRIORITY.REQUIRED){ + const removeFrom = get(this.podAffinity, 'requiredDuringSchedulingIgnoredDuringExecution') + const addTo = get(this.podAntiAffinity, 'requiredDuringSchedulingIgnoredDuringExecution') + + // removeFrom.removeObject(term.term) + set(this.podAffinity, 'requiredDuringSchedulingIgnoredDuringExecution', this.removeFromSpec(term.term, removeFrom)) + + addTo.pushObject(term.term) + } else { + const removeFrom = get(this.podAffinity, 'preferredDuringSchedulingIgnoredDuringExecution') + const addTo = get(this.podAntiAffinity, 'preferredDuringSchedulingIgnoredDuringExecution') + + // removeFrom.removeObject(term.term) + set(this.podAffinity, 'preferredDuringSchedulingIgnoredDuringExecution', this.removeFromSpec(term.term, removeFrom)) + + addTo.pushObject(term.term) + } + } + this.notifyPropertyChange('podAffinity') + this.notifyPropertyChange('podAntiAffinity') } }, @@ -43,14 +217,38 @@ export default Component.extend({ return mode === 'new' || mode === 'edit' }), - requiredDuringSchedulingIgnoredDuringExecution: computed('value.requiredDuringSchedulingIgnoredDuringExecution', function(){ - return get(this.value, 'requiredDuringSchedulingIgnoredDuringExecution') || [] - }), + removeFromSpec: (term, array) => { + return array.filter((each) => each._id !== term._id) + }, - preferredDuringSchedulingIgnoredDuringExecution: computed('value.preferredDuringSchedulingIngnoredDuringExecution', function(){ - return get(this.value, 'preferredDuringSchedulingIgnoredDuringExecution') || [] - }), + // affinityRequiredDuringSchedulingIgnoredDuringExecution: computed('podAffinity.requiredDuringSchedulingIgnoredDuringExecution', { + // get(){ + // return get(this.podAffinity, 'requiredDuringSchedulingIgnoredDuringExecution') || [] + // }, + // set(key, val){ + // debugger + // if (get(this.podAffinity, 'requiredDuringSchedulingIgnoredDuringExecution')){ + // get(this.podAffinity, 'requiredDuringSchedulingIgnoredDuringExecution').addObject(val) + // } else { + // set(this.podAffinity, 'requiredDuringSchedulingIgnoredDuringExecution', [val]) + // } + // this.notifyPropertyChange('podAffinity') + // return val + // } + // }), + + // affinityPreferredDuringSchedulingIgnoredDuringExecution: computed('podAffinity.preferredDuringSchedulingIngnoredDuringExecution', function(){ + // return get(this.podAffinity, 'preferredDuringSchedulingIgnoredDuringExecution') || [] + // }), + + // antiAffinityRequiredDuringSchedulingIgnoredDuringExecution: computed('podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution', function(){ + // return get(this.podAntiAffinity, 'requiredDuringSchedulingIgnoredDuringExecution') || [] + // }), + + // antiAffinityPreferredDuringSchedulingIgnoredDuringExecution: computed('podAntiAffinity.preferredDuringSchedulingIngnoredDuringExecution', function(){ + // return get(this.podAntiAffinity, 'preferredDuringSchedulingIgnoredDuringExecution') || [] + // }), }) \ 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 587ccef48..ce0411b03 100644 --- a/lib/shared/addon/components/form-pod-affinity-k8s/template.hbs +++ b/lib/shared/addon/components/form-pod-affinity-k8s/template.hbs @@ -9,41 +9,23 @@
-
+
- {{#each requiredDuringSchedulingIgnoredDuringExecution as |requiredTerm|}} + {{#each allTerms as |term|}} {{/each}}
{{#if editing}} - - {{/if}} -
-
-
- {{#each preferredDuringSchedulingIgnoredDuringExecution as |preferredTerm|}} - - {{/each}} -
- {{#if editing}} - {{/if}} 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 0c6f1f6e7..45cc039c4 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 @@ -6,6 +6,7 @@ import { set, observer } from '@ember/object'; +import { TERM_PRIORITY } from '../form-pod-affinity-k8s/component'; /** if preferred: * - { @@ -46,10 +47,38 @@ export default Component.extend({ layout, namespaceModes, + /** + * { + * priority: preferred or required + * anti: bool - podAffinity or podAntiAffinity + * term: podaffinityterm OR + * { + * weight, + * podAffintyTerm + * } + * } + */ value: null, mode: 'new', - perferred: false, remove: null, + 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', + label: 'clusterNew.agentConfig.overrideAffinity.podAffinity.typeOptions.antiAffinity' + }, { + value: 'false', + label: 'clusterNew.agentConfig.overrideAffinity.podAffinity.typeOptions.affinity' + }], actions: { removeTerm(){ @@ -95,7 +124,6 @@ export default Component.extend({ return namespaces.join(', ') }, set(key, val){ - // TODO nb delete if not set if (val || val === ''){ // a,b,c or a, b, c const parsed = val.split(/,\s*/g).map((ns) => ns.trim()).filter((ns) => !!ns) @@ -126,6 +154,39 @@ export default Component.extend({ } }), + priority: computed('priorityOptions', 'value.priority', { + get(){ + return get(this.value, 'priority') + }, + set(key, val){ + const old = get(this.value, 'priority') + + set(this.value, 'priority', val) + this.typeChanged(old, val) + + return val + }, + }), + + anti: computed('affinityOptions', 'value.anti', { + get(){ + const isAnti = get(this.value, 'anti') + + + return isAnti ? 'true' : 'false' + }, + set(key, val){ + const old = get(this, 'anti') === 'true' + const neu = val === 'true' + + set(this.value, 'anti', neu) + + this.antiChanged(old, neu) + + return val + }, + }), + namespaceMode: namespaceModes.ALL, 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 9e21330e0..e08117d33 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 @@ -6,6 +6,34 @@
{{/if }} +
+
+ {{!-- --}} + +
+
+ {{!-- --}} + +
+
diff --git a/translations/en-us.yaml b/translations/en-us.yaml index cb7ac1863..1a87ff05c 100644 --- a/translations/en-us.yaml +++ b/translations/en-us.yaml @@ -3360,16 +3360,21 @@ clusterNew: title: Pod AntiAffinity podAffinity: title: Pod Affinity - addRequired: Add Required Pod Affinity Term - addPreferred: Add Preferred Pod Affinity Term + addTerm: Add Pod Affinity Term topologyKey: label: Topology Key placeholder: e.g. failure-domain.beta.kubernetes.io/zone + typeOptions: + affinity: Affinity + antiAffinity: AntiAffinity + preferred: Preferred + required: Required namespaces: radioOptions: all: All Namespaces thisPod: This pod's namespace inList: 'Namespaces in this list:' + priority: Priority nodeAffinity: title: Node Affinity aliyunack: