1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-07-26 00:39:41 +02:00

feat(container): add sysctls setting in the container view (#4910)

* feat(container): add sysctls in the container view (#2756)

* feat(container): add setting to restrict sysctl access

* feat(endpoint): move sysctl disable setting to security settings

* feat(container): add sysctls to container edit view

* fix(container) remove unnecessary migration setting

Co-authored-by: Owen Kirby <oskirby@gmail.com>
This commit is contained in:
Lukas Grotz 2021-04-12 09:40:45 +02:00 committed by GitHub
parent ac7d819620
commit d09ae22ba8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 125 additions and 9 deletions

View file

@ -80,6 +80,7 @@ angular.module('portainer.docker').controller('CreateContainerController', [
EntrypointMode: 'default',
NodeName: null,
capabilities: [],
Sysctls: [],
LogDriverName: '',
LogDriverOpts: [],
RegistryModel: new PorImageRegistryModel(),
@ -136,6 +137,7 @@ angular.module('portainer.docker').controller('CreateContainerController', [
Devices: [],
CapAdd: [],
CapDrop: [],
Sysctls: {},
},
NetworkingConfig: {
EndpointsConfig: {},
@ -191,6 +193,14 @@ angular.module('portainer.docker').controller('CreateContainerController', [
$scope.config.HostConfig.Devices.splice(index, 1);
};
$scope.addSysctl = function () {
$scope.formValues.Sysctls.push({ name: '', value: '' });
};
$scope.removeSysctl = function (index) {
$scope.formValues.Sysctls.splice(index, 1);
};
$scope.addLogDriverOpt = function () {
$scope.formValues.LogDriverOpts.push({ name: '', value: '' });
};
@ -344,6 +354,16 @@ angular.module('portainer.docker').controller('CreateContainerController', [
config.HostConfig.Devices = path;
}
function prepareSysctls(config) {
var sysctls = {};
$scope.formValues.Sysctls.forEach(function (sysctl) {
if (sysctl.name && sysctl.value) {
sysctls[sysctl.name] = sysctl.value;
}
});
config.HostConfig.Sysctls = sysctls;
}
function prepareResources(config) {
// Memory Limit - Round to 0.125
if ($scope.formValues.MemoryLimit >= 0) {
@ -412,6 +432,7 @@ angular.module('portainer.docker').controller('CreateContainerController', [
prepareResources(config);
prepareLogDriver(config);
prepareCapabilities(config);
prepareSysctls(config);
return config;
}
@ -557,6 +578,14 @@ angular.module('portainer.docker').controller('CreateContainerController', [
$scope.config.HostConfig.Devices = path;
}
function loadFromContainerSysctls() {
for (var s in $scope.config.HostConfig.Sysctls) {
if ({}.hasOwnProperty.call($scope.config.HostConfig.Sysctls, s)) {
$scope.formValues.Sysctls.push({ name: s, value: $scope.config.HostConfig.Sysctls[s] });
}
}
}
function loadFromContainerImageConfig() {
RegistryService.retrievePorRegistryModelFromRepository($scope.config.Image)
.then((model) => {
@ -632,6 +661,7 @@ angular.module('portainer.docker').controller('CreateContainerController', [
loadFromContainerImageConfig(d);
loadFromContainerResources(d);
loadFromContainerCapabilities(d);
loadFromContainerSysctls(d);
})
.catch(function error(err) {
Notifications.error('Failure', err, 'Unable to retrieve container');
@ -656,6 +686,7 @@ angular.module('portainer.docker').controller('CreateContainerController', [
$scope.isAdmin = Authentication.isAdmin();
$scope.showDeviceMapping = await shouldShowDevices();
$scope.showSysctls = await shouldShowSysctls();
$scope.areContainerCapabilitiesEnabled = await checkIfContainerCapabilitiesEnabled();
$scope.isAdminOrEndpointAdmin = Authentication.isAdmin();
@ -940,6 +971,12 @@ angular.module('portainer.docker').controller('CreateContainerController', [
return endpoint.SecuritySettings.allowDeviceMappingForRegularUsers || Authentication.isAdmin();
}
async function shouldShowSysctls() {
const { allowSysctlSettingForRegularUsers } = $scope.applicationState.application;
return allowSysctlSettingForRegularUsers || Authentication.isAdmin();
}
async function checkIfContainerCapabilitiesEnabled() {
return endpoint.SecuritySettings.allowContainerCapabilitiesForRegularUsers || Authentication.isAdmin();
}

View file

@ -706,6 +706,33 @@
<!-- !devices-input-list -->
</div>
<!-- !devices-->
<!-- sysctls -->
<div ng-if="showSysctls" class="form-group">
<div class="col-sm-12" style="margin-top: 5px;">
<label class="control-label text-left">Sysctls</label>
<span class="label label-default interactive" style="margin-left: 10px;" ng-click="addSysctl()">
<i class="fa fa-plus-circle" aria-hidden="true"></i> add sysctl
</span>
</div>
<!-- sysctls-input-list -->
<div class="col-sm-12 form-inline" style="margin-top: 10px;">
<div ng-repeat="sysctl in formValues.Sysctls" style="margin-top: 2px;">
<div class="input-group col-sm-5 input-group-sm">
<span class="input-group-addon">name</span>
<input type="text" class="form-control" ng-model="sysctl.name" placeholder="e.g. FOO" />
</div>
<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="sysctl.value" placeholder="e.g. bar" />
</div>
<button class="btn btn-sm btn-danger" type="button" ng-click="removeSysctl($index)">
<i class="fa fa-trash" aria-hidden="true"></i>
</button>
</div>
</div>
<!-- !sysctls-input-list -->
</div>
<!-- !sysctls -->
<div class="col-sm-12 form-section-title">
Resources
</div>

View file

@ -274,6 +274,17 @@
</container-restart-policy>
</td>
</tr>
<tr ng-if="!(container.HostConfig.Sysctls | emptyobject)">
<td>Sysctls</td>
<td>
<table class="table table-bordered table-condensed">
<tr ng-repeat="(k, v) in container.HostConfig.Sysctls">
<td>{{ k }}</td>
<td>{{ v }}</td>
</tr>
</table>
</td>
</tr>
</tbody>
</table>
</rd-widget-body>

View file

@ -104,6 +104,7 @@ angular.module('portainer.docker').controller('ContainerController', [
allowContainerCapabilitiesForRegularUsers,
allowHostNamespaceForRegularUsers,
allowDeviceMappingForRegularUsers,
allowSysctlSettingForRegularUsers,
allowBindMountsForRegularUsers,
allowPrivilegedModeForRegularUsers,
} = endpoint.SecuritySettings;
@ -112,6 +113,7 @@ angular.module('portainer.docker').controller('ContainerController', [
!allowContainerCapabilitiesForRegularUsers ||
!allowBindMountsForRegularUsers ||
!allowDeviceMappingForRegularUsers ||
!allowSysctlSettingForRegularUsers ||
!allowHostNamespaceForRegularUsers ||
!allowPrivilegedModeForRegularUsers;

View file

@ -15,6 +15,7 @@ export default class DockerFeaturesConfigurationController {
disableStackManagementForRegularUsers: false,
disableDeviceMappingForRegularUsers: false,
disableContainerCapabilitiesForRegularUsers: false,
disableSysctlSettingForRegularUsers: false,
};
this.isAgent = false;
@ -33,13 +34,15 @@ export default class DockerFeaturesConfigurationController {
disablePrivilegedModeForRegularUsers,
disableDeviceMappingForRegularUsers,
disableContainerCapabilitiesForRegularUsers,
disableSysctlSettingForRegularUsers,
} = this.formValues;
return (
disableBindMountsForRegularUsers ||
disableHostNamespaceForRegularUsers ||
disablePrivilegedModeForRegularUsers ||
disableDeviceMappingForRegularUsers ||
disableContainerCapabilitiesForRegularUsers
disableContainerCapabilitiesForRegularUsers ||
disableSysctlSettingForRegularUsers
);
}
@ -56,6 +59,7 @@ export default class DockerFeaturesConfigurationController {
allowDeviceMappingForRegularUsers: !this.formValues.disableDeviceMappingForRegularUsers,
allowStackManagementForRegularUsers: !this.formValues.disableStackManagementForRegularUsers,
allowContainerCapabilitiesForRegularUsers: !this.formValues.disableContainerCapabilitiesForRegularUsers,
allowSysctlSettingForRegularUsers: !this.formValues.disableSysctlSettingForRegularUsers,
};
await this.EndpointService.updateSecuritySettings(this.endpoint.Id, securitySettings);
@ -89,6 +93,7 @@ export default class DockerFeaturesConfigurationController {
disableDeviceMappingForRegularUsers: !securitySettings.allowDeviceMappingForRegularUsers,
disableStackManagementForRegularUsers: !securitySettings.allowStackManagementForRegularUsers,
disableContainerCapabilitiesForRegularUsers: !securitySettings.allowContainerCapabilitiesForRegularUsers,
disableSysctlSettingForRegularUsers: !securitySettings.allowSysctlSettingForRegularUsers,
};
}
}

View file

@ -108,6 +108,16 @@
></por-switch-field>
</div>
</div>
<div class="form-group">
<div class="col-sm-12">
<por-switch-field
ng-model="$ctrl.formValues.disableSysctlSettingForRegularUsers"
name="disableSysctlSettingForRegularUsers"
label="Disable sysctl settings for non-administrators"
label-class="col-sm-7 col-lg-4"
></por-switch-field>
</div>
</div>
<div class="form-group" ng-if="$ctrl.isContainerEditDisabled()">
<span class="col-sm-12 text-muted small">