From c778ef64049d75153bb0518a47a89288ddff7cb3 Mon Sep 17 00:00:00 2001 From: Maxime Bajeux Date: Wed, 8 Jul 2020 03:35:52 +0200 Subject: [PATCH] feat(networks): Support multiple excluded IPs for MACVLAN networks (#3962) * feat(networks): Support multiple excluded IPs for MACVLAN networks * feat(networks): add a generated name * feat(networks): prevent create macvlan network where exclude ip is the same as gateway * feat(networks): remove auxaddresses validation on submit * feat(networks): check exclude ip validation on change * feat(networks): check form validation on change * feat(networks): clean checkAuxiliaryAddress function --- .../create/createNetworkController.js | 67 +++++++++++++++++-- .../views/networks/create/createnetwork.html | 50 ++++++++++++-- app/docker/views/networks/edit/network.html | 8 ++- 3 files changed, 112 insertions(+), 13 deletions(-) diff --git a/app/docker/views/networks/create/createNetworkController.js b/app/docker/views/networks/create/createNetworkController.js index 8fe56ede9..134d4fff9 100644 --- a/app/docker/views/networks/create/createNetworkController.js +++ b/app/docker/views/networks/create/createNetworkController.js @@ -21,13 +21,13 @@ angular.module('portainer.docker').controller('CreateNetworkController', [ Subnet: '', Gateway: '', IPRange: '', - AuxAddress: '', + AuxiliaryAddresses: [], }, IPV6: { Subnet: '', Gateway: '', IPRange: '', - AuxAddress: '', + AuxiliaryAddresses: [], }, Labels: [], AccessControlData: new AccessControlFormData(), @@ -79,6 +79,59 @@ angular.module('portainer.docker').controller('CreateNetworkController', [ $scope.formValues.Labels.splice(index, 1); }; + $scope.addIPV4AuxAddress = function () { + $scope.formValues.IPV4.AuxiliaryAddresses.push(''); + }; + + $scope.addIPV6AuxAddress = function () { + $scope.formValues.IPV6.AuxiliaryAddresses.push(''); + }; + + $scope.removeIPV4AuxAddress = function (index) { + $scope.formValues.IPV4.AuxiliaryAddresses.splice(index, 1); + $scope.state.IPV4AuxiliaryAddressesError.splice(index, 1); + }; + + $scope.removeIPV6AuxAddress = function (index) { + $scope.formValues.IPV6.AuxiliaryAddresses.splice(index, 1); + $scope.state.IPV6AuxiliaryAddressesError.splice(index, 1); + }; + + function checkAuxiliaryAddress(excludedIP, gateway) { + const split = _.split(excludedIP, '='); + + if (split.length === 2) { + return split[1] === gateway; + } + return excludedIP === gateway; + } + + $scope.checkIPV4AuxiliaryAddress = function (index) { + $scope.state.IPV4AuxiliaryAddressesError[index] = checkAuxiliaryAddress($scope.formValues.IPV4.AuxiliaryAddresses[index], $scope.formValues.IPV4.Gateway); + }; + + $scope.checkIPV6AuxiliaryAddress = function (index) { + $scope.state.IPV6AuxiliaryAddressesError[index] = checkAuxiliaryAddress($scope.formValues.IPV6.AuxiliaryAddresses[index], $scope.formValues.IPV6.Gateway); + }; + + $scope.isValid = function () { + const validIPV4 = !_.reduce($scope.state.IPV4AuxiliaryAddressesError, (acc, item) => acc || item, false); + const validIPV6 = !_.reduce($scope.state.IPV6AuxiliaryAddressesError, (acc, item) => acc || item, false); + return validIPV4 && validIPV6; + }; + + function prepareAuxiliaryAddresses(ipamConfig, ipFormValues) { + ipamConfig.AuxiliaryAddresses = {}; + _.forEach(ipFormValues.AuxiliaryAddresses, (auxAddress, index) => { + const split = _.split(auxAddress, '='); + if (split.length === 2) { + ipamConfig.AuxiliaryAddresses[split[0]] = split[1]; + } else { + ipamConfig.AuxiliaryAddresses['device' + index] = auxAddress; + } + }); + } + function prepareIPAMConfiguration(config) { if ($scope.formValues.IPV4.Subnet) { let ipamConfig = {}; @@ -89,8 +142,8 @@ angular.module('portainer.docker').controller('CreateNetworkController', [ if ($scope.formValues.IPV4.IPRange) { ipamConfig.IPRange = $scope.formValues.IPV4.IPRange; } - if ($scope.formValues.IPV4.AuxAddress) { - ipamConfig.AuxAddress = $scope.formValues.IPV4.AuxAddress; + if ($scope.formValues.IPV4.AuxiliaryAddresses.length) { + prepareAuxiliaryAddresses(ipamConfig, $scope.formValues.IPV4); } config.IPAM.Config.push(ipamConfig); } @@ -103,8 +156,8 @@ angular.module('portainer.docker').controller('CreateNetworkController', [ if ($scope.formValues.IPV6.IPRange) { ipamConfig.IPRange = $scope.formValues.IPV6.IPRange; } - if ($scope.formValues.IPV6.AuxAddress) { - ipamConfig.AuxAddress = $scope.formValues.IPV6.AuxAddress; + if ($scope.formValues.IPV6.AuxiliaryAddresses.length) { + prepareAuxiliaryAddresses(ipamConfig, $scope.formValues.IPV6); } config.EnableIPv6 = true; config.IPAM.Config.push(ipamConfig); @@ -245,6 +298,8 @@ angular.module('portainer.docker').controller('CreateNetworkController', [ function initView() { var apiVersion = $scope.applicationState.endpoint.apiVersion; + $scope.state.IPV4AuxiliaryAddressesError = []; + $scope.state.IPV6AuxiliaryAddressesError = []; PluginService.networkPlugins(apiVersion < 1.25) .then(function success(data) { diff --git a/app/docker/views/networks/create/createnetwork.html b/app/docker/views/networks/create/createnetwork.html index 7cfc402c8..56a3f06bf 100644 --- a/app/docker/views/networks/create/createnetwork.html +++ b/app/docker/views/networks/create/createnetwork.html @@ -88,12 +88,32 @@
- + +
+
- + +
+ +
+

Exclude ip cannot be the same as gateway.

+
+ + add excluded IP + +
@@ -117,12 +137,32 @@
- +
+
+
- + +
+ +
+

Exclude ip cannot be the same as gateway.

+
+ + add excluded IP + +
Advanced configuration @@ -205,7 +245,7 @@