1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-08-04 21:35:23 +02:00

feat(docker/containers): migrate network tab to react [EE-5210] (#10344)

This commit is contained in:
Chaim Lev-Ari 2023-09-21 14:02:02 +03:00 committed by GitHub
parent e92f067e42
commit 2b47b84e5e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 413 additions and 246 deletions

View file

@ -20,6 +20,11 @@ import {
VolumesTab,
volumesTabUtils,
} from '@/react/docker/containers/CreateView/VolumesTab';
import {
networkTabUtils,
NetworkTab,
type NetworkTabValues,
} from '@/react/docker/containers/CreateView/NetworkTab';
const ngModule = angular
.module('portainer.docker.react.components.containers', [])
@ -57,3 +62,11 @@ withFormValidation(
['allowBindMounts'],
volumesTabUtils.validation
);
withFormValidation<ComponentProps<typeof NetworkTab>, NetworkTabValues>(
ngModule,
withUIRouter(withReactQuery(NetworkTab)),
'dockerCreateContainerNetworkTab',
[],
networkTabUtils.validation
);

View file

@ -8,12 +8,14 @@ import { buildConfirmButton } from '@@/modals/utils';
import { commandsTabUtils } from '@/react/docker/containers/CreateView/CommandsTab';
import { volumesTabUtils } from '@/react/docker/containers/CreateView/VolumesTab';
import { networkTabUtils } from '@/react/docker/containers/CreateView/NetworkTab';
import { ContainerCapabilities, ContainerCapability } from '@/docker/models/containerCapabilities';
import { AccessControlFormData } from '@/portainer/components/accessControlForm/porAccessControlFormModel';
import { ContainerDetailsViewModel } from '@/docker/models/container';
import './createcontainer.css';
import { envVarsTabUtils } from '@/react/docker/containers/CreateView/EnvVarsTab';
import { getContainers } from '@/react/docker/containers/queries/containers';
angular.module('portainer.docker').controller('CreateContainerController', [
'$q',
@ -74,7 +76,6 @@ angular.module('portainer.docker').controller('CreateContainerController', [
selectedGPUs: ['all'],
capabilities: ['compute', 'utility'],
},
NetworkContainer: null,
Labels: [],
ExtraHosts: [],
MacAddress: '',
@ -94,10 +95,9 @@ angular.module('portainer.docker').controller('CreateContainerController', [
commands: commandsTabUtils.getDefaultViewModel(),
envVars: envVarsTabUtils.getDefaultViewModel(),
volumes: volumesTabUtils.getDefaultViewModel(),
network: networkTabUtils.getDefaultViewModel(),
};
$scope.extraNetworks = {};
$scope.state = {
formValidationError: '',
actionInProgress: false,
@ -132,6 +132,11 @@ angular.module('portainer.docker').controller('CreateContainerController', [
$scope.formValues.volumes = volumes;
});
};
$scope.onNetworkChange = function (network) {
return $scope.$evalAsync(() => {
$scope.formValues.network = network;
});
};
function onAlwaysPullChange(checked) {
return $scope.$evalAsync(() => {
@ -280,50 +285,6 @@ angular.module('portainer.docker').controller('CreateContainerController', [
config.HostConfig.PortBindings = bindings;
}
function prepareNetworkConfig(config) {
var mode = config.HostConfig.NetworkMode;
var container = $scope.formValues.NetworkContainer;
var containerName = container;
if (container && typeof container === 'object') {
containerName = container.Names[0];
}
var networkMode = mode;
if (containerName) {
networkMode += ':' + containerName;
config.Hostname = '';
}
config.HostConfig.NetworkMode = networkMode;
config.MacAddress = $scope.formValues.MacAddress;
config.NetworkingConfig.EndpointsConfig[networkMode] = {
IPAMConfig: {
IPv4Address: $scope.formValues.IPv4,
IPv6Address: $scope.formValues.IPv6,
},
};
if (networkMode && _.get($scope.config.NetworkingConfig.EndpointsConfig[networkMode], 'Aliases')) {
var aliases = $scope.config.NetworkingConfig.EndpointsConfig[networkMode].Aliases;
config.NetworkingConfig.EndpointsConfig[networkMode].Aliases = _.filter(aliases, (o) => {
return !_.startsWith($scope.fromContainer.Id, o);
});
}
var dnsServers = [];
if ($scope.formValues.DnsPrimary) {
dnsServers.push($scope.formValues.DnsPrimary);
}
if ($scope.formValues.DnsSecondary) {
dnsServers.push($scope.formValues.DnsSecondary);
}
config.HostConfig.Dns = dnsServers;
config.HostConfig.ExtraHosts = _.map(
_.filter($scope.formValues.ExtraHosts, (v) => v.value),
'value'
);
}
function prepareLabels(config) {
var labels = {};
$scope.formValues.Labels.forEach(function (label) {
@ -439,8 +400,8 @@ angular.module('portainer.docker').controller('CreateContainerController', [
config = commandsTabUtils.toRequest(config, $scope.formValues.commands);
config = envVarsTabUtils.toRequest(config, $scope.formValues.envVars);
config = volumesTabUtils.toRequest(config, $scope.formValues.volumes);
config = networkTabUtils.toRequest(config, $scope.formValues.network, $scope.fromContainer.Id);
prepareNetworkConfig(config);
prepareImageConfig(config);
preparePortBindings(config);
prepareLabels(config);
@ -457,70 +418,6 @@ angular.module('portainer.docker').controller('CreateContainerController', [
$scope.config.HostConfig.PortBindings = bindings;
}
$scope.resetNetworkConfig = function () {
$scope.config.NetworkingConfig = {
EndpointsConfig: {},
};
};
function loadFromContainerNetworkConfig(d) {
$scope.config.NetworkingConfig = {
EndpointsConfig: {},
};
var networkMode = d.HostConfig.NetworkMode;
if (networkMode === 'default') {
$scope.config.HostConfig.NetworkMode = 'bridge';
if (!_.find($scope.availableNetworks, { Name: 'bridge' })) {
$scope.config.HostConfig.NetworkMode = 'nat';
}
}
if ($scope.config.HostConfig.NetworkMode.indexOf('container:') === 0) {
var netContainer = $scope.config.HostConfig.NetworkMode.split(/^container:/)[1];
$scope.config.HostConfig.NetworkMode = 'container';
for (var c in $scope.runningContainers) {
if ($scope.runningContainers[c].Id == netContainer) {
$scope.formValues.NetworkContainer = $scope.runningContainers[c];
}
}
}
$scope.fromContainerMultipleNetworks = Object.keys(d.NetworkSettings.Networks).length >= 2;
if (d.NetworkSettings.Networks[$scope.config.HostConfig.NetworkMode]) {
if (d.NetworkSettings.Networks[$scope.config.HostConfig.NetworkMode].IPAMConfig) {
if (d.NetworkSettings.Networks[$scope.config.HostConfig.NetworkMode].IPAMConfig.IPv4Address) {
$scope.formValues.IPv4 = d.NetworkSettings.Networks[$scope.config.HostConfig.NetworkMode].IPAMConfig.IPv4Address;
}
if (d.NetworkSettings.Networks[$scope.config.HostConfig.NetworkMode].IPAMConfig.IPv6Address) {
$scope.formValues.IPv6 = d.NetworkSettings.Networks[$scope.config.HostConfig.NetworkMode].IPAMConfig.IPv6Address;
}
}
}
$scope.config.NetworkingConfig.EndpointsConfig[$scope.config.HostConfig.NetworkMode] = d.NetworkSettings.Networks[$scope.config.HostConfig.NetworkMode];
if (Object.keys(d.NetworkSettings.Networks).length > 1) {
var firstNetwork = d.NetworkSettings.Networks[Object.keys(d.NetworkSettings.Networks)[0]];
$scope.config.NetworkingConfig.EndpointsConfig[$scope.config.HostConfig.NetworkMode] = firstNetwork;
$scope.extraNetworks = angular.copy(d.NetworkSettings.Networks);
delete $scope.extraNetworks[Object.keys(d.NetworkSettings.Networks)[0]];
}
$scope.formValues.MacAddress = d.Config.MacAddress;
if (d.HostConfig.Dns && d.HostConfig.Dns[0]) {
$scope.formValues.DnsPrimary = d.HostConfig.Dns[0];
if (d.HostConfig.Dns[1]) {
$scope.formValues.DnsSecondary = d.HostConfig.Dns[1];
}
}
// ExtraHosts
if ($scope.config.HostConfig.ExtraHosts) {
var extraHosts = $scope.config.HostConfig.ExtraHosts;
for (var i = 0; i < extraHosts.length; i++) {
var host = extraHosts[i];
$scope.formValues.ExtraHosts.push({ value: host });
}
$scope.config.HostConfig.ExtraHosts = [];
}
}
function loadFromContainerLabels() {
for (var l in $scope.config.Labels) {
if ({}.hasOwnProperty.call($scope.config.Labels, l)) {
@ -640,16 +537,14 @@ angular.module('portainer.docker').controller('CreateContainerController', [
$scope.fromContainer = fromContainer;
$scope.state.mode = 'duplicate';
$scope.config = ContainerHelper.configFromContainer(fromContainer.Model);
$scope.config = ContainerHelper.configFromContainer(angular.copy(d));
$scope.formValues.commands = commandsTabUtils.toViewModel(d);
$scope.formValues.envVars = envVarsTabUtils.toViewModel(d);
$scope.formValues.volumes = volumesTabUtils.toViewModel(d);
$scope.formValues.network = networkTabUtils.toViewModel(d, $scope.availableNetworks, $scope.runningContainers);
loadFromContainerPortBindings(d);
loadFromContainerNetworkConfig(d);
loadFromContainerLabels(d);
loadFromContainerDevices(d);
loadFromContainerDeviceRequests(d);
@ -691,11 +586,8 @@ angular.module('portainer.docker').controller('CreateContainerController', [
.catch(function error(err) {
Notifications.error('Failure', err, 'Unable to retrieve networks');
});
Container.query(
{},
function (d) {
var containers = d;
getContainers(endpoint.Id)
.then((containers) => {
$scope.runningContainers = containers;
$scope.gpuUseAll = _.get($scope, 'endpoint.Snapshots[0].GpuUseAll', false);
$scope.gpuUseList = _.get($scope, 'endpoint.Snapshots[0].GpuUseList', []);
@ -706,11 +598,10 @@ angular.module('portainer.docker').controller('CreateContainerController', [
$scope.fromContainer = {};
$scope.formValues.capabilities = $scope.areContainerCapabilitiesEnabled ? new ContainerCapabilities() : [];
}
},
function (e) {
})
.catch((e) => {
Notifications.error('Failure', e, 'Unable to retrieve running containers');
}
);
});
SystemService.info()
.then(function success(data) {
@ -928,11 +819,11 @@ angular.module('portainer.docker').controller('CreateContainerController', [
}
function connectToExtraNetworks(newContainerId) {
if (!$scope.extraNetworks) {
if (!$scope.formValues.network.extraNetworks) {
return $q.when();
}
var connectionPromises = _.forOwn($scope.extraNetworks, function (network, networkName) {
var connectionPromises = _.forOwn($scope.formValues.network.extraNetworks, function (network, networkName) {
if (_.has(network, 'Aliases')) {
var aliases = _.filter(network.Aliases, (o) => {
return !_.startsWith($scope.fromContainer.Id, o);

View file

@ -202,7 +202,7 @@
<li ng-if="areContainerCapabilitiesEnabled" class="interactive"><a data-target="#container-capabilities" data-toggle="tab">Capabilities</a></li>
</ul>
<!-- tab-content -->
<div class="form-horizontal">
<div class="form-horizontal" ng-if="state.containerIsLoaded">
<div class="tab-content">
<!-- tab-command -->
<div class="tab-pane active" id="command">
@ -220,122 +220,10 @@
</docker-create-container-volumes-tab>
</div>
<!-- tab-network -->
<div class="tab-pane" id="network">
<form class="form-horizontal" style="margin-top: 15px">
<div class="form-group" ng-if="globalNetworkCount === 0 && applicationState.endpoint.mode.provider !== 'DOCKER_SWARM_MODE'">
<div class="col-sm-12">
<span class="small text-muted">You don't have any shared networks. Head over to the <a ui-sref="docker.networks">networks view</a> to create one.</span>
</div>
</div>
<!-- network-input -->
<div class="form-group">
<label for="container_network" class="col-sm-2 col-lg-1 control-label text-left">Network</label>
<div class="col-sm-9">
<select
class="form-control"
ng-options="net.Name as net.Name for net in availableNetworks"
ng-model="config.HostConfig.NetworkMode"
id="container_network"
ng-change="resetNetworkConfig()"
>
<option selected disabled hidden value="">Select a network</option>
</select>
</div>
</div>
<!-- !network-input -->
<!-- container-name-input -->
<div class="form-group" ng-if="config.HostConfig.NetworkMode == 'container'">
<label for="container_network_container" class="col-sm-2 col-lg-1 control-label text-left">Container</label>
<div class="col-sm-9">
<select ng-options="container|containername for container in runningContainers" class="form-control" ng-model="formValues.NetworkContainer">
<option selected disabled hidden value="">Select a container</option>
</select>
</div>
</div>
<!-- !container-name-input -->
<!-- hostname-input -->
<div class="form-group">
<label for="container_hostname" class="col-sm-2 col-lg-1 control-label text-left">Hostname</label>
<div class="col-sm-9">
<input type="text" class="form-control" ng-model="config.Hostname" id="container_hostname" placeholder="e.g. web01" />
</div>
</div>
<!-- !hostname-input -->
<!-- domainname-input -->
<div class="form-group">
<label for="container_domainname" class="col-sm-2 col-lg-1 control-label text-left">Domain Name</label>
<div class="col-sm-9">
<input type="text" class="form-control" ng-model="config.Domainname" id="container_domainname" placeholder="e.g. example.com" />
</div>
</div>
<!-- !domainname -->
<!-- mac-address-input -->
<div class="form-group">
<label for="container_macaddress" class="col-sm-2 col-lg-1 control-label text-left">Mac Address</label>
<div class="col-sm-9">
<input type="text" class="form-control" ng-model="formValues.MacAddress" id="container_macaddress" placeholder="e.g. 12-34-56-78-9a-bc" />
</div>
</div>
<!-- !mac-address-input -->
<!-- ipv4-input -->
<div class="form-group">
<label for="container_ipv4" class="col-sm-2 col-lg-1 control-label text-left">IPv4 Address</label>
<div class="col-sm-9">
<input type="text" class="form-control" ng-model="formValues.IPv4" id="container_ipv4" placeholder="e.g. 172.20.0.7" />
</div>
</div>
<!-- !ipv4-input -->
<!-- ipv6-input -->
<div class="form-group">
<label for="container_ipv6" class="col-sm-2 col-lg-1 control-label text-left">IPv6 Address</label>
<div class="col-sm-9">
<input type="text" class="form-control" ng-model="formValues.IPv6" id="container_ipv6" placeholder="e.g. a:b:c:d::1234" />
</div>
</div>
<!-- !ipv6-input -->
<!-- dns-primary-input -->
<div class="form-group">
<label for="container_dns_primary" class="col-sm-2 col-lg-1 control-label text-left">Primary DNS Server</label>
<div class="col-sm-9">
<input type="text" class="form-control" ng-model="formValues.DnsPrimary" id="container_dns_primary" placeholder="e.g. 1.1.1.1, 2606:4700:4700::1111" />
</div>
</div>
<!-- !dns-primary-input -->
<!-- dns-secondary-input -->
<div class="form-group">
<label for="container_dns_secondary" class="col-sm-2 col-lg-1 control-label text-left">Secondary DNS Server</label>
<div class="col-sm-9">
<input type="text" class="form-control" ng-model="formValues.DnsSecondary" id="container_dns_secondary" placeholder="e.g. 1.0.0.1, 2606:4700:4700::1001" />
</div>
</div>
<!-- !dns-secondary-input -->
<!-- extra-hosts-variables -->
<div class="form-group">
<div class="col-sm-12" style="margin-top: 5px">
<label class="control-label text-left">Hosts file entries</label>
<span class="label label-default interactive" style="margin-left: 10px" ng-click="addExtraHost()">
<pr-icon icon="'plus'" mode="'alt'"></pr-icon> add additional entry
</span>
</div>
<!-- extra-hosts-input-list -->
<div class="col-sm-12 form-inline" style="margin-top: 10px">
<div ng-repeat="variable in formValues.ExtraHosts" style="margin-top: 2px">
<div class="input-group col-sm-5 input-group-sm">
<span class="input-group-addon">value</span>
<input type="text" class="form-control" ng-model="variable.value" placeholder="e.g. host:IP" />
</div>
<button class="btn btn-light" type="button" ng-click="removeExtraHost($index)">
<pr-icon icon="'trash-2'" class-name="'icon-secondary icon-md'"></pr-icon>
</button>
</div>
</div>
<!-- !extra-hosts-input-list -->
</div>
<!-- !extra-hosts-variables -->
</form>
<docker-create-container-network-tab values="formValues.network" on-change="(onNetworkChange)"> </docker-create-container-network-tab>
</div>
<!-- !tab-network -->
<!-- tab-labels -->
<div class="tab-pane" id="labels">
<form class="form-horizontal" style="margin-top: 15px">