-
Notifications
You must be signed in to change notification settings - Fork 135
/
groupsConfigUtil.ts
169 lines (147 loc) · 5.78 KB
/
groupsConfigUtil.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
import { FastifyRequest } from 'fastify';
import {
GroupsConfig,
GroupsConfigBody,
GroupsConfigBodyList,
GroupStatus,
KubeFastifyInstance,
} from '../../../types';
import { getAllGroups, getGroupsCR, updateGroupsCR } from '../../../utils/groupsUtils';
import { getUserName } from '../../../utils/userUtils';
import { isUserAdmin } from '../../../utils/adminUtils';
import createError from 'http-errors';
const SYSTEM_AUTHENTICATED = 'system:authenticated';
export const getGroupsConfig = async (fastify: KubeFastifyInstance): Promise<GroupsConfig> => {
const customObjectsApi = fastify.kube.customObjectsApi;
const groupsCluster = await getAllGroups(customObjectsApi);
const groupsData = getGroupsCR();
const groupsProcessed = processGroupData(groupsData);
const groupsConfigProcessed = processGroupConfig(fastify, groupsProcessed, groupsCluster);
await removeDeletedGroups(fastify, groupsData, groupsConfigProcessed.groupsCRData);
return groupsConfigProcessed.groupsConfig;
};
const transformGroupsConfig = (groupStatus: GroupStatus[]): string[] => {
return groupStatus.filter((group) => group.enabled).map((group) => group.name);
};
export const updateGroupsConfig = async (
fastify: KubeFastifyInstance,
request: FastifyRequest<{ Body: GroupsConfig }>,
): Promise<GroupsConfig> => {
const customObjectsApi = fastify.kube.customObjectsApi;
const { namespace } = fastify.kube;
const username = await getUserName(fastify, request);
const isAdmin = await isUserAdmin(fastify, username, namespace);
if (!isAdmin) {
const error = createError(403, 'Error updating groups, user needs to be admin');
throw error;
}
const groupConfigUpdated = request.body;
const adminConfig = transformGroupsConfig(groupConfigUpdated.adminGroups);
const allowedConfig = transformGroupsConfig(groupConfigUpdated.allowedGroups);
if (adminConfig.length === 0 || allowedConfig.length === 0) {
const error = createError(403, 'Error, groups cannot be empty');
throw error;
}
const dataUpdated: GroupsConfigBody = {
adminGroups: adminConfig.join(','),
allowedGroups: allowedConfig.join(','),
};
const groupsData = await updateGroupsCR(fastify, dataUpdated);
const groupsProcessed = processGroupData(groupsData);
const groupsCluster = await getAllGroups(customObjectsApi);
const updatedConfig = processGroupConfig(fastify, groupsProcessed, groupsCluster);
await removeDeletedGroups(fastify, groupsData, updatedConfig.groupsCRData);
return updatedConfig.groupsConfig;
};
const processGroupData = (groupsData: GroupsConfigBody): GroupsConfigBodyList => {
const adminGroupsList = groupsData.adminGroups.split(',');
const userGroupList = groupsData.allowedGroups.split(',');
return {
adminGroups: adminGroupsList,
allowedGroups: userGroupList,
};
};
const mapListToGroupStatus =
(list: string[]) =>
(group: string, index: number): GroupStatus => ({
id: index,
name: group,
enabled: list.includes(group),
});
/**
* Process the CR Groups data and removes deleted groups that might be selected
* @param groupsDataList CR Groups data in Array format
* @param groups All the current groups in the cluster
* @returns Processed object with the groups, removing missing groups that might be selected
*/
const processGroupConfig = (
fastify: KubeFastifyInstance,
groupsDataList: GroupsConfigBodyList,
groups: string[],
): { groupsConfig: GroupsConfig; groupsCRData: GroupsConfigBody } => {
const adminGroupsConfig = groups.map(mapListToGroupStatus(groupsDataList.adminGroups));
const allowedGroupsConfig = groups.map(mapListToGroupStatus(groupsDataList.allowedGroups));
allowedGroupsConfig.push({
id: allowedGroupsConfig.length,
name: SYSTEM_AUTHENTICATED,
enabled: groupsDataList.allowedGroups.includes(SYSTEM_AUTHENTICATED),
});
const groupsConfig: GroupsConfig = {
adminGroups: adminGroupsConfig,
allowedGroups: allowedGroupsConfig,
errorAdmin: getError(
fastify,
groupsDataList.adminGroups.filter((group) => group),
(group) => !groups.includes(group),
),
errorUser: getError(
fastify,
groupsDataList.allowedGroups.filter((group) => group),
(group) => !groups.includes(group) && group !== SYSTEM_AUTHENTICATED,
),
};
const updatedBody: GroupsConfigBody = {
adminGroups: groupsDataList.adminGroups.filter((group) => groups.includes(group)).join(','),
allowedGroups: groupsDataList.allowedGroups
.filter((group) => groups.includes(group) || group === SYSTEM_AUTHENTICATED)
.join(','),
};
return { groupsConfig, groupsCRData: updatedBody };
};
const getError = (
fastify: KubeFastifyInstance,
array: string[],
predicate: (group: string) => boolean,
): string | undefined => {
let error;
if (array.length === 0) {
error = 'No group is set in the group config, please set one or more group.';
fastify.log.error(error);
return error;
}
const missingItems = array.filter(predicate);
if (missingItems.length === 0) return undefined;
error = `The group${missingItems.length === 1 ? '' : 's'} ${missingItems.join(
', ',
)} no longer exists in OpenShift and has been removed from the selected group list.`;
fastify.log.error(error);
return error;
};
/**
* Check if any selected groups has been deleted and update the configuration if so
* @param fastify Fastify instance
* @param groupsData Custom Resource Data for group configuration
* @param groupsConfigProcessed Processed data with missing groups deleted
*/
const removeDeletedGroups = async (
fastify: KubeFastifyInstance,
groupsData: GroupsConfigBody,
groupsCRData: GroupsConfigBody,
): Promise<void> => {
if (
groupsData.adminGroups !== groupsCRData.adminGroups ||
groupsData.allowedGroups !== groupsCRData.allowedGroups
) {
await updateGroupsCR(fastify, groupsCRData);
}
};