clever-tools 4.1.0 → 4.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/models/ng.js CHANGED
@@ -9,17 +9,20 @@ import crypto from 'node:crypto';
9
9
  import { searchNetworkGroupOrResource } from '../clever-client/ng.js';
10
10
  import { styleText } from '../lib/style-text.js';
11
11
  import { Logger } from '../logger.js';
12
+ import { getOwnerIdFromOrgIdOrName } from './ids-resolver.js';
12
13
  import { checkMembersToLink } from './ng-resources.js';
13
- import * as Organisation from './organisation.js';
14
14
  import { sendToApi } from './send-to-api.js';
15
- import * as User from './user.js';
16
15
 
17
16
  export const POLLING_TIMEOUT_MS = 30_000;
18
17
  export const POLLING_INTERVAL_MS = 1000;
19
18
  export const DOMAIN = 'cc-ng.cloud';
20
- const TYPE_PREFIXES = {
19
+ export const NG_MEMBER_PREFIXES = {
21
20
  app_: 'APPLICATION',
22
- addon_: 'ADDON',
21
+ elasticsearch_: 'ADDON',
22
+ mongodb_: 'ADDON',
23
+ mysql_: 'ADDON',
24
+ postgresql_: 'ADDON',
25
+ redis_: 'ADDON',
23
26
  external_: 'EXTERNAL',
24
27
  };
25
28
 
@@ -34,10 +37,10 @@ const TYPE_PREFIXES = {
34
37
  */
35
38
  export async function create(label, description, tags, membersIds, orgaIdOrName) {
36
39
  const id = `ng_${crypto.randomUUID()}`;
37
- const ownerId = await getOwnerIdFromOrgaIdOrName(orgaIdOrName);
40
+ const ownerId = await getOwnerIdFromOrgIdOrName(orgaIdOrName);
38
41
 
39
42
  if (membersIds?.length > 0) {
40
- await checkMembersToLink(membersIds, ownerId);
43
+ checkMembersToLink(membersIds);
41
44
  }
42
45
 
43
46
  const members = constructMembers(id, membersIds || []);
@@ -72,11 +75,11 @@ export async function destroy(ngIdOrLabel, orgaIdOrName) {
72
75
  }
73
76
 
74
77
  /**
75
- * Get the Wireguard configuration of a Network Group peer
78
+ * Get the WireGuard configuration of a Network Group peer
76
79
  * @param {object} peerIdOrLabel The Peer ID or Label
77
80
  * @param {object} ngIdOrLabel The Network Group ID or Label
78
81
  * @param {object} orgaIdOrName The owner ID or name
79
- * @returns {Promise<Object>} The Peer Wireguard configuration
82
+ * @returns {Promise<Object>} The Peer WireGuard configuration
80
83
  * @throws {Error} If the Peer is not found
81
84
  * @throws {Error} If the Network Group is not found
82
85
  * @throws {Error} If the Peer is not in the Network Group
@@ -116,13 +119,13 @@ export async function getPeerConfig(peerIdOrLabel, ngIdOrLabel, orgaIdOrName) {
116
119
  }
117
120
 
118
121
  /**
119
- * Get a Network group from an owner with members and peers
122
+ * Get a Network Group from an owner with members and peers
120
123
  * @param {string} networkGroupId The Network Group ID
121
124
  * @param {string} orgaIdOrName The owner ID or name
122
125
  * @returns {Promise<Array<Object>>} The Network Groups
123
126
  */
124
127
  export async function getNG(networkGroupId, orgaIdOrName) {
125
- const ownerId = await getOwnerIdFromOrgaIdOrName(orgaIdOrName);
128
+ const ownerId = await getOwnerIdFromOrgIdOrName(orgaIdOrName);
126
129
 
127
130
  Logger.info(`Get Network Group ${networkGroupId} for owner ${ownerId}`);
128
131
  const result = await getNetworkGroup({ networkGroupId, ownerId }).then(sendToApi);
@@ -137,7 +140,7 @@ export async function getNG(networkGroupId, orgaIdOrName) {
137
140
  * @returns {Promise<Array<Object>>} The Network Groups
138
141
  */
139
142
  export async function getAllNGs(orgaIdOrName) {
140
- const ownerId = await getOwnerIdFromOrgaIdOrName(orgaIdOrName);
143
+ const ownerId = await getOwnerIdFromOrgIdOrName(orgaIdOrName);
141
144
 
142
145
  Logger.info(`Listing Network Groups from owner ${ownerId}`);
143
146
  const result = await listNetworkGroups({ ownerId }).then(sendToApi);
@@ -155,7 +158,7 @@ export async function getAllNGs(orgaIdOrName) {
155
158
  * @returns {Promise<Object>} Found results
156
159
  */
157
160
  export async function searchNgOrResource(idOrLabel, orgaIdOrName, type = 'all', exactMatch = true) {
158
- const ownerId = await getOwnerIdFromOrgaIdOrName(orgaIdOrName);
161
+ const ownerId = await getOwnerIdFromOrgIdOrName(orgaIdOrName);
159
162
 
160
163
  // If idOrLabel is a string we use it, or we look through multiple keys
161
164
  const query =
@@ -187,7 +190,7 @@ export async function searchNgOrResource(idOrLabel, orgaIdOrName, type = 'all',
187
190
 
188
191
  if (filtered.length > 1 && type !== 'all') {
189
192
  throw new Error(`Multiple resources found for ${styleText('red', query)}, use ID instead:
190
- ${filtered.map((f) => ` • ${f.id} ${styleText('grey', `(${f.label} - ${f.type})`)}`).join('\n')}`);
193
+ ${filtered.map((f) => ` • ${f.id} ${styleText('grey', `(${f.domainName || f.label} - ${f.type})`)}`).join('\n')}`);
191
194
  }
192
195
 
193
196
  // Deduplicate results
@@ -203,14 +206,9 @@ ${filtered.map((f) => ` • ${f.id} ${styleText('grey', `(${f.label} - ${f.type}
203
206
  export function constructMembers(ngId, membersIds) {
204
207
  return membersIds.map((id) => {
205
208
  const domainName = `${id}.m.${ngId}.${DOMAIN}`;
206
- const prefixToType = TYPE_PREFIXES;
207
-
208
- return {
209
- id,
210
- domainName,
211
- // Get kind from prefix match in id (app_*, addon_*, external_*) or default to 'APPLICATION'
212
- kind: prefixToType[Object.keys(prefixToType).find((p) => id.startsWith(p))] ?? TYPE_PREFIXES.app_,
213
- };
209
+ const prefix = Object.keys(NG_MEMBER_PREFIXES).find((p) => id.startsWith(p));
210
+ const kind = NG_MEMBER_PREFIXES[prefix];
211
+ return { id, domainName, kind };
214
212
  });
215
213
  }
216
214
 
@@ -266,12 +264,3 @@ async function pollNetworkGroup(ownerId, ngId, { waitForMembers = null, waitForD
266
264
  pollOnce();
267
265
  });
268
266
  }
269
-
270
- /**
271
- * Get the owner ID from an Organisation ID or name
272
- * @param {object} orgaIdOrName The Organisation ID or name
273
- * @returns {Promise<string>} The owner ID
274
- */
275
- async function getOwnerIdFromOrgaIdOrName(orgaIdOrName) {
276
- return orgaIdOrName != null ? Organisation.getId(orgaIdOrName) : User.getCurrentId();
277
- }
package/src/parsers.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import cliparse from 'cliparse';
2
2
  import ISO8601 from 'iso8601-duration';
3
3
  import * as Application from './models/application.js';
4
+ import { NG_MEMBER_PREFIXES } from './models/ng.js';
4
5
 
5
6
  const addonOptionsRegex = /^[\w-]+=.+$/;
6
7
 
@@ -99,12 +100,13 @@ export function orgaIdOrName(string) {
99
100
  const addonIdRegex = /^addon_[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
100
101
  const operatorIdRegex =
101
102
  /^(keycloak|otoroshi|matomo|metabase)_[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
103
+ const ulidRegex = /^(kubernetes)_[0-9A-HJ-NP-TV-Z]{26}$/i;
102
104
 
103
105
  export function addonIdOrName(string) {
104
106
  if (string.match(addonIdRegex)) {
105
107
  return cliparse.parsers.success({ addon_id: string });
106
108
  }
107
- if (string.match(operatorIdRegex)) {
109
+ if (string.match(operatorIdRegex) || string.match(ulidRegex)) {
108
110
  return cliparse.parsers.success({ operator_id: string });
109
111
  }
110
112
  return cliparse.parsers.success({ addon_name: string });
@@ -225,12 +227,12 @@ function parseSimpleDuration(durationStr) {
225
227
  }
226
228
  }
227
229
 
228
- // Network groups parsers
230
+ // Network Groups parsers
229
231
  export function ngResourceType(string) {
230
232
  if (string.startsWith('ng_')) {
231
233
  return cliparse.parsers.success({ ngId: string });
232
234
  }
233
- if (string.startsWith('app_') || string.startsWith('addon_') || string.startsWith('external_')) {
235
+ if (Object.keys(NG_MEMBER_PREFIXES).some((prefix) => string.startsWith(prefix))) {
234
236
  return cliparse.parsers.success({ memberId: string });
235
237
  }
236
238
  return cliparse.parsers.success({ ngResourceLabel: string });