Skip to content

Commit

Permalink
Impl [Nuclio] Resources: Add Node Selectors (#1237)
Browse files Browse the repository at this point in the history
Co-authored-by: Andrew Mavdryk <[email protected]>
  • Loading branch information
eran-nussbaum and mavdryk authored Jun 9, 2021
1 parent c0f9033 commit cfc7bf2
Show file tree
Hide file tree
Showing 4 changed files with 172 additions and 15 deletions.
2 changes: 2 additions & 0 deletions src/i18n/en/functions.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
"CREATE_NEW_HEADER": "Create a new header",
"CREATE_NEW_HOST": "Create a new host",
"CREATE_NEW_LABEL": "Create a new label",
"CREATE_NEW_NODE_SELECTOR": "Create a new node selector",
"CREATE_NEW_RUNTIME_ATTRIBUTE": "Create a new runtime attribute",
"CREATE_NEW_SUBSCRIPTION": "Create a new subscription",
"CREATE_NEW_TRIGGER": "Create a new trigger",
Expand Down Expand Up @@ -175,6 +176,7 @@
"NO_FUNCTIONS_AVAILABLE": "No functions available",
"NO_INTERNET_ACCESS": "No internet access",
"NO_LOGS_HAVE_BEEN_FOUND": "No logs have been found...",
"NODE_SELECTORS": "Node selectors",
"NORMAL": "Normal",
"NOT_START_WITH_FORBIDDEN_WORDS": "Must not start with 'kubernetes.io', 'k8s.io' or 'nuclio.io'",
"NOT_YET_DEPLOYED": "Not yet deployed",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
}

.inputs-container {
width: calc(100% - 30px);
width: calc(100% - 45px);
display: flex;

&.use-checkbox {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint max-statements: ["error", 60] */
(function () {
'use strict';

Expand All @@ -11,8 +12,10 @@
controller: NclVersionConfigurationResourcesController
});

function NclVersionConfigurationResourcesController($rootScope, $scope, $timeout, lodash, ConfigService) {
function NclVersionConfigurationResourcesController($i18next, $rootScope, $scope, $timeout, i18next, lodash,
ConfigService, FormValidationService) {
var ctrl = this;
var lng = i18next.language;

var defaultUnit = {
id: 'gb',
Expand Down Expand Up @@ -74,18 +77,31 @@
{ id: 'eb', name: 'EB', unit: 'E', root: 1000, power: 6 },
{ id: 'eib', name: 'EiB', unit: 'Ei', root: 1024, power: 6 }
];
ctrl.nodeSelectors = [];
ctrl.nodeSelectorsValidationRules = {
key: [
{
name: 'uniqueness',
label: $i18next.t('functions:UNIQUENESS', {lng: lng}),
pattern: validateNodeSelectorUniqueness
}
]
};
ctrl.windowSizeSlider = {};

ctrl.$onInit = onInit;
ctrl.$onChanges = onChanges;
ctrl.$onDestroy = onDestroy;

ctrl.addNewNodeSelector = addNewNodeSelector;
ctrl.cpuDropdownCallback = cpuDropdownCallback;
ctrl.cpuInputCallback = cpuInputCallback;
ctrl.gpuInputCallback = gpuInputCallback;
ctrl.handleNodeSelectorsAction = handleNodeSelectorsAction;
ctrl.isInactivityWindowShown = isInactivityWindowShown;
ctrl.memoryDropdownCallback = memoryDropdownCallback;
ctrl.memoryInputCallback = memoryInputCallback;
ctrl.onChangeNodeSelectorsData = onChangeNodeSelectorsData;
ctrl.replicasInputCallback = replicasInputCallback;
ctrl.sliderInputCallback = sliderInputCallback;

Expand Down Expand Up @@ -124,6 +140,7 @@
ctrl.maxReplicas = lodash.get(ctrl.version, 'spec.maxReplicas');

initScaleToZeroData();
initNodeSelectors();

$timeout(function () {
setFormValidity();
Expand All @@ -146,6 +163,29 @@
// Public methods
//

/**
* Adds new node selector
* param {Event} event - native event object
*/
function addNewNodeSelector(event) {
$timeout(function () {
if (ctrl.nodeSelectors.length < 1 || lodash.last(ctrl.nodeSelectors).ui.isFormValid) {
ctrl.nodeSelectors.push({
name: '',
value: '',
ui: {
editModeActive: true,
isFormValid: false,
name: 'nodeSelector'
}
});

$rootScope.$broadcast('change-state-deploy-button', { component: 'nodeSelector', isDisabled: true });
event.stopPropagation();
}
}, 50);
}

/**
* CPU dropdown callback
* @param {Object} item
Expand Down Expand Up @@ -211,6 +251,22 @@
}
}

/**
* Handler on Node selector action type
* @param {string} actionType
* @param {number} index - index of the "Node selector" in the array
*/
function handleNodeSelectorsAction(actionType, index) {
if (actionType === 'delete') {
ctrl.nodeSelectors.splice(index, 1);

$timeout(function () {
updateNodeSelectors();
});
}
}


/**
* Checks whether the inactivity window can be shown
* @returns {boolean}
Expand Down Expand Up @@ -278,6 +334,17 @@
ctrl.onChangeCallback();
}

/**
* Changes Node selector data
* @param {Object} nodeSelector
* @param {number} index
*/
function onChangeNodeSelectorsData(nodeSelector, index) {
ctrl.nodeSelectors[index] = lodash.cloneDeep(nodeSelector);

updateNodeSelectors();
}

/**
* Replicas data update callback
* @param {string|number} newData
Expand Down Expand Up @@ -424,7 +491,7 @@
cpu: parseValue(limitsCpu),
gpu: parseValue(limitsGpu)
}
}
};

// get size unit from memory values into int or set default, example: '15G' -> 'G'
ctrl.selectedRequestUnit = lodash.isNil(requestsMemory) ? defaultUnit :
Expand Down Expand Up @@ -491,6 +558,33 @@
});
}

/**
* Initializes data for Node selectors section
*/
function initNodeSelectors() {
ctrl.nodeSelectors = lodash.chain(ctrl.version)
.get('spec.nodeSelector', {})
.map(function (value, key) {
return {
name: key,
value: value,
ui: {
editModeActive: false,
isFormValid: key.length > 0 && value.length > 0,
name: 'nodeSelector'
}
};
})
.value();

$timeout(function () {
if (ctrl.nodeSelectorsForm.$invalid) {
ctrl.nodeSelectorsForm.$setSubmitted();
$rootScope.$broadcast('change-state-deploy-button', { component: 'nodeSelector', isDisabled: true });
}
});
}

/**
* Initializes data for "Scale to zero" section
*/
Expand Down Expand Up @@ -534,6 +628,33 @@
}
}

/**
* Updates Node selectors
*/
function updateNodeSelectors() {
var isFormValid = true;
var newNodeSelectors = {};

lodash.forEach(ctrl.nodeSelectors, function (nodeSelector) {
if (!nodeSelector.ui.isFormValid) {
isFormValid = false;
}

newNodeSelectors[nodeSelector.name] = nodeSelector.value;
});

// since uniqueness validation rule of some fields is dependent on the entire label list, then whenever
// the list is modified - the rest of the labels need to be re-validated
FormValidationService.validateAllFields(ctrl.nodeSelectorsForm);

$rootScope.$broadcast('change-state-deploy-button', {
component: 'nodeSelector',
isDisabled: !isFormValid || ctrl.nodeSelectorsForm.$invalid
});

lodash.set(ctrl.version, 'spec.nodeSelector', newNodeSelectors);
}

/**
* Updates parameters for "Scale to zero" section
*/
Expand Down Expand Up @@ -578,7 +699,16 @@
}
}
}
}
};
}

/**
* Determines `uniqueness` validation for Node selector `Key` field
* @param {string} value - value to validate
* @returns {boolean}
*/
function validateNodeSelectorUniqueness(value) {
return lodash.filter(ctrl.nodeSelectors, ['name', value]).length === 1;
}
}
}());
Original file line number Diff line number Diff line change
@@ -1,15 +1,37 @@
<div class="ncl-version-configuration-resources">
<div class="title">{{ 'common:RESOURCES' | i18next }}</div>
<form name="$ctrl.nodeSelectorsForm" novalidate>
<div class="title">{{ 'functions:NODE_SELECTORS' | i18next }}</div>
<div class="row">
<div class="igz-row form-row">
<div class="table-body" data-ng-repeat="nodeSelector in $ctrl.nodeSelectors">
<ncl-key-value-input class="node-selectors"
data-row-data="nodeSelector"
data-item-index="$index"
data-use-type="false"
data-validation-rules="$ctrl.nodeSelectorsValidationRules"
data-action-handler-callback="$ctrl.handleNodeSelectorsAction(actionType, index)"
data-change-data-callback="$ctrl.onChangeNodeSelectorsData(newData, index)"
data-submit-on-fly="true">
</ncl-key-value-input>
</div>
<div class="igz-create-button" data-ng-click="$ctrl.addNewNodeSelector($event)">
<span class="igz-icon-add-round"></span>
{{ 'functions:CREATE_NEW_NODE_SELECTOR' | i18next }}
</div>
</div>
</div>
</form>
<form name="$ctrl.resourcesForm" class="resources-wrapper" novalidate>
<div class="title">{{ 'common:RESOURCES' | i18next }}</div>
<div class="row">

<div class="igz-row form-row range-inputs-row">
<div class="igz-col-20 row-title">{{ 'common:MEMORY' | i18next }}
<igz-more-info data-trigger="click"
data-is-html-enabled="true"
data-is-open="$ctrl.memoryWarningOpen"
data-icon-type="{{$ctrl.memoryWarningOpen ? 'warn' : 'info'}}"
data-description="{{ 'common:RESOURCES_WARNING_LIMIT_FILLED_REQUEST_EMPTY' | i18next:{ when: 'the function is deployed' } }}"></igz-more-info>
data-description="{{ 'common:RESOURCES_WARNING_LIMIT_FILLED_REQUEST_EMPTY' | i18next:{ when: 'the function is deployed' } }}">
</igz-more-info>
</div>

<div class="igz-col-40 input-wrapper">
Expand Down Expand Up @@ -145,9 +167,10 @@
<div class="igz-col-40 input-wrapper">
<div class="input-title">
{{ 'functions:MIN' | i18next }}
<igz-more-info data-description="{{ 'functions:MIN_REPLICAS' | i18next:{default: $ctrl.defaultFunctionConfig.spec.minReplicas} }}"
data-default-tooltip-placement="top"
data-trigger="click">
<igz-more-info
data-description="{{ 'functions:MIN_REPLICAS' | i18next:{default: $ctrl.defaultFunctionConfig.spec.minReplicas} }}"
data-default-tooltip-placement="top"
data-trigger="click">
</igz-more-info>
</div>
<div class="row-input replicas-number-input">
Expand All @@ -170,9 +193,10 @@
<div class="igz-col-40 input-wrapper">
<div class="input-title" data-ng-class="{ asterisk: $ctrl.minReplicas === 0 }">
{{ 'functions:MAX' | i18next }}
<igz-more-info data-description="{{ 'functions:MAX_REPLICAS' | i18next:{default: $ctrl.defaultFunctionConfig.spec.maxReplicas} }}"
data-default-tooltip-placement="top"
data-trigger="click">
<igz-more-info
data-description="{{ 'functions:MAX_REPLICAS' | i18next:{default: $ctrl.defaultFunctionConfig.spec.maxReplicas} }}"
data-default-tooltip-placement="top"
data-trigger="click">
</igz-more-info>
</div>
<div class="row-input replicas-number-input">
Expand Down Expand Up @@ -216,8 +240,9 @@
<div class="igz-row form-row range-inputs-row slider-block">
<div class="igz-col-25 row-title no-margin target-cpu-title">
<span>{{ 'common:TARGET_CPU' | i18next }}</span>
<igz-more-info data-description="{{ 'functions:TARGET_CPU_DESCRIPTION' | i18next:{default: $ctrl.defaultFunctionConfig.spec.targetCPU} }}"
data-trigger="click">
<igz-more-info
data-description="{{ 'functions:TARGET_CPU_DESCRIPTION' | i18next:{default: $ctrl.defaultFunctionConfig.spec.targetCPU} }}"
data-trigger="click">
</igz-more-info>
</div>
<div class="igz-col-75 row-input slider">
Expand Down

0 comments on commit cfc7bf2

Please sign in to comment.