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:
parent
ac7d819620
commit
d09ae22ba8
14 changed files with 125 additions and 9 deletions
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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">
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue