Skip to content

Commit 539e08b

Browse files
authored
CRTX-275274-migrate-gcp-compute-images (#45631)
* CRTX-275274-migrate-gcp-compute-images * delete output * update rn * update * update * ai review fixes * cr fixes * doc review
1 parent 066388a commit 539e08b

6 files changed

Lines changed: 1459 additions & 1 deletion

File tree

Packs/GCP/Integrations/GCP/GCP.py

Lines changed: 257 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,11 @@ def test_all_services(cls, credentials, project_id: str) -> list[tuple[str, bool
469469
),
470470
"gcp-compute-network-get": (GCPServices.COMPUTE, ["compute.networks.get"]),
471471
"gcp-compute-image-get": (GCPServices.COMPUTE, ["compute.images.get"]),
472+
"gcp-compute-image-get-from-family": (GCPServices.COMPUTE, ["compute.images.get"]),
473+
"gcp-compute-images-list": (GCPServices.COMPUTE, ["compute.images.list"]),
474+
"gcp-compute-image-delete": (GCPServices.COMPUTE, ["compute.images.delete"]),
475+
"gcp-compute-image-labels-set": (GCPServices.COMPUTE, ["compute.images.setLabels"]),
476+
"gcp-compute-image-insert": (GCPServices.COMPUTE, ["compute.images.create"]),
472477
"gcp-compute-instance-group-get": (GCPServices.COMPUTE, ["compute.instanceGroups.get"]),
473478
"gcp-compute-region-get": (GCPServices.COMPUTE, ["compute.regions.get"]),
474479
"gcp-compute-regions-list": (GCPServices.COMPUTE, ["compute.regions.list"]),
@@ -4756,6 +4761,253 @@ def gcp_compute_image_get(creds: Credentials, args: dict[str, Any]) -> CommandRe
47564761
)
47574762

47584763

4764+
def gcp_compute_image_get_from_family(creds: Credentials, args: dict[str, Any]) -> CommandResults:
4765+
"""
4766+
Returns the latest image that is part of an image family and is not deprecated.
4767+
4768+
Args:
4769+
creds (Credentials): Authorized GCP credentials used to access the Compute Engine API.
4770+
args (dict): Command arguments including 'project_id' and 'family'.
4771+
4772+
Returns:
4773+
CommandResults: Object containing the image details under `GCP.Compute.Images`.
4774+
"""
4775+
project_id = args.get("project_id")
4776+
family = args.get("family")
4777+
4778+
compute = GCPServices.COMPUTE.build(creds)
4779+
response = compute.images().getFromFamily(project=project_id, family=family).execute() # pylint: disable=E1101
4780+
4781+
data_res = {
4782+
"id": response.get("id"),
4783+
"name": response.get("name"),
4784+
"family": response.get("family"),
4785+
"creationTimestamp": response.get("creationTimestamp"),
4786+
"description": response.get("description"),
4787+
}
4788+
headers = ["id", "name", "family", "creationTimestamp", "description"]
4789+
4790+
readable_output = tableToMarkdown(
4791+
f"GCP image family {family}", data_res, headers=headers, removeNull=True, headerTransform=pascalToSpace
4792+
)
4793+
4794+
return CommandResults(
4795+
readable_output=readable_output,
4796+
outputs_prefix="GCP.Compute.Images",
4797+
outputs_key_field="id",
4798+
outputs=response,
4799+
raw_response=response,
4800+
)
4801+
4802+
4803+
def gcp_compute_images_list(creds: Credentials, args: dict[str, Any]) -> CommandResults:
4804+
"""
4805+
Lists all Compute Engine images in a specified GCP project.
4806+
4807+
Args:
4808+
creds (Credentials): Authorized GCP credentials used to access the Compute Engine API.
4809+
args (dict): Command arguments including:
4810+
- project_id (str): The GCP project ID.
4811+
- limit (int, optional): Maximum number of results to return (1-500).
4812+
- next_token (str, optional): Token for pagination.
4813+
- filter (str, optional): Expression for filtering listed images.
4814+
- order_by (str, optional): Sorts list results by a certain order.
4815+
4816+
Returns:
4817+
CommandResults: Object containing a list of image details under `GCP.Compute.Images`
4818+
and pagination token under `GCP.Compute.ImagesNextToken`.
4819+
"""
4820+
project_id = args.get("project_id")
4821+
limit = arg_to_number(args.get("limit")) or 50
4822+
next_token = args.get("next_token")
4823+
flt = args.get("filter")
4824+
order_by = args.get("order_by")
4825+
validate_limit(limit)
4826+
4827+
params: dict[str, Any] = {
4828+
"project": project_id,
4829+
"maxResults": limit,
4830+
"pageToken": next_token,
4831+
"filter": flt,
4832+
"orderBy": order_by,
4833+
}
4834+
remove_nulls_from_dictionary(params)
4835+
4836+
compute = GCPServices.COMPUTE.build(creds)
4837+
response = compute.images().list(**params).execute() # pylint: disable=E1101
4838+
items = response.get("items", [])
4839+
next_page_token = response.get("nextPageToken")
4840+
headers = ["name", "id", "family", "status", "creationTimestamp"]
4841+
readable_output = tableToMarkdown(
4842+
"GCP Compute Images",
4843+
items,
4844+
headers=headers,
4845+
removeNull=True,
4846+
headerTransform=pascalToSpace,
4847+
)
4848+
4849+
outputs = {
4850+
"GCP.Compute.Images(val.id && val.id == obj.id)": items,
4851+
"GCP.Compute(true)": {"ImagesNextToken": next_page_token},
4852+
}
4853+
return CommandResults(readable_output=readable_output, outputs=outputs, raw_response=response)
4854+
4855+
4856+
def gcp_compute_image_delete(creds: Credentials, args: dict[str, Any]) -> CommandResults:
4857+
"""
4858+
Deletes the specified image.
4859+
4860+
Args:
4861+
creds (Credentials): Authorized GCP credentials used to access the Compute Engine API.
4862+
args (dict): Command arguments including 'project_id' and 'image'.
4863+
4864+
Returns:
4865+
CommandResults: Object containing the human-readable status of the delete operation.
4866+
"""
4867+
project_id = args.get("project_id")
4868+
image = args.get("image")
4869+
4870+
compute = GCPServices.COMPUTE.build(creds)
4871+
response = compute.images().delete(project=project_id, image=image).execute() # pylint: disable=E1101
4872+
4873+
hr = tableToMarkdown(
4874+
"Google Cloud Compute Image Delete Operation Started Successfully",
4875+
t=response,
4876+
headers=OPERATION_TABLE,
4877+
headerTransform=pascalToSpace,
4878+
removeNull=True,
4879+
)
4880+
return CommandResults(
4881+
readable_output=hr,
4882+
raw_response=response,
4883+
)
4884+
4885+
4886+
def gcp_compute_image_labels_set(creds: Credentials, args: dict[str, Any]) -> CommandResults:
4887+
"""
4888+
Sets the labels on an image.
4889+
4890+
Args:
4891+
creds (Credentials): Authorized GCP credentials used to access the Compute Engine API.
4892+
args (dict): Command arguments including 'project_id', 'image', 'labels', and 'label_fingerprint'.
4893+
4894+
Returns:
4895+
CommandResults: Object containing the operation details of the setLabels request,
4896+
with `GCP.Compute.Operations` context output.
4897+
"""
4898+
project_id = args.get("project_id")
4899+
image = args.get("image")
4900+
labels = parse_labels(args.get("labels", ""))
4901+
label_fingerprint = args.get("label_fingerprint")
4902+
demisto.debug(f"The parsed {labels=}")
4903+
4904+
body = {"labels": labels, "labelFingerprint": label_fingerprint}
4905+
4906+
compute = GCPServices.COMPUTE.build(creds)
4907+
response = compute.images().setLabels(project=project_id, resource=image, body=body).execute() # pylint: disable=E1101
4908+
4909+
hr = tableToMarkdown(
4910+
f"Google Cloud Compute Image {image} Labels Update Operation Started Successfully",
4911+
t=response,
4912+
headers=OPERATION_TABLE,
4913+
headerTransform=pascalToSpace,
4914+
removeNull=True,
4915+
)
4916+
return CommandResults(
4917+
readable_output=hr,
4918+
outputs_prefix="GCP.Compute.Operations",
4919+
outputs_key_field="id",
4920+
outputs=response,
4921+
raw_response=response,
4922+
)
4923+
4924+
4925+
def gcp_compute_image_insert(creds: Credentials, args: dict[str, Any]) -> CommandResults:
4926+
"""
4927+
Creates an image in the specified project using the data included in the request.
4928+
4929+
Args:
4930+
creds (Credentials): Authorized GCP credentials used to access the Compute Engine API.
4931+
args (dict): Command arguments including 'project_id', 'name', and the various optional
4932+
image source and encryption fields.
4933+
4934+
Returns:
4935+
CommandResults: Object containing the operation details of the insert request,
4936+
with `GCP.Compute.Operations` context output.
4937+
"""
4938+
project_id = args.get("project_id")
4939+
force_create = argToBoolean(args.get("force_create", False))
4940+
name = args["name"]
4941+
labels = args.get("labels")
4942+
guest_os_features = argToList(args.get("guest_os_features"))
4943+
4944+
body = remove_empty_elements(
4945+
{
4946+
"name": name.lower(),
4947+
"description": args.get("description"),
4948+
"sourceDisk": args.get("source_disk"),
4949+
"sourceImage": args.get("source_image"),
4950+
"sourceSnapshot": args.get("source_snapshot"),
4951+
"family": args.get("family"),
4952+
"archiveSizeBytes": arg_to_number(args.get("archive_size_bytes")),
4953+
"diskSizeGb": arg_to_number(args.get("disk_size_gb")),
4954+
"licenses": argToList(args.get("licenses")),
4955+
"licenseCodes": argToList(args.get("license_codes")),
4956+
"labels": parse_labels(labels) if labels else None,
4957+
"labelFingerprint": args.get("label_fingerprint"),
4958+
"guestOsFeatures": [{"type": feature} for feature in guest_os_features],
4959+
"rawDisk": {
4960+
"source": args.get("raw_disk_source"),
4961+
"sha1Checksum": args.get("raw_disk_sha1_checksum"),
4962+
"containerType": args.get("raw_disk_container_type"),
4963+
},
4964+
"deprecated": {
4965+
"state": args.get("deprecated_state"),
4966+
"replacement": args.get("deprecated_replacement"),
4967+
},
4968+
"imageEncryptionKey": {
4969+
"rawKey": args.get("image_encryption_key_raw_key"),
4970+
"kmsKeyName": args.get("image_encryption_key_kms_key_name"),
4971+
},
4972+
"sourceDiskEncryptionKey": {
4973+
"rawKey": args.get("source_disk_encryption_key_raw_key"),
4974+
"kmsKeyName": args.get("source_disk_encryption_key_kms_key_name"),
4975+
},
4976+
"sourceImageEncryptionKey": {
4977+
"rawKey": args.get("source_image_encryption_key_raw_key"),
4978+
"kmsKeyName": args.get("source_image_encryption_key_kms_key_name"),
4979+
},
4980+
"sourceSnapshotEncryptionKey": {
4981+
"rawKey": args.get("source_snapshot_encryption_key_raw_key"),
4982+
"kmsKeyName": args.get("source_snapshot_encryption_key_kms_key_name"),
4983+
},
4984+
}
4985+
)
4986+
4987+
compute = GCPServices.COMPUTE.build(creds)
4988+
demisto.debug(f"Image insert body keys for project {project_id}: {list(body.keys()) if isinstance(body, dict) else []}")
4989+
response = (
4990+
compute.images() # pylint: disable=E1101
4991+
.insert(project=project_id, forceCreate=force_create, body=body)
4992+
.execute()
4993+
)
4994+
4995+
hr = tableToMarkdown(
4996+
"Google Cloud Compute Image Insert Operation Started Successfully",
4997+
t=response,
4998+
headers=OPERATION_TABLE,
4999+
headerTransform=pascalToSpace,
5000+
removeNull=True,
5001+
)
5002+
return CommandResults(
5003+
readable_output=hr,
5004+
outputs_prefix="GCP.Compute.Operations",
5005+
outputs_key_field="id",
5006+
outputs=response,
5007+
raw_response=response,
5008+
)
5009+
5010+
47595011
def gcp_compute_region_get(creds: Credentials, args: dict[str, Any]) -> CommandResults:
47605012
"""
47615013
Get a specified region resource.
@@ -5176,6 +5428,11 @@ def main(): # pragma: no cover
51765428
"gcp-compute-instance-labels-set": gcp_compute_instance_label_set_command,
51775429
"gcp-compute-network-get": gcp_compute_network_get_command,
51785430
"gcp-compute-image-get": gcp_compute_image_get,
5431+
"gcp-compute-image-get-from-family": gcp_compute_image_get_from_family,
5432+
"gcp-compute-images-list": gcp_compute_images_list,
5433+
"gcp-compute-image-delete": gcp_compute_image_delete,
5434+
"gcp-compute-image-labels-set": gcp_compute_image_labels_set,
5435+
"gcp-compute-image-insert": gcp_compute_image_insert,
51795436
"gcp-compute-instance-group-get": gcp_compute_instance_group_get,
51805437
"gcp-compute-region-get": gcp_compute_region_get,
51815438
"gcp-compute-regions-list": gcp_compute_regions_list,

0 commit comments

Comments
 (0)