This repository has been archived by the owner on Mar 18, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 99
/
PoolFetchImpl.ts
245 lines (214 loc) · 10 KB
/
PoolFetchImpl.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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
import SFPLogger from '@dxatscale/sfp-logger';
import { AuthInfo, LoggerLevel, Org, SfdxError, SfError } from '@salesforce/core';
import { PoolBaseImpl } from './PoolBaseImpl';
import ScratchOrg from '../ScratchOrg';
import { getUserEmail } from './services/fetchers/GetUserEmail';
import ScratchOrgInfoFetcher from './services/fetchers/ScratchOrgInfoFetcher';
import ScratchOrgInfoAssigner from './services/updaters/ScratchOrgInfoAssigner';
import * as fs from 'fs-extra';
import ClientSourceTracking from './ClientSourceTracking';
import isValidSfdxAuthUrl from './prequisitecheck/IsValidSfdxAuthUrl';
import ScratchOrgOperator from '../ScratchOrgOperator';
export default class PoolFetchImpl extends PoolBaseImpl {
private tag: string;
private mypool: boolean;
private sendToUser: string;
private alias: string;
private setdefaultusername: boolean;
private authURLEnabledScratchOrg: boolean;
private isSourceTrackingToBeSet: boolean = false;
public constructor(
hubOrg: Org,
tag: string,
mypool: boolean,
authURLEnabledScratchOrg: boolean,
sendToUser?: string,
alias?: string,
setdefaultusername?: boolean,
private fetchAllScratchOrgs?: boolean,
private limitBy?:number
) {
super(hubOrg);
this.tag = tag;
this.mypool = mypool;
this.authURLEnabledScratchOrg = authURLEnabledScratchOrg;
this.sendToUser = sendToUser;
this.alias = alias;
this.setdefaultusername = setdefaultusername;
}
public setSourceTrackingOnFetch() {
this.isSourceTrackingToBeSet = true;
}
protected async onExec(): Promise<ScratchOrg | ScratchOrg[]> {
const results = (await new ScratchOrgInfoFetcher(this.hubOrg).getScratchOrgsByTag(
this.tag,
this.mypool,
true
)) as any;
let availableSo = [];
if (results.records.length > 0) {
availableSo = results.records.filter((soInfo) => soInfo.Allocation_status__c === 'Available');
}
if (availableSo.length == 0) {
throw new SfError(`No scratch org available at the moment for ${this.tag}, try again in sometime.`);
}
if (this.fetchAllScratchOrgs) {
return this.fetchAllScratchOrg(availableSo,this.limitBy);
} else return this.fetchSingleScratchOrg(availableSo);
}
private async fetchAllScratchOrg(availableSo: any[],limitBy?:number): Promise<ScratchOrg[]> {
let fetchedSOs: ScratchOrg[] = [];
if (availableSo.length > 0) {
SFPLogger.log(`${this.tag} pool has ${availableSo.length} Scratch orgs available`, LoggerLevel.TRACE);
let count = 1;
for (let element of availableSo) {
if (this.authURLEnabledScratchOrg) {
if (element.SfdxAuthUrl__c && !isValidSfdxAuthUrl(element.SfdxAuthUrl__c)) {
SFPLogger.log(
`Iterating through pool to find a scratch org with valid authURL`,
LoggerLevel.TRACE
);
continue;
}
}
SFPLogger.log(
`Scratch org ${element.SignupUsername} is allocated from the pool. Expiry date is ${element.ExpirationDate}`,
LoggerLevel.TRACE
);
let soDetail: any = {};
soDetail['Id'] = element.Id;
soDetail.orgId = element.ScratchOrg;
soDetail.loginURL = element.LoginUrl;
soDetail.username = element.SignupUsername;
soDetail.password = element.Password__c;
soDetail.expiryDate = element.ExpirationDate;
soDetail.sfdxAuthUrl = element.SfdxAuthUrl__c;
soDetail.status = 'Available';
soDetail.alias = `SO` + count;
fetchedSOs.push(soDetail);
if(limitBy && count==limitBy)
break;
count++;
}
}
for (const soDetail of fetchedSOs) {
//Login to the org
let isLoginSuccessFull = await this.loginToScratchOrgIfSfdxAuthURLExists(soDetail);
if (!isLoginSuccessFull) {
SFPLogger.log(`Unable to login to scratchorg ${soDetail.username}}`, LoggerLevel.ERROR);
fetchedSOs = fetchedSOs.filter((item) => item.username !== soDetail.username);
}
}
return fetchedSOs;
}
private async fetchSingleScratchOrg(availableSo: any[]): Promise<ScratchOrg> {
let soDetail: ScratchOrg;
if (availableSo.length > 0) {
SFPLogger.log(`${this.tag} pool has ${availableSo.length} Scratch orgs available`, LoggerLevel.TRACE);
for (let element of availableSo) {
if (this.authURLEnabledScratchOrg) {
if (element.SfdxAuthUrl__c && !isValidSfdxAuthUrl(element.SfdxAuthUrl__c)) {
SFPLogger.log(
`Iterating through pool to find a scratch org with valid authURL`,
LoggerLevel.TRACE
);
continue;
}
}
let allocateSO = await new ScratchOrgInfoAssigner(this.hubOrg).setScratchOrgInfo({
Id: element.Id,
Allocation_status__c: 'Allocate',
});
if (allocateSO === true) {
SFPLogger.log(
`Scratch org ${element.SignupUsername} is allocated from the pool. Expiry date is ${element.ExpirationDate}`,
LoggerLevel.TRACE
);
soDetail = {};
soDetail['Id'] = element.Id;
soDetail.orgId = element.ScratchOrg;
soDetail.loginURL = element.LoginUrl;
soDetail.username = element.SignupUsername;
soDetail.password = element.Password__c;
soDetail.expiryDate = element.ExpirationDate;
soDetail.sfdxAuthUrl = element.SfdxAuthUrl__c;
soDetail.status = 'Assigned';
break;
} else {
SFPLogger.log(
`Scratch org ${element.SignupUsername} allocation failed. trying to get another Scratch org from ${this.tag} pool`,
LoggerLevel.TRACE
);
}
}
}
if (availableSo.length == 0 || !soDetail) {
throw new SfdxError(`No scratch org available at the moment for ${this.tag}, try again in sometime.`);
}
if (this.sendToUser) {
//Fetch the email for user id
let emailId;
try {
emailId = await getUserEmail(this.sendToUser, this.hubOrg);
} catch (error) {
SFPLogger.log(
'Unable to fetch details of the specified user, Check whether the user exists in the org ',
LoggerLevel.ERROR
);
throw new SfdxError('Failed to fetch user details');
}
try {
//Send an email for username
await new ScratchOrgOperator(this.hubOrg).shareScratchOrgThroughEmail(emailId, soDetail);
} catch (error) {
SFPLogger.log(
'Unable to send the scratchorg details to specified user. Check whether the user exists in the org',
LoggerLevel.ERROR
);
throw new SfdxError(
'Unable to send the scratchorg details to specified user. Check whether the user exists in the org'
);
}
} else {
//Login to the org
let isLoginSuccessFull = await this.loginToScratchOrgIfSfdxAuthURLExists(soDetail);
//Attempt to Fetch Source Tracking Files and silently continue if it fails
if (isLoginSuccessFull && this.isSourceTrackingToBeSet) {
try {
const conn = (await Org.create({ aliasOrUsername: soDetail.username })).getConnection();
const clientSourceTracking = await ClientSourceTracking.create(conn, null);
await clientSourceTracking.creatSourceTrackingFiles();
} catch (error) {
SFPLogger.log('Retriveing Source Tracking skipped.. ' + error.message, LoggerLevel.TRACE);
}
}
}
return soDetail;
}
private async loginToScratchOrgIfSfdxAuthURLExists(soDetail: ScratchOrg): Promise<boolean> {
try {
if (soDetail.sfdxAuthUrl && isValidSfdxAuthUrl(soDetail.sfdxAuthUrl)) {
const oauth2Options = AuthInfo.parseSfdxAuthUrl(soDetail.sfdxAuthUrl);
const authInfo = await AuthInfo.create({ oauth2Options });
await authInfo.save();
await authInfo.handleAliasAndDefaultSettings({
alias: this.alias?this.alias:soDetail.alias,
setDefault: true,
setDefaultDevHub: false,
});
const result = authInfo.getFields(true);
// ensure the clientSecret field... even if it is empty
// as per https://github.com/salesforcecli/plugin-auth/blob/main/src/commands/auth/sfdxurl/store.ts
result.clientSecret = result.clientSecret ?? '';
await AuthInfo.identifyPossibleScratchOrgs(result, authInfo);
return true;
} else {
SFPLogger.log('Unable to autenticate to the scratch org', LoggerLevel.INFO);
return false;
}
} catch (error) {
SFPLogger.log('Unable to autenticate to the scratch org due ' + error.message, LoggerLevel.ERROR);
return false;
}
}
}