mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-11-01 19:17:58 +00:00
* Adding explicit MPL license for sub-package. This directory and its subdirectories (packages) contain files licensed with the MPLv2 `LICENSE` file in this directory and are intentionally licensed separately from the BSL `LICENSE` file at the root of this repository. * Adding explicit MPL license for sub-package. This directory and its subdirectories (packages) contain files licensed with the MPLv2 `LICENSE` file in this directory and are intentionally licensed separately from the BSL `LICENSE` file at the root of this repository. * Updating the license from MPL to Business Source License. Going forward, this project will be licensed under the Business Source License v1.1. Please see our blog post for more details at https://hashi.co/bsl-blog, FAQ at www.hashicorp.com/licensing-faq, and details of the license at www.hashicorp.com/bsl. * add missing license headers * Update copyright file headers to BUS-1.1 * Fix test that expected exact offset on hcl file --------- Co-authored-by: hashicorp-copywrite[bot] <110428419+hashicorp-copywrite[bot]@users.noreply.github.com> Co-authored-by: Sarah Thompson <sthompson@hashicorp.com> Co-authored-by: Brian Kassouf <bkassouf@hashicorp.com>
260 lines
7.6 KiB
JavaScript
260 lines
7.6 KiB
JavaScript
/**
|
|
* Copyright (c) HashiCorp, Inc.
|
|
* SPDX-License-Identifier: BUSL-1.1
|
|
*/
|
|
|
|
import { parseAPITimestamp } from 'core/utils/date-formatters';
|
|
import { compareAsc } from 'date-fns';
|
|
|
|
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);
|
|
if (Object.keys(m).includes('counts')) {
|
|
const totalCounts = flattenDataset(m);
|
|
const newCounts = m.new_clients ? flattenDataset(m.new_clients) : {};
|
|
return {
|
|
month,
|
|
timestamp: m.timestamp,
|
|
...totalCounts,
|
|
namespaces: formatByNamespace(m.namespaces) || [],
|
|
namespaces_by_key: namespaceArrayToObject(totalClientsByNamespace, newClientsByNamespace, month),
|
|
new_clients: {
|
|
month,
|
|
timestamp: m.timestamp,
|
|
...newCounts,
|
|
namespaces: formatByNamespace(m.new_clients?.namespaces) || [],
|
|
},
|
|
};
|
|
}
|
|
});
|
|
};
|
|
|
|
export const formatByNamespace = (namespaceArray) => {
|
|
if (!Array.isArray(namespaceArray)) return namespaceArray;
|
|
return namespaceArray?.map((ns) => {
|
|
// 'namespace_path' is an empty string for root
|
|
if (ns['namespace_id'] === 'root') ns['namespace_path'] = 'root';
|
|
const label = ns['namespace_path'];
|
|
const flattenedNs = flattenDataset(ns);
|
|
// if no mounts, mounts will be an empty array
|
|
flattenedNs.mounts = [];
|
|
if (ns?.mounts && ns.mounts.length > 0) {
|
|
flattenedNs.mounts = ns.mounts.map((mount) => {
|
|
return {
|
|
label: mount['mount_path'],
|
|
...flattenDataset(mount),
|
|
};
|
|
});
|
|
}
|
|
return {
|
|
label,
|
|
...flattenedNs,
|
|
};
|
|
});
|
|
};
|
|
|
|
// In 1.10 'distinct_entities' changed to 'entity_clients' and
|
|
// 'non_entity_tokens' to 'non_entity_clients'
|
|
export const homogenizeClientNaming = (object) => {
|
|
// if new key names exist, only return those key/value pairs
|
|
if (Object.keys(object).includes('entity_clients')) {
|
|
const { clients, entity_clients, non_entity_clients } = object;
|
|
return {
|
|
clients,
|
|
entity_clients,
|
|
non_entity_clients,
|
|
};
|
|
}
|
|
// if object only has outdated key names, update naming
|
|
if (Object.keys(object).includes('distinct_entities')) {
|
|
const { clients, distinct_entities, non_entity_tokens } = object;
|
|
return {
|
|
clients,
|
|
entity_clients: distinct_entities,
|
|
non_entity_clients: non_entity_tokens,
|
|
};
|
|
}
|
|
return object;
|
|
};
|
|
|
|
export const flattenDataset = (object) => {
|
|
if (object?.counts) {
|
|
const flattenedObject = {};
|
|
Object.keys(object['counts']).forEach((key) => (flattenedObject[key] = object['counts'][key]));
|
|
return homogenizeClientNaming(flattenedObject);
|
|
}
|
|
return object;
|
|
};
|
|
|
|
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) => {
|
|
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 { label, clients, entity_clients, non_entity_clients } = 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,
|
|
clients,
|
|
entity_clients,
|
|
non_entity_clients,
|
|
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,
|
|
...mountObject,
|
|
new_clients: { month, ...mountObject.new_clients },
|
|
};
|
|
});
|
|
|
|
const { label, clients, entity_clients, non_entity_clients, new_clients } = namespaceObject;
|
|
namespaces_by_key[label] = {
|
|
month,
|
|
clients,
|
|
entity_clients,
|
|
non_entity_clients,
|
|
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,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
};
|
|
*/
|
|
};
|
|
|
|
/*
|
|
API RESPONSE STRUCTURE:
|
|
data: {
|
|
** by_namespace organized in descending order of client count number **
|
|
by_namespace: [
|
|
{
|
|
namespace_id: '96OwG',
|
|
namespace_path: 'test-ns/',
|
|
counts: {},
|
|
mounts: [{ mount_path: 'path-1', counts: {} }],
|
|
},
|
|
],
|
|
** months organized in ascending order of timestamps, oldest to most recent
|
|
months: [
|
|
{
|
|
timestamp: '2022-03-01T00:00:00Z',
|
|
counts: {},
|
|
namespaces: [
|
|
{
|
|
namespace_id: 'root',
|
|
namespace_path: '',
|
|
counts: {},
|
|
mounts: [{ mount_path: 'auth/up2/', counts: {} }],
|
|
},
|
|
],
|
|
new_clients: {
|
|
counts: {},
|
|
namespaces: [
|
|
{
|
|
namespace_id: 'root',
|
|
namespace_path: '',
|
|
counts: {},
|
|
mounts: [{ mount_path: 'auth/up2/', counts: {} }],
|
|
},
|
|
],
|
|
},
|
|
},
|
|
{
|
|
timestamp: '2022-04-01T00:00:00Z',
|
|
counts: {},
|
|
namespaces: [
|
|
{
|
|
namespace_id: 'root',
|
|
namespace_path: '',
|
|
counts: {},
|
|
mounts: [{ mount_path: 'auth/up2/', counts: {} }],
|
|
},
|
|
],
|
|
new_clients: {
|
|
counts: {},
|
|
namespaces: [
|
|
{
|
|
namespace_id: 'root',
|
|
namespace_path: '',
|
|
counts: {},
|
|
mounts: [{ mount_path: 'auth/up2/', counts: {} }],
|
|
},
|
|
],
|
|
},
|
|
},
|
|
],
|
|
start_time: 'start timestamp string',
|
|
end_time: 'end timestamp string',
|
|
total: { clients: 300, non_entity_clients: 100, entity_clients: 400} ,
|
|
}
|
|
*/
|