mirror of https://github.com/portainer/portainer
fix(k8s/resource-pool): unusable RP access management (#4810)
parent
d2d7f6fdb9
commit
e401724d43
|
@ -1,10 +1,32 @@
|
||||||
import _ from 'lodash-es';
|
import _ from 'lodash-es';
|
||||||
import { KubernetesConfigMap } from 'Kubernetes/models/config-map/models';
|
import { KubernetesConfigMap, KubernetesPortainerAccessConfigMap } from 'Kubernetes/models/config-map/models';
|
||||||
import { KubernetesConfigMapCreatePayload, KubernetesConfigMapUpdatePayload } from 'Kubernetes/models/config-map/payloads';
|
import { KubernetesConfigMapCreatePayload, KubernetesConfigMapUpdatePayload } from 'Kubernetes/models/config-map/payloads';
|
||||||
import { KubernetesPortainerConfigurationOwnerLabel } from 'Kubernetes/models/configuration/models';
|
import { KubernetesPortainerConfigurationOwnerLabel } from 'Kubernetes/models/configuration/models';
|
||||||
import { KubernetesConfigurationFormValuesEntry } from 'Kubernetes/models/configuration/formvalues';
|
import { KubernetesConfigurationFormValuesEntry } from 'Kubernetes/models/configuration/formvalues';
|
||||||
|
|
||||||
class KubernetesConfigMapConverter {
|
class KubernetesConfigMapConverter {
|
||||||
|
static apiToPortainerAccessConfigMap(data) {
|
||||||
|
const res = new KubernetesPortainerAccessConfigMap();
|
||||||
|
res.Id = data.metadata.uid;
|
||||||
|
res.Data = data.data;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static createAccessPayload(data) {
|
||||||
|
const res = new KubernetesConfigMapCreatePayload();
|
||||||
|
_.unset(res, 'binaryData');
|
||||||
|
res.metadata.name = data.Name;
|
||||||
|
res.metadata.namespace = data.Namespace;
|
||||||
|
res.data = data.Data;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static updateAccessPayload(data) {
|
||||||
|
const res = KubernetesConfigMapConverter.createAccessPayload(data);
|
||||||
|
res.metadata.uid = data.Id;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API ConfigMap to front ConfigMap
|
* API ConfigMap to front ConfigMap
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -2,6 +2,15 @@ export const KubernetesPortainerConfigMapNamespace = 'portainer';
|
||||||
export const KubernetesPortainerConfigMapConfigName = 'portainer-config';
|
export const KubernetesPortainerConfigMapConfigName = 'portainer-config';
|
||||||
export const KubernetesPortainerConfigMapAccessKey = 'NamespaceAccessPolicies';
|
export const KubernetesPortainerConfigMapAccessKey = 'NamespaceAccessPolicies';
|
||||||
|
|
||||||
|
export function KubernetesPortainerAccessConfigMap() {
|
||||||
|
return {
|
||||||
|
Id: 0,
|
||||||
|
Name: KubernetesPortainerConfigMapConfigName,
|
||||||
|
Namespace: KubernetesPortainerConfigMapNamespace,
|
||||||
|
Data: {},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ConfigMap Model
|
* ConfigMap Model
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -3,6 +3,7 @@ import _ from 'lodash-es';
|
||||||
import PortainerError from 'Portainer/error';
|
import PortainerError from 'Portainer/error';
|
||||||
import KubernetesConfigMapConverter from 'Kubernetes/converters/configMap';
|
import KubernetesConfigMapConverter from 'Kubernetes/converters/configMap';
|
||||||
import { KubernetesCommonParams } from 'Kubernetes/models/common/params';
|
import { KubernetesCommonParams } from 'Kubernetes/models/common/params';
|
||||||
|
import { KubernetesPortainerAccessConfigMap } from 'Kubernetes/models/config-map/models';
|
||||||
|
|
||||||
class KubernetesConfigMapService {
|
class KubernetesConfigMapService {
|
||||||
/* @ngInject */
|
/* @ngInject */
|
||||||
|
@ -17,6 +18,54 @@ class KubernetesConfigMapService {
|
||||||
this.deleteAsync = this.deleteAsync.bind(this);
|
this.deleteAsync = this.deleteAsync.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getAccess(namespace, name) {
|
||||||
|
return this.$async(async () => {
|
||||||
|
try {
|
||||||
|
const params = new KubernetesCommonParams();
|
||||||
|
params.id = name;
|
||||||
|
const raw = await this.KubernetesConfigMaps(namespace).get(params).$promise;
|
||||||
|
return KubernetesConfigMapConverter.apiToPortainerAccessConfigMap(raw);
|
||||||
|
} catch (err) {
|
||||||
|
if (err.status === 404) {
|
||||||
|
return new KubernetesPortainerAccessConfigMap();
|
||||||
|
}
|
||||||
|
throw new PortainerError('Unable to retrieve Portainer accesses', err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
createAccess(config) {
|
||||||
|
return this.$async(async () => {
|
||||||
|
try {
|
||||||
|
const payload = KubernetesConfigMapConverter.createAccessPayload(config);
|
||||||
|
const params = {};
|
||||||
|
const namespace = payload.metadata.namespace;
|
||||||
|
const data = await this.KubernetesConfigMaps(namespace).create(params, payload).$promise;
|
||||||
|
return KubernetesConfigMapConverter.apiToPortainerAccessConfigMap(data);
|
||||||
|
} catch (err) {
|
||||||
|
throw new PortainerError('Unable to create Portainer accesses', err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
updateAccess(config) {
|
||||||
|
return this.$async(async () => {
|
||||||
|
try {
|
||||||
|
if (!config.Id) {
|
||||||
|
return await this.createAccess(config);
|
||||||
|
}
|
||||||
|
const payload = KubernetesConfigMapConverter.updateAccessPayload(config);
|
||||||
|
const params = new KubernetesCommonParams();
|
||||||
|
params.id = payload.metadata.name;
|
||||||
|
const namespace = payload.metadata.namespace;
|
||||||
|
const data = await this.KubernetesConfigMaps(namespace).update(params, payload).$promise;
|
||||||
|
return KubernetesConfigMapConverter.apiToPortainerAccessConfigMap(data);
|
||||||
|
} catch (err) {
|
||||||
|
throw new PortainerError('Unable to update Portainer accesses', err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GET
|
* GET
|
||||||
*/
|
*/
|
||||||
|
@ -29,7 +78,7 @@ class KubernetesConfigMapService {
|
||||||
this.KubernetesConfigMaps(namespace).getYaml(params).$promise,
|
this.KubernetesConfigMaps(namespace).getYaml(params).$promise,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (_.get(rawPromise, 'reason.status') == 404 && _.get(yamlPromise, 'reason.status') == 404) {
|
if (_.get(rawPromise, 'reason.status') === 404 && _.get(yamlPromise, 'reason.status') === 404) {
|
||||||
return KubernetesConfigMapConverter.defaultConfigMap(namespace, name);
|
return KubernetesConfigMapConverter.defaultConfigMap(namespace, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@ class KubernetesResourcePoolAccessController {
|
||||||
let [endpoint, pool, configMap] = await Promise.all([
|
let [endpoint, pool, configMap] = await Promise.all([
|
||||||
this.EndpointService.endpoint(this.endpointId),
|
this.EndpointService.endpoint(this.endpointId),
|
||||||
this.KubernetesResourcePoolService.get(name),
|
this.KubernetesResourcePoolService.get(name),
|
||||||
this.KubernetesConfigMapService.get(KubernetesPortainerConfigMapNamespace, KubernetesPortainerConfigMapConfigName),
|
this.KubernetesConfigMapService.getAccess(KubernetesPortainerConfigMapNamespace, KubernetesPortainerConfigMapConfigName),
|
||||||
]);
|
]);
|
||||||
const group = await this.GroupService.group(endpoint.GroupId);
|
const group = await this.GroupService.group(endpoint.GroupId);
|
||||||
const roles = [];
|
const roles = [];
|
||||||
|
@ -96,7 +96,7 @@ class KubernetesResourcePoolAccessController {
|
||||||
this.state.actionInProgress = true;
|
this.state.actionInProgress = true;
|
||||||
const newAccesses = _.concat(this.authorizedUsersAndTeams, this.formValues.multiselectOutput);
|
const newAccesses = _.concat(this.authorizedUsersAndTeams, this.formValues.multiselectOutput);
|
||||||
const accessConfigMap = KubernetesConfigMapHelper.modifiyNamespaceAccesses(angular.copy(this.accessConfigMap), this.pool.Namespace.Name, newAccesses);
|
const accessConfigMap = KubernetesConfigMapHelper.modifiyNamespaceAccesses(angular.copy(this.accessConfigMap), this.pool.Namespace.Name, newAccesses);
|
||||||
await this.KubernetesConfigMapService.update(accessConfigMap);
|
await this.KubernetesConfigMapService.updateAccess(accessConfigMap);
|
||||||
this.Notifications.success('Access successfully created');
|
this.Notifications.success('Access successfully created');
|
||||||
this.$state.reload();
|
this.$state.reload();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
@ -116,7 +116,7 @@ class KubernetesResourcePoolAccessController {
|
||||||
this.state.actionInProgress = true;
|
this.state.actionInProgress = true;
|
||||||
const newAccesses = _.without(this.authorizedUsersAndTeams, ...selectedItems);
|
const newAccesses = _.without(this.authorizedUsersAndTeams, ...selectedItems);
|
||||||
const accessConfigMap = KubernetesConfigMapHelper.modifiyNamespaceAccesses(angular.copy(this.accessConfigMap), this.pool.Namespace.Name, newAccesses);
|
const accessConfigMap = KubernetesConfigMapHelper.modifiyNamespaceAccesses(angular.copy(this.accessConfigMap), this.pool.Namespace.Name, newAccesses);
|
||||||
await this.KubernetesConfigMapService.update(accessConfigMap);
|
await this.KubernetesConfigMapService.updateAccess(accessConfigMap);
|
||||||
this.Notifications.success('Access successfully removed');
|
this.Notifications.success('Access successfully removed');
|
||||||
this.$state.reload();
|
this.$state.reload();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|
|
@ -167,7 +167,6 @@ angular
|
||||||
|
|
||||||
async function initView() {
|
async function initView() {
|
||||||
var endpointMode = $scope.applicationState.endpoint.mode;
|
var endpointMode = $scope.applicationState.endpoint.mode;
|
||||||
const endpointId = +$state.params.endpointId;
|
|
||||||
$scope.state.StackType = 2;
|
$scope.state.StackType = 2;
|
||||||
if (endpointMode.provider === 'DOCKER_SWARM_MODE' && endpointMode.role === 'MANAGER') {
|
if (endpointMode.provider === 'DOCKER_SWARM_MODE' && endpointMode.role === 'MANAGER') {
|
||||||
$scope.state.StackType = 1;
|
$scope.state.StackType = 1;
|
||||||
|
|
Loading…
Reference in New Issue