cumulusci-plus 5.0.17__py3-none-any.whl → 5.0.19__py3-none-any.whl
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.
- cumulusci/__about__.py +1 -1
- cumulusci/core/dependencies/base.py +77 -33
- cumulusci/core/dependencies/dependencies.py +27 -17
- cumulusci/core/dependencies/tests/test_dependencies.py +12 -6
- cumulusci/core/dependencies/tests/test_resolvers.py +61 -27
- cumulusci/cumulusci.yml +12 -0
- cumulusci/tasks/salesforce/SfDataCommands.py +400 -0
- cumulusci/tasks/salesforce/profiles.py +36 -7
- cumulusci/tasks/salesforce/tests/test_SfDataCommands.py +363 -0
- cumulusci/tasks/salesforce/tests/test_profiles.py +125 -1
- cumulusci/tasks/salesforce/tests/test_update_dependencies.py +1 -1
- cumulusci/tasks/salesforce/update_dependencies.py +9 -3
- cumulusci/tasks/utility/env_management.py +2 -6
- {cumulusci_plus-5.0.17.dist-info → cumulusci_plus-5.0.19.dist-info}/METADATA +4 -4
- {cumulusci_plus-5.0.17.dist-info → cumulusci_plus-5.0.19.dist-info}/RECORD +19 -17
- {cumulusci_plus-5.0.17.dist-info → cumulusci_plus-5.0.19.dist-info}/WHEEL +0 -0
- {cumulusci_plus-5.0.17.dist-info → cumulusci_plus-5.0.19.dist-info}/entry_points.txt +0 -0
- {cumulusci_plus-5.0.17.dist-info → cumulusci_plus-5.0.19.dist-info}/licenses/AUTHORS.rst +0 -0
- {cumulusci_plus-5.0.17.dist-info → cumulusci_plus-5.0.19.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
import json
|
|
2
|
+
|
|
3
|
+
import sarge
|
|
4
|
+
|
|
5
|
+
from cumulusci.core.exceptions import SalesforceDXException
|
|
6
|
+
from cumulusci.core.sfdx import sfdx
|
|
7
|
+
from cumulusci.tasks.salesforce import BaseSalesforceApiTask
|
|
8
|
+
from cumulusci.utils.options import CCIOptions, Field
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class SfDataCommands(BaseSalesforceApiTask):
|
|
12
|
+
class Options(CCIOptions):
|
|
13
|
+
json_output: bool = Field(
|
|
14
|
+
None, description="Whether to return the result as a JSON object"
|
|
15
|
+
)
|
|
16
|
+
api_version: str = Field(None, description="API version to use for the command")
|
|
17
|
+
flags_dir: str = Field(None, description="Import flag values from a directory")
|
|
18
|
+
|
|
19
|
+
parsed_options: Options
|
|
20
|
+
|
|
21
|
+
def _init_task(self):
|
|
22
|
+
super()._init_task()
|
|
23
|
+
|
|
24
|
+
def _init_options(self, kwargs):
|
|
25
|
+
self.args = []
|
|
26
|
+
self.data_command = "data "
|
|
27
|
+
super()._init_options(kwargs)
|
|
28
|
+
if self.parsed_options.flags_dir:
|
|
29
|
+
self.args.extend(["--flags-dir ", self.parsed_options.flags_dir])
|
|
30
|
+
if self.parsed_options.json_output:
|
|
31
|
+
self.args.extend(["--json"])
|
|
32
|
+
if self.parsed_options.api_version:
|
|
33
|
+
self.args.extend(["--api_version", self.parsed_options.api_version])
|
|
34
|
+
|
|
35
|
+
def _run_task(self):
|
|
36
|
+
self.return_values = {}
|
|
37
|
+
|
|
38
|
+
self.p: sarge.Command = sfdx(
|
|
39
|
+
self.data_command,
|
|
40
|
+
log_note="Running data command",
|
|
41
|
+
args=self.args,
|
|
42
|
+
check_return=True,
|
|
43
|
+
username=self.org_config.username,
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
if self.parsed_options.json_output:
|
|
47
|
+
self.return_values = self._load_json_output(self.p)
|
|
48
|
+
|
|
49
|
+
for line in self.p.stdout_text:
|
|
50
|
+
self.logger.info(line)
|
|
51
|
+
|
|
52
|
+
for line in self.p.stderr_text:
|
|
53
|
+
self.logger.error(line)
|
|
54
|
+
|
|
55
|
+
def _load_json_output(self, p: sarge.Command, stdout: str = None):
|
|
56
|
+
try:
|
|
57
|
+
stdout = stdout or p.stdout_text.read()
|
|
58
|
+
return json.loads(stdout)
|
|
59
|
+
except json.decoder.JSONDecodeError:
|
|
60
|
+
raise SalesforceDXException(
|
|
61
|
+
f"Failed to parse the output of the {self.data_command} command"
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class SfDataToolingAPISupportedCommands(SfDataCommands):
|
|
66
|
+
class Options(SfDataCommands.Options):
|
|
67
|
+
use_tooling_api: bool = Field(
|
|
68
|
+
None,
|
|
69
|
+
description="Use Tooling API so you can run queries on Tooling API objects.",
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class DataQueryTask(SfDataToolingAPISupportedCommands):
|
|
74
|
+
class Options(SfDataToolingAPISupportedCommands.Options):
|
|
75
|
+
query: str = Field(None, description="SOQL query to execute")
|
|
76
|
+
file: str = Field(None, description="File that contains the SOQL query")
|
|
77
|
+
all_rows: bool = Field(
|
|
78
|
+
None,
|
|
79
|
+
description="Include deleted records. By default, deleted records are not returned.",
|
|
80
|
+
)
|
|
81
|
+
result_format: str = Field(
|
|
82
|
+
None,
|
|
83
|
+
description="Format to display the results; the --json_output flag overrides this flag. Permissible values are: human, csv, json.",
|
|
84
|
+
)
|
|
85
|
+
output_file: str = Field(
|
|
86
|
+
None,
|
|
87
|
+
description="File where records are written; only CSV and JSON output formats are supported.",
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
def _init_task(self):
|
|
91
|
+
super()._init_task()
|
|
92
|
+
self.data_command += "query"
|
|
93
|
+
|
|
94
|
+
def _init_options(self, kwargs):
|
|
95
|
+
super()._init_options(kwargs)
|
|
96
|
+
if self.parsed_options.query:
|
|
97
|
+
self.args.extend(["--query", self.parsed_options.query])
|
|
98
|
+
if self.parsed_options.file:
|
|
99
|
+
self.args.extend(["--file", self.parsed_options.file])
|
|
100
|
+
if self.parsed_options.all_rows:
|
|
101
|
+
self.args.extend(["--all-rows", self.parsed_options.all_rows])
|
|
102
|
+
if self.parsed_options.result_format:
|
|
103
|
+
self.args.extend(["--result-format", self.parsed_options.result_format])
|
|
104
|
+
if self.parsed_options.output_file:
|
|
105
|
+
self.args.extend(["--output-file", self.parsed_options.output_file])
|
|
106
|
+
|
|
107
|
+
def _run_task(self):
|
|
108
|
+
super()._run_task()
|
|
109
|
+
|
|
110
|
+
if self.parsed_options.json_output:
|
|
111
|
+
self.logger.info(self.return_values)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
class DataCreateRecordTask(SfDataToolingAPISupportedCommands):
|
|
115
|
+
class Options(SfDataToolingAPISupportedCommands.Options):
|
|
116
|
+
sobject: str = Field(
|
|
117
|
+
...,
|
|
118
|
+
description="API name of the Salesforce or Tooling API object that you're inserting a record into.",
|
|
119
|
+
)
|
|
120
|
+
values: str = Field(
|
|
121
|
+
...,
|
|
122
|
+
description="Values for the flags in the form <fieldName>=<value>, separate multiple pairs with spaces.",
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
def _init_task(self):
|
|
126
|
+
super()._init_task()
|
|
127
|
+
self.data_command += "create record"
|
|
128
|
+
|
|
129
|
+
def _init_options(self, kwargs):
|
|
130
|
+
super()._init_options(kwargs)
|
|
131
|
+
if self.options.get("sobject"):
|
|
132
|
+
self.args.extend(["--sobject", self.options.get("sobject")])
|
|
133
|
+
if self.options.get("values"):
|
|
134
|
+
self.args.extend(["--values", self.options.get("values")])
|
|
135
|
+
|
|
136
|
+
def _run_task(self):
|
|
137
|
+
return super()._run_task()
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
class DataDeleteRecordTask(SfDataToolingAPISupportedCommands):
|
|
141
|
+
class Options(SfDataToolingAPISupportedCommands.Options):
|
|
142
|
+
sobject: str = Field(
|
|
143
|
+
...,
|
|
144
|
+
description="API name of the Salesforce or Tooling API object that you're deleting a record from.",
|
|
145
|
+
)
|
|
146
|
+
record_id: str = Field(None, description="ID of the record you’re deleting.")
|
|
147
|
+
where: str = Field(
|
|
148
|
+
None,
|
|
149
|
+
description="List of <fieldName>=<value> pairs that identify the record you want to delete.",
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
def _init_task(self):
|
|
153
|
+
super()._init_task()
|
|
154
|
+
self.data_command += "delete record"
|
|
155
|
+
|
|
156
|
+
def _init_options(self, kwargs):
|
|
157
|
+
super()._init_options(kwargs)
|
|
158
|
+
if self.options.get("sobject"):
|
|
159
|
+
self.args.extend(["--sobject", self.options.get("sobject")])
|
|
160
|
+
if self.options.get("record_id"):
|
|
161
|
+
self.args.extend(["--record-id", self.options.get("record_id")])
|
|
162
|
+
if self.options.get("where"):
|
|
163
|
+
self.args.extend(["--where", self.options.get("where")])
|
|
164
|
+
|
|
165
|
+
def _run_task(self):
|
|
166
|
+
return super()._run_task()
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
class DataUpdateRecordTask(SfDataToolingAPISupportedCommands):
|
|
170
|
+
class Options(SfDataToolingAPISupportedCommands.Options):
|
|
171
|
+
sobject: str = Field(
|
|
172
|
+
...,
|
|
173
|
+
description="API name of the Salesforce or Tooling API object that you're updating a record from.",
|
|
174
|
+
)
|
|
175
|
+
record_id: str = Field(None, description="ID of the record you’re updating.")
|
|
176
|
+
where: str = Field(
|
|
177
|
+
None,
|
|
178
|
+
description="List of <fieldName>=<value> pairs that identify the record you want to update.",
|
|
179
|
+
)
|
|
180
|
+
values: str = Field(
|
|
181
|
+
...,
|
|
182
|
+
description="Values for the flags in the form <fieldName>=<value>, separate multiple pairs with spaces.",
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
def _init_task(self):
|
|
186
|
+
super()._init_task()
|
|
187
|
+
self.data_command += "update record"
|
|
188
|
+
|
|
189
|
+
def _init_options(self, kwargs):
|
|
190
|
+
super()._init_options(kwargs)
|
|
191
|
+
if self.parsed_options.sobject:
|
|
192
|
+
self.args.extend(["--sobject", self.parsed_options.sobject])
|
|
193
|
+
if self.parsed_options.record_id:
|
|
194
|
+
self.args.extend(["--record-id", self.parsed_options.record_id])
|
|
195
|
+
if self.parsed_options.where:
|
|
196
|
+
self.args.extend(["--where", self.parsed_options.where])
|
|
197
|
+
if self.parsed_options.values:
|
|
198
|
+
self.args.extend(["--values", self.parsed_options.values])
|
|
199
|
+
|
|
200
|
+
def _run_task(self):
|
|
201
|
+
return super()._run_task()
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
class DataGetRecordTask(SfDataToolingAPISupportedCommands):
|
|
205
|
+
class Options(SfDataToolingAPISupportedCommands.Options):
|
|
206
|
+
sobject: str = Field(
|
|
207
|
+
...,
|
|
208
|
+
description="API name of the Salesforce or Tooling API object that you're fetching a record from.",
|
|
209
|
+
)
|
|
210
|
+
record_id: str = Field(None, description="ID of the record you’re fetching.")
|
|
211
|
+
where: str = Field(
|
|
212
|
+
None,
|
|
213
|
+
description="List of <fieldName>=<value> pairs that identify the record you want to fetch.",
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
def _init_task(self):
|
|
217
|
+
super()._init_task()
|
|
218
|
+
self.data_command += "get record"
|
|
219
|
+
|
|
220
|
+
def _init_options(self, kwargs):
|
|
221
|
+
super()._init_options(kwargs)
|
|
222
|
+
if self.parsed_options.sobject:
|
|
223
|
+
self.args.extend(["--sobject", self.parsed_options.sobject])
|
|
224
|
+
if self.parsed_options.record_id:
|
|
225
|
+
self.args.extend(["--record-id", self.parsed_options.record_id])
|
|
226
|
+
if self.parsed_options.where:
|
|
227
|
+
self.args.extend(["--where", self.parsed_options.where])
|
|
228
|
+
|
|
229
|
+
def _run_task(self):
|
|
230
|
+
return super()._run_task()
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
class DataQueryResumeTask(SfDataToolingAPISupportedCommands):
|
|
234
|
+
class Options(SfDataToolingAPISupportedCommands.Options):
|
|
235
|
+
bulk_query_id: str = Field(
|
|
236
|
+
...,
|
|
237
|
+
description="The 18-character ID of the bulk query to resume.",
|
|
238
|
+
)
|
|
239
|
+
result_format: str = Field(
|
|
240
|
+
None,
|
|
241
|
+
description="Format to display the results; the --json_output flag overrides this flag. Permissible values are: human, csv, json.",
|
|
242
|
+
)
|
|
243
|
+
|
|
244
|
+
def _init_task(self):
|
|
245
|
+
super()._init_task()
|
|
246
|
+
self.data_command += "query resume"
|
|
247
|
+
|
|
248
|
+
def _init_options(self, kwargs):
|
|
249
|
+
super()._init_options(kwargs)
|
|
250
|
+
if self.parsed_options.bulk_query_id:
|
|
251
|
+
self.args.extend(["--bulk-query-id", self.parsed_options.bulk_query_id])
|
|
252
|
+
if self.parsed_options.result_format:
|
|
253
|
+
self.args.extend(["--result-format", self.parsed_options.result_format])
|
|
254
|
+
|
|
255
|
+
def _run_task(self):
|
|
256
|
+
return super()._run_task()
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
class DataDeleteBulkTask(SfDataCommands):
|
|
260
|
+
class Options(SfDataCommands.Options):
|
|
261
|
+
sobject: str = Field(
|
|
262
|
+
...,
|
|
263
|
+
description="The API name of the object for the bulk job.",
|
|
264
|
+
)
|
|
265
|
+
file: str = Field(
|
|
266
|
+
...,
|
|
267
|
+
description="The path to the CSV file that contains the IDs of the records to delete.",
|
|
268
|
+
)
|
|
269
|
+
wait: int = Field(
|
|
270
|
+
None,
|
|
271
|
+
description="The number of minutes to wait for the command to complete.",
|
|
272
|
+
)
|
|
273
|
+
|
|
274
|
+
def _init_task(self):
|
|
275
|
+
super()._init_task()
|
|
276
|
+
self.data_command += "delete bulk"
|
|
277
|
+
|
|
278
|
+
def _init_options(self, kwargs):
|
|
279
|
+
super()._init_options(kwargs)
|
|
280
|
+
if self.parsed_options.sobject:
|
|
281
|
+
self.args.extend(["--sobject", self.parsed_options.sobject])
|
|
282
|
+
if self.parsed_options.file:
|
|
283
|
+
self.args.extend(["--file", self.parsed_options.file])
|
|
284
|
+
if self.parsed_options.wait:
|
|
285
|
+
self.args.extend(["--wait", str(self.parsed_options.wait)])
|
|
286
|
+
|
|
287
|
+
def _run_task(self):
|
|
288
|
+
return super()._run_task()
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
class DataUpsertBulkTask(SfDataCommands):
|
|
292
|
+
class Options(SfDataCommands.Options):
|
|
293
|
+
sobject: str = Field(
|
|
294
|
+
...,
|
|
295
|
+
description="The API name of the object for the bulk job.",
|
|
296
|
+
)
|
|
297
|
+
file: str = Field(
|
|
298
|
+
...,
|
|
299
|
+
description="The path to the CSV file that contains the records to upsert.",
|
|
300
|
+
)
|
|
301
|
+
external_id_field: str = Field(
|
|
302
|
+
...,
|
|
303
|
+
description="The API name of the external ID field for the upsert.",
|
|
304
|
+
)
|
|
305
|
+
wait: int = Field(
|
|
306
|
+
None,
|
|
307
|
+
description="The number of minutes to wait for the command to complete.",
|
|
308
|
+
)
|
|
309
|
+
|
|
310
|
+
def _init_task(self):
|
|
311
|
+
super()._init_task()
|
|
312
|
+
self.data_command += "upsert bulk"
|
|
313
|
+
|
|
314
|
+
def _init_options(self, kwargs):
|
|
315
|
+
super()._init_options(kwargs)
|
|
316
|
+
if self.parsed_options.sobject:
|
|
317
|
+
self.args.extend(["--sobject", self.parsed_options.sobject])
|
|
318
|
+
if self.parsed_options.file:
|
|
319
|
+
self.args.extend(["--file", self.parsed_options.file])
|
|
320
|
+
if self.parsed_options.external_id_field:
|
|
321
|
+
self.args.extend(
|
|
322
|
+
["--external-id-field", self.parsed_options.external_id_field]
|
|
323
|
+
)
|
|
324
|
+
if self.parsed_options.wait:
|
|
325
|
+
self.args.extend(["--wait", str(self.parsed_options.wait)])
|
|
326
|
+
|
|
327
|
+
def _run_task(self):
|
|
328
|
+
return super()._run_task()
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
class DataImportTreeTask(SfDataCommands):
|
|
332
|
+
class Options(SfDataCommands.Options):
|
|
333
|
+
files: list = Field(
|
|
334
|
+
None,
|
|
335
|
+
description="A list of paths to sObject Tree API plan definition files.",
|
|
336
|
+
)
|
|
337
|
+
plan: str = Field(
|
|
338
|
+
None,
|
|
339
|
+
description="The path to a plan definition file.",
|
|
340
|
+
)
|
|
341
|
+
content_type_map: str = Field(
|
|
342
|
+
None,
|
|
343
|
+
description="A mapping of file extensions to content types.",
|
|
344
|
+
)
|
|
345
|
+
|
|
346
|
+
def _init_task(self):
|
|
347
|
+
super()._init_task()
|
|
348
|
+
self.data_command += "import tree"
|
|
349
|
+
|
|
350
|
+
def _init_options(self, kwargs):
|
|
351
|
+
super()._init_options(kwargs)
|
|
352
|
+
if self.parsed_options.files:
|
|
353
|
+
self.args.extend(["--files", ",".join(self.parsed_options.files)])
|
|
354
|
+
if self.parsed_options.plan:
|
|
355
|
+
self.args.extend(["--plan", self.parsed_options.plan])
|
|
356
|
+
if self.parsed_options.content_type_map:
|
|
357
|
+
self.args.extend(
|
|
358
|
+
["--content-type-map", self.parsed_options.content_type_map]
|
|
359
|
+
)
|
|
360
|
+
|
|
361
|
+
def _run_task(self):
|
|
362
|
+
return super()._run_task()
|
|
363
|
+
|
|
364
|
+
|
|
365
|
+
class DataExportTreeTask(SfDataCommands):
|
|
366
|
+
class Options(SfDataCommands.Options):
|
|
367
|
+
query: str = Field(
|
|
368
|
+
...,
|
|
369
|
+
description="A SOQL query that retrieves the records you want to export.",
|
|
370
|
+
)
|
|
371
|
+
plan: bool = Field(
|
|
372
|
+
False,
|
|
373
|
+
description="Generate a plan definition file.",
|
|
374
|
+
)
|
|
375
|
+
prefix: str = Field(
|
|
376
|
+
None,
|
|
377
|
+
description="The prefix for the exported data files.",
|
|
378
|
+
)
|
|
379
|
+
output_dir: str = Field(
|
|
380
|
+
None,
|
|
381
|
+
description="The directory to store the exported files.",
|
|
382
|
+
)
|
|
383
|
+
|
|
384
|
+
def _init_task(self):
|
|
385
|
+
super()._init_task()
|
|
386
|
+
self.data_command += "export tree"
|
|
387
|
+
|
|
388
|
+
def _init_options(self, kwargs):
|
|
389
|
+
super()._init_options(kwargs)
|
|
390
|
+
if self.parsed_options.query:
|
|
391
|
+
self.args.extend(["--query", self.parsed_options.query])
|
|
392
|
+
if self.parsed_options.plan:
|
|
393
|
+
self.args.extend(["--plan"])
|
|
394
|
+
if self.parsed_options.prefix:
|
|
395
|
+
self.args.extend(["--prefix", self.parsed_options.prefix])
|
|
396
|
+
if self.parsed_options.output_dir:
|
|
397
|
+
self.args.extend(["--output-dir", self.parsed_options.output_dir])
|
|
398
|
+
|
|
399
|
+
def _run_task(self):
|
|
400
|
+
return super()._run_task()
|
|
@@ -23,6 +23,9 @@ class CreateBlankProfile(BaseSalesforceMetadataApiTask):
|
|
|
23
23
|
"description": "The description of the the new profile",
|
|
24
24
|
"required": False,
|
|
25
25
|
},
|
|
26
|
+
"collision_check": {
|
|
27
|
+
"description": "Performs a collision check with metadata already present in the target org. Defaults to True"
|
|
28
|
+
},
|
|
26
29
|
}
|
|
27
30
|
|
|
28
31
|
def _init_options(self, kwargs):
|
|
@@ -32,6 +35,7 @@ class CreateBlankProfile(BaseSalesforceMetadataApiTask):
|
|
|
32
35
|
"Either the name or the ID of the user license must be set."
|
|
33
36
|
)
|
|
34
37
|
self.license = self.options.get("license", "Salesforce")
|
|
38
|
+
self.sf = None
|
|
35
39
|
|
|
36
40
|
def _run_task(self):
|
|
37
41
|
|
|
@@ -39,6 +43,15 @@ class CreateBlankProfile(BaseSalesforceMetadataApiTask):
|
|
|
39
43
|
self.description = self.options.get("description") or ""
|
|
40
44
|
self.license_id = self.options.get("license_id")
|
|
41
45
|
|
|
46
|
+
if self.options.get("collision_check", True):
|
|
47
|
+
profile_id = self._get_profile_id(self.name)
|
|
48
|
+
if profile_id:
|
|
49
|
+
self.logger.info(
|
|
50
|
+
f"Profile '{self.name}' already exists with id: {profile_id}"
|
|
51
|
+
)
|
|
52
|
+
self.return_values = {"profile_id": profile_id}
|
|
53
|
+
return profile_id
|
|
54
|
+
|
|
42
55
|
if not self.license_id:
|
|
43
56
|
self.license_id = self._get_user_license_id(self.license)
|
|
44
57
|
|
|
@@ -48,22 +61,38 @@ class CreateBlankProfile(BaseSalesforceMetadataApiTask):
|
|
|
48
61
|
self.logger.info(f"Profile '{self.name}' created with id: {result}")
|
|
49
62
|
return result
|
|
50
63
|
|
|
64
|
+
def _get_profile_id(self, profile_name):
|
|
65
|
+
"""Returns the Id of a Profile from a given Name"""
|
|
66
|
+
res = self._query_sf(
|
|
67
|
+
f"SELECT Id, Name FROM Profile WHERE FullName = '{profile_name}' LIMIT 1"
|
|
68
|
+
)
|
|
69
|
+
if res["records"]:
|
|
70
|
+
return res["records"][0]["Id"]
|
|
71
|
+
|
|
72
|
+
self.logger.info(f"Profile name '{profile_name}' was not found.")
|
|
73
|
+
return None
|
|
74
|
+
|
|
51
75
|
def _get_user_license_id(self, license_name):
|
|
52
76
|
"""Returns the Id of a UserLicense from a given Name"""
|
|
53
|
-
|
|
54
|
-
self.project_config,
|
|
55
|
-
self.org_config,
|
|
56
|
-
api_version=self.org_config.latest_api_version,
|
|
57
|
-
base_url=None,
|
|
58
|
-
)
|
|
59
|
-
res = self.sf.query(
|
|
77
|
+
res = self._query_sf(
|
|
60
78
|
f"SELECT Id, Name FROM UserLicense WHERE Name = '{license_name}' LIMIT 1"
|
|
61
79
|
)
|
|
80
|
+
|
|
62
81
|
if res["records"]:
|
|
63
82
|
return res["records"][0]["Id"]
|
|
64
83
|
else:
|
|
65
84
|
raise TaskOptionsError(f"License name '{license_name}' was not found.")
|
|
66
85
|
|
|
86
|
+
def _query_sf(self, query):
|
|
87
|
+
self.sf = self.sf or get_simple_salesforce_connection(
|
|
88
|
+
self.project_config,
|
|
89
|
+
self.org_config,
|
|
90
|
+
api_version=self.org_config.latest_api_version,
|
|
91
|
+
base_url=None,
|
|
92
|
+
)
|
|
93
|
+
res = self.sf.query(query)
|
|
94
|
+
return res
|
|
95
|
+
|
|
67
96
|
def _get_api(self):
|
|
68
97
|
return self.api_class(
|
|
69
98
|
self,
|