mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-11-01 02:57:59 +00:00
* remove yarn script that no longer works in yarn 3 * delete other deprecated yarn script * add acme_clients to mirage handler and utils * consolidate client names * revert changes to homogenizeClientNaming, wait until confirmation from backend * remove flattenDataset helper * revert deleting flattendataset method (done in separate PR) * move response to helper file * cleanup utils based on test changes * add acme_clients to tests * rename variables and add comments! * refactor homogenizeClientNaming and rename * move by_namespace to test helper as well * add comments and finally delete flattenDataset * add more comments and update response to match no mounts shape * update test selector * finish updates for removing clients: null from serialized response * final comments! * remove arrayOfCounts helper * Update ui/tests/integration/components/clients/page/sync-test.js Co-authored-by: Chelsea Shaw <82459713+hashishaw@users.noreply.github.com> --------- Co-authored-by: Chelsea Shaw <82459713+hashishaw@users.noreply.github.com>
214 lines
7.3 KiB
JavaScript
214 lines
7.3 KiB
JavaScript
/**
|
|
* Copyright (c) HashiCorp, Inc.
|
|
* SPDX-License-Identifier: BUSL-1.1
|
|
*/
|
|
|
|
import { parseAPITimestamp } from 'core/utils/date-formatters';
|
|
import { compareAsc, getUnixTime, isWithinInterval } from 'date-fns';
|
|
|
|
// add new types here
|
|
export const CLIENT_TYPES = [
|
|
'acme_clients',
|
|
'clients', // summation of total clients
|
|
'entity_clients',
|
|
'non_entity_clients',
|
|
'secret_syncs',
|
|
];
|
|
|
|
// returns array of VersionHistoryModels for noteworthy upgrades: 1.9, 1.10
|
|
// that occurred between timestamps (i.e. queried activity data)
|
|
export const filterVersionHistory = (versionHistory, start, end) => {
|
|
if (versionHistory) {
|
|
const upgrades = versionHistory.reduce((array, upgradeData) => {
|
|
const includesVersion = (v) =>
|
|
// only add first match, disregard subsequent patch releases of the same version
|
|
upgradeData.version.match(v) && !array.some((d) => d.version.match(v));
|
|
|
|
['1.9', '1.10'].forEach((v) => {
|
|
if (includesVersion(v)) array.push(upgradeData);
|
|
});
|
|
|
|
return array;
|
|
}, []);
|
|
|
|
// if there are noteworthy upgrades, only return those during queried date range
|
|
if (upgrades.length) {
|
|
const startDate = parseAPITimestamp(start);
|
|
const endDate = parseAPITimestamp(end);
|
|
return upgrades.filter(({ timestampInstalled }) => {
|
|
const upgradeDate = parseAPITimestamp(timestampInstalled);
|
|
return isWithinInterval(upgradeDate, { start: startDate, end: endDate });
|
|
});
|
|
}
|
|
}
|
|
return [];
|
|
};
|
|
|
|
export const formatDateObject = (dateObj, isEnd) => {
|
|
if (dateObj) {
|
|
const { year, monthIdx } = dateObj;
|
|
// day=0 for Date.UTC() returns the last day of the month before
|
|
// increase monthIdx by one to get last day of queried month
|
|
const utc = isEnd ? Date.UTC(year, monthIdx + 1, 0) : Date.UTC(year, monthIdx, 1);
|
|
return getUnixTime(utc);
|
|
}
|
|
};
|
|
|
|
export const formatByMonths = (monthsArray) => {
|
|
// the monthsArray will always include a timestamp of the month and either new/total client data or counts = null
|
|
if (!Array.isArray(monthsArray)) return monthsArray;
|
|
|
|
const sortedPayload = sortMonthsByTimestamp(monthsArray);
|
|
return sortedPayload?.map((m) => {
|
|
const month = parseAPITimestamp(m.timestamp, 'M/yy');
|
|
const totalClientsByNamespace = formatByNamespace(m.namespaces);
|
|
const newClientsByNamespace = formatByNamespace(m.new_clients?.namespaces);
|
|
return {
|
|
month,
|
|
timestamp: m.timestamp,
|
|
...destructureClientCounts(m?.counts),
|
|
namespaces: formatByNamespace(m.namespaces) || [],
|
|
namespaces_by_key: namespaceArrayToObject(
|
|
totalClientsByNamespace,
|
|
newClientsByNamespace,
|
|
month,
|
|
m.timestamp
|
|
),
|
|
new_clients: {
|
|
month,
|
|
timestamp: m.timestamp,
|
|
...destructureClientCounts(m?.new_clients?.counts),
|
|
namespaces: formatByNamespace(m.new_clients?.namespaces) || [],
|
|
},
|
|
};
|
|
});
|
|
};
|
|
|
|
export const formatByNamespace = (namespaceArray) => {
|
|
if (!Array.isArray(namespaceArray)) return namespaceArray;
|
|
return namespaceArray?.map((ns) => {
|
|
// i.e. 'namespace_path' is an empty string for 'root', so use namespace_id
|
|
const label = ns.namespace_path === '' ? ns.namespace_id : ns.namespace_path;
|
|
// data prior to adding mount granularity will still have a mounts key,
|
|
// but with the value: "no mount accessor (pre-1.10 upgrade?)" (ref: vault/activity_log_util_common.go)
|
|
// transform to an empty array for type consistency
|
|
let mounts = [];
|
|
if (Array.isArray(ns.mounts)) {
|
|
mounts = ns.mounts.map((m) => ({ label: m['mount_path'], ...destructureClientCounts(m?.counts) }));
|
|
}
|
|
return {
|
|
label,
|
|
...destructureClientCounts(ns.counts),
|
|
mounts,
|
|
};
|
|
});
|
|
};
|
|
|
|
// In 1.10 'distinct_entities' changed to 'entity_clients' and 'non_entity_tokens' to 'non_entity_clients'
|
|
// these deprecated keys still exist on the response, so only return relevant keys here
|
|
// when querying historical data the response will always contain the latest client type keys because the activity log is
|
|
// constructed based on the version of Vault the user is on (key values will be 0)
|
|
export const destructureClientCounts = (verboseObject) => {
|
|
if (!verboseObject) return;
|
|
return CLIENT_TYPES.reduce((newObj, clientType) => {
|
|
newObj[clientType] = verboseObject[clientType];
|
|
return newObj;
|
|
}, {});
|
|
};
|
|
|
|
export const sortMonthsByTimestamp = (monthsArray) => {
|
|
const sortedPayload = [...monthsArray];
|
|
return sortedPayload.sort((a, b) =>
|
|
compareAsc(parseAPITimestamp(a.timestamp), parseAPITimestamp(b.timestamp))
|
|
);
|
|
};
|
|
|
|
export const namespaceArrayToObject = (totalClientsByNamespace, newClientsByNamespace, month, timestamp) => {
|
|
if (!totalClientsByNamespace) return {}; // return if no data for that month
|
|
// all 'new_client' data resides within a separate key of each month (see data structure below)
|
|
// FIRST: iterate and nest respective 'new_clients' data within each namespace and mount object
|
|
// note: this is happening within the month object
|
|
const nestNewClientsWithinNamespace = totalClientsByNamespace?.map((ns) => {
|
|
const newNamespaceCounts = newClientsByNamespace?.find((n) => n.label === ns.label);
|
|
if (newNamespaceCounts) {
|
|
const newClientsByMount = [...newNamespaceCounts.mounts];
|
|
const nestNewClientsWithinMounts = ns.mounts?.map((mount) => {
|
|
const new_clients = newClientsByMount?.find((m) => m.label === mount.label) || {};
|
|
return {
|
|
...mount,
|
|
new_clients,
|
|
};
|
|
});
|
|
return {
|
|
...ns,
|
|
new_clients: {
|
|
label: ns.label,
|
|
...destructureClientCounts(newNamespaceCounts),
|
|
mounts: newClientsByMount,
|
|
},
|
|
mounts: [...nestNewClientsWithinMounts],
|
|
};
|
|
}
|
|
return {
|
|
...ns,
|
|
new_clients: {},
|
|
};
|
|
});
|
|
// SECOND: create a new object (namespace_by_key) in which each namespace label is a key
|
|
const namespaces_by_key = {};
|
|
nestNewClientsWithinNamespace?.forEach((namespaceObject) => {
|
|
// THIRD: make another object within the namespace where each mount label is a key
|
|
const mounts_by_key = {};
|
|
namespaceObject.mounts.forEach((mountObject) => {
|
|
mounts_by_key[mountObject.label] = {
|
|
month,
|
|
timestamp,
|
|
...mountObject,
|
|
new_clients: { month, ...mountObject.new_clients },
|
|
};
|
|
});
|
|
|
|
const { label, new_clients } = namespaceObject;
|
|
namespaces_by_key[label] = {
|
|
month,
|
|
timestamp,
|
|
...destructureClientCounts(namespaceObject),
|
|
new_clients: { month, ...new_clients },
|
|
mounts_by_key,
|
|
};
|
|
});
|
|
return namespaces_by_key;
|
|
/*
|
|
structure of object returned
|
|
namespace_by_key: {
|
|
"namespace_label": {
|
|
month: "3/22",
|
|
clients: 32,
|
|
entity_clients: 16,
|
|
non_entity_clients: 16,
|
|
new_clients: {
|
|
month: "3/22",
|
|
clients: 5,
|
|
entity_clients: 2,
|
|
non_entity_clients: 3,
|
|
mounts: [...array of this namespace's mounts and their new client counts],
|
|
},
|
|
mounts_by_key: {
|
|
"mount_label": {
|
|
month: "3/22",
|
|
clients: 3,
|
|
entity_clients: 2,
|
|
non_entity_clients: 1,
|
|
new_clients: {
|
|
month: "3/22",
|
|
clients: 5,
|
|
entity_clients: 2,
|
|
non_entity_clients: 3,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
};
|
|
*/
|
|
};
|