Skip to content

Commit ae1fa91

Browse files
Rewrite of startEntitlementAggregation because of sailpoint-oss/typescript-sdk#36. Implementing startAccountAggregation because missing from SDK
1 parent dddf2f7 commit ae1fa91

File tree

4 files changed

+38
-79
lines changed

4 files changed

+38
-79
lines changed

src/commands/source/importAccount.ts

+1-3
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,10 @@ class AccountImporter {
3535

3636
protected async importFile(task: any, token: vscode.CancellationToken): Promise<void> {
3737
console.log("> AccountImporter.importFile");
38-
const source = await this.client.getSourceById(this.sourceId);
3938

4039
let job = await this.client.startAccountAggregation(
41-
this.sourceCCId,
40+
this.sourceId,
4241
false,
43-
source.connectorAttributes["deleteThresholdPercentage"],
4442
this.fileUri.fsPath
4543
);
4644

src/extension.ts

+6-4
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ export function activate(context: vscode.ExtensionContext) {
327327
context.subscriptions.push(
328328
vscode.commands.registerCommand(commands.VALIDATE_CONNECTOR_RULE,
329329
newConnectorRuleCommand.validateScript, newConnectorRuleCommand));
330-
330+
331331
const openScriptCommand = new OpenScriptCommand()
332332
context.subscriptions.push(
333333
vscode.commands.registerCommand(commands.EDIT_CONNECTOR_RULE,
@@ -464,15 +464,17 @@ export function activate(context: vscode.ExtensionContext) {
464464
identityFilterCommand.execute, identityFilterCommand));
465465
context.subscriptions.push(
466466
vscode.commands.registerCommand(commands.IDENTITIES_ATT_SYNC,
467-
newIdentityCommand.attSyncIdentity, newIdentityCommand));
467+
newIdentityCommand.attSyncIdentity, newIdentityCommand));
468468
context.subscriptions.push(
469469
vscode.commands.registerCommand(commands.IDENTITIES_DELETE,
470-
newIdentityCommand.deleteIdentity, newIdentityCommand));
470+
newIdentityCommand.deleteIdentity, newIdentityCommand));
471471
context.subscriptions.push(
472472
vscode.commands.registerCommand(commands.IDENTITIES_PROCESS,
473-
newIdentityCommand.processIdentity, newIdentityCommand));
473+
newIdentityCommand.processIdentity, newIdentityCommand));
474474

475475

476+
// Add global interceptor for axios, to applied with the sailpoint SDK
477+
// Add a request interceptor
476478
axios.interceptors.request.use(onRequest)
477479

478480
// Add a response interceptor

src/services/ISCClient.ts

+15-32
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export const TOTAL_COUNT_HEADER = "x-total-count";
2525
// Content types
2626
const CONTENT_TYPE_JSON = "application/json";
2727
const CONTENT_TYPE_FORM_URLENCODED = "application/x-www-form-urlencoded";
28+
const CONTENT_TYPE_FORM_DATA = "multipart/form-data";
2829
const CONTENT_TYPE_FORM_JSON_PATCH = "application/json-patch+json";
2930

3031

@@ -107,12 +108,6 @@ export class ISCClient {
107108
}
108109

109110
});
110-
instance.interceptors.request.use(
111-
onRequest);
112-
instance.interceptors.response.use(
113-
onResponse,
114-
onErrorResponse
115-
);
116111
return instance;
117112
}
118113

@@ -219,13 +214,23 @@ export class ISCClient {
219214
sourceID: string
220215
): Promise<LoadEntitlementTaskBeta> {
221216
console.log("> ISCClient.startEntitlementAggregation");
217+
/* https://github.com/sailpoint-oss/typescript-sdk/issues/36
222218
const apiConfig = await this.getApiConfiguration();
223219
const api = new EntitlementsBetaApi(apiConfig);
224220
const response = await api.importEntitlements({
225221
id: sourceID,
226222
csvFile: null
227223
})
228224
return response.data
225+
*/
226+
const endpoint = `beta/entitlements/aggregate/sources/${sourceID}`;
227+
console.log("endpoint = " + endpoint);
228+
229+
const formData = new FormData();
230+
231+
const httpClient = await this.getAxios(CONTENT_TYPE_FORM_DATA);
232+
const response = await httpClient.post(endpoint, formData);
233+
return response.data;
229234
}
230235

231236
public async startEntitlementReset(
@@ -253,32 +258,13 @@ export class ISCClient {
253258
}
254259

255260
public async startAccountAggregation(
256-
sourceID: number,
261+
sourceID: string,
257262
disableOptimization = false,
258-
deleteThreshold: number | undefined = undefined,
259263
filePath: string | undefined = undefined
260264
): Promise<any> {
261265
console.log("> ISCClient.startAccountAggregation");
262-
/*
263-
const apiConfig = await this.getApiConfiguration();
264-
const api = new SourcesAggregationCCApi(apiConfig);
265-
let requestParameter: SourcesAggregationCCApiLoadAccountsRequest;
266-
if (disableOptimization) {
267-
requestParameter = {
268-
id: sourceID.toString(),
269-
disableOptimization: disableOptimization
270-
};
271-
} else {
272-
requestParameter = {
273-
id: sourceID.toString()
274-
};
275-
}
276-
const response = await api.loadAccounts(requestParameter);
277-
278-
return response.data;
279-
*/
280266

281-
const endpoint = `cc/api/source/loadAccounts/${sourceID}`;
267+
const endpoint = `beta/sources/${sourceID}/load-accounts`;
282268
console.log("endpoint = " + endpoint);
283269

284270
const formData = new FormData();
@@ -287,18 +273,15 @@ export class ISCClient {
287273
formData.append("disableOptimization", "true");
288274
}
289275

290-
if (deleteThreshold !== undefined) {
291-
formData.append("update-delete-threshold-combobox-inputEl", `${deleteThreshold}%`);
292-
}
293-
294276
if (filePath !== undefined) {
295277
const blob = createReadStream(filePath);
296278
formData.append('file', blob, basename(filePath));
297279
}
298280

299-
const httpClient = await this.getAxios(CONTENT_TYPE_FORM_URLENCODED);
281+
const httpClient = await this.getAxios(CONTENT_TYPE_FORM_DATA);
300282
const response = await httpClient.post(endpoint, formData);
301283
return response.data;
284+
302285
}
303286

304287
public async resetSource(sourceID: number, skip: string | null = null): Promise<any> {

src/services/TreeManager.ts

+16-40
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ export class TreeManager {
121121

122122
const client = new ISCClient(item.tenantId, item.tenantName);
123123

124-
await vscode.window.withProgress({
124+
return await vscode.window.withProgress({
125125
location: vscode.ProgressLocation.Notification,
126126
title: `Resetting accounts from ${item.label}`,
127127
cancellable: true
@@ -134,7 +134,7 @@ export class TreeManager {
134134
"Warning during account reset of {0}: {1}",
135135
"Reset of accounts for {0} failed: {1}: {2}"
136136
)
137-
return undefined;
137+
return task;
138138
});
139139
}
140140

@@ -155,51 +155,27 @@ export class TreeManager {
155155
"Aggregation of entitlements for {0} failed: {1}: {2}"
156156
)
157157
});
158-
159158
}
160159

161-
public async aggregateSource(item: SourceTreeItem, disableOptimization = false, type = "accounts"): Promise<void> {
160+
public async aggregateSource(item: SourceTreeItem, disableOptimization = false): Promise<void> {
162161
console.log("> aggregateSource", item, disableOptimization);
163-
// assessing that item is a SourceTreeItem
164-
if (item === undefined || !(item instanceof SourceTreeItem)) {
165-
console.log("WARNING: aggregateSource: invalid item", item);
166-
throw new Error("aggregateSource: invalid item");
167-
}
162+
168163
const client = new ISCClient(item.tenantId, item.tenantName);
169164
await vscode.window.withProgress({
170165
location: vscode.ProgressLocation.Notification,
171-
title: `Aggregation of ${type} from ${item.label}`,
172-
cancellable: false
166+
title: `Aggregation accounts from ${item.label}`,
167+
cancellable: true
173168
}, async (progress, token) => {
174-
let job: any;
175-
let jobType: AggregationJob;
176-
if ("accounts" === type) {
177-
178-
job = await client.startAccountAggregation(item.ccId, disableOptimization)
179-
.catch(error => {
180-
console.error(error);
181-
});
182-
jobType = AggregationJob.CLOUD_ACCOUNT_AGGREGATION;
183-
}
184-
console.log("job =", job);
185-
let task: any | null = null;
186-
do {
187-
await delay(5000);
188-
task = await client.getAggregationJob(item.ccId, job.task.id, jobType);
189-
console.log("task =", task);
190-
191-
} while (task !== undefined && task.status === "PENDING");
192-
if (task !== undefined) {
193-
if (task.status === "SUCCESS") {
194-
vscode.window.showInformationMessage(`Source ${task.object.displayName} successfully aggregated`);
195-
} else if (task.status === "WARNING") {
196-
vscode.window.showWarningMessage(
197-
`Warning during aggregation of ${task.object.displayName}: ${task.details?.messages?.Warn}`);
198-
} else {
199-
vscode.window.showErrorMessage(
200-
`Aggregation of ${task.object.displayName} failed: ${task.status}: ${task.details?.messages?.Error}`);
201-
}
202-
};
169+
170+
171+
const job = await client.startAccountAggregation(item.id!, disableOptimization)
172+
const task = await this.waifForJob(client, job.task.id, token)
173+
this.formatTask(task,
174+
item.label as string,
175+
"Source {0} successfully aggregated",
176+
"Warning during aggregation of {0}: {1}",
177+
"Aggregation of {0} failed: {1}: {2}"
178+
)
203179
});
204180
}
205181

0 commit comments

Comments
 (0)