|
17 | 17 | import os
|
18 | 18 | import logging
|
19 | 19 | import click
|
20 |
| -import base64 |
21 |
| -import mimetypes |
22 | 20 | import tarfile
|
23 | 21 |
|
| 22 | +from importlib.metadata import version as importlib_version |
| 23 | + |
24 | 24 | from turbinia_api_lib import exceptions
|
25 | 25 | from turbinia_api_lib import api_client
|
26 | 26 | from turbinia_api_lib.api import turbinia_requests_api
|
@@ -274,95 +274,6 @@ def get_task(
|
274 | 274 | f'when calling get_task_status: {exception.body}')
|
275 | 275 |
|
276 | 276 |
|
277 |
| -@click.pass_context |
278 |
| -def create_request(ctx: click.Context, *args: int, **kwargs: int) -> None: |
279 |
| - """Creates and submits a new Turbinia request.""" |
280 |
| - client: api_client.ApiClient = ctx.obj.api_client |
281 |
| - api_instance = turbinia_requests_api.TurbiniaRequestsApi(client) |
282 |
| - evidence_name = ctx.command.name |
283 |
| - |
284 |
| - # Normalize the evidence class name from lowercase to the original name. |
285 |
| - evidence_name = ctx.obj.normalize_evidence_name(evidence_name) |
286 |
| - # Build request and request_options objects to send to the API server. |
287 |
| - request_options = list(ctx.obj.request_options.keys()) |
288 |
| - request = {'evidence': {'type': evidence_name}, 'request_options': {}} |
289 |
| - |
290 |
| - if 'googlecloud' in evidence_name: |
291 |
| - api_instance_config = turbinia_configuration_api.TurbiniaConfigurationApi( |
292 |
| - client) |
293 |
| - cloud_provider = api_instance_config.read_config()['CLOUD_PROVIDER'] |
294 |
| - if cloud_provider != 'GCP': |
295 |
| - log.error( |
296 |
| - f'The evidence type {evidence_name} is Google Cloud only and ' |
297 |
| - f'the configured provider for this Turbinia instance is ' |
298 |
| - f'{cloud_provider}.') |
299 |
| - return |
300 |
| - |
301 |
| - for key, value in kwargs.items(): |
302 |
| - # If the value is not empty, add it to the request. |
303 |
| - if kwargs.get(key): |
304 |
| - # Check if the key is for evidence or request_options |
305 |
| - if not key in request_options: |
306 |
| - request['evidence'][key] = value |
307 |
| - elif key in ('jobs_allowlist', 'jobs_denylist'): |
308 |
| - jobs_list = value.split(',') |
309 |
| - request['request_options'][key] = jobs_list |
310 |
| - else: |
311 |
| - request['request_options'][key] = value |
312 |
| - |
313 |
| - if all(key in request['request_options'] |
314 |
| - for key in ('recipe_name', 'recipe_data')): |
315 |
| - log.error('You can only provide one of recipe_data or recipe_name') |
316 |
| - return |
317 |
| - |
318 |
| - recipe_name = request['request_options'].get('recipe_name') |
319 |
| - if recipe_name: |
320 |
| - if not recipe_name.endswith('.yaml'): |
321 |
| - recipe_name = f'{recipe_name}.yaml' |
322 |
| - # Fallback path for the recipe would be TURBINIA_CLI_CONFIG_PATH/recipe_name |
323 |
| - # This is the same path where the client configuration is loaded from. |
324 |
| - recipe_path_fallback = os.path.expanduser(ctx.obj.config_path) |
325 |
| - recipe_path_fallback = os.path.join(recipe_path_fallback, recipe_name) |
326 |
| - |
327 |
| - if os.path.isfile(recipe_name): |
328 |
| - recipe_path = recipe_name |
329 |
| - elif os.path.isfile(recipe_path_fallback): |
330 |
| - recipe_path = recipe_path_fallback |
331 |
| - else: |
332 |
| - log.error(f'Unable to load recipe {recipe_name}.') |
333 |
| - return |
334 |
| - |
335 |
| - try: |
336 |
| - with open(recipe_path, 'r', encoding='utf-8') as recipe_file: |
337 |
| - # Read the file and convert to base64 encoded bytes. |
338 |
| - recipe_bytes = recipe_file.read().encode('utf-8') |
339 |
| - recipe_data = base64.b64encode(recipe_bytes) |
340 |
| - except OSError as exception: |
341 |
| - log.error(f'Error opening recipe file {recipe_path}: {exception}') |
342 |
| - return |
343 |
| - except TypeError as exception: |
344 |
| - log.error(f'Error converting recipe data to Base64: {exception}') |
345 |
| - return |
346 |
| - # We found the recipe file, so we will send it to the API server |
347 |
| - # via the recipe_data parameter. To do so, we need to pop recipe_name |
348 |
| - # from the request so that we only have recipe_data. |
349 |
| - request['request_options'].pop('recipe_name') |
350 |
| - # recipe_data should be a UTF-8 encoded string. |
351 |
| - request['request_options']['recipe_data'] = recipe_data.decode('utf-8') |
352 |
| - |
353 |
| - # Send the request to the API server. |
354 |
| - try: |
355 |
| - log.info(f'Sending request: {request}') |
356 |
| - api_response = api_instance.create_request(request) |
357 |
| - log.info(f'Received response: {api_response}') |
358 |
| - except exceptions.ApiException as exception: |
359 |
| - log.error( |
360 |
| - f'Received status code {exception.status} ' |
361 |
| - f'when calling create_request: {exception.body}') |
362 |
| - except (TypeError, exceptions.ApiTypeError) as exception: |
363 |
| - log.error(f'The request object is invalid. {exception}') |
364 |
| - |
365 |
| - |
366 | 277 | @groups.evidence_group.command('summary')
|
367 | 278 | @click.pass_context
|
368 | 279 | @click.option(
|
@@ -514,3 +425,10 @@ def upload_evidence(
|
514 | 425 | formatter.EvidenceMarkdownReport({}).dict_to_markdown(
|
515 | 426 | report, 0, format_keys=False))
|
516 | 427 | click.echo(report)
|
| 428 | + |
| 429 | + |
| 430 | +@click.command('version') |
| 431 | +def version(): |
| 432 | + """Returns the turbinia-client package distribution version.""" |
| 433 | + cli_version = importlib_version('turbinia-client') |
| 434 | + click.echo(f'turbinia-client version {cli_version}') |
0 commit comments