From 52debffb468e6a73e37af40b2a6e097db5b8aebf Mon Sep 17 00:00:00 2001 From: TechnoSavage Date: Mon, 10 Nov 2025 13:31:29 -0500 Subject: [PATCH 1/3] Improvements to timestamps and label attributes. Optimizations to reduce API calls and fetch time. --- akamai_guardicore_centra/centrav4.star | 46 ++++++++++++++++++++------ 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/akamai_guardicore_centra/centrav4.star b/akamai_guardicore_centra/centrav4.star index b6f1a49..b39a41c 100644 --- a/akamai_guardicore_centra/centrav4.star +++ b/akamai_guardicore_centra/centrav4.star @@ -9,12 +9,13 @@ load('uuid', 'new_uuid') CENTRA_BASE_URL = 'https://' RUNZERO_REDIRECT = 'https://console.runzero.com/' -def build_assets(assets): +def build_assets(assets, token): assets_import = [] + label_mapping = {} for asset in assets: agent_info = asset.get('agent', {}) os_info = asset.get('os_info', {}) - asset_id = agent_info.get('id', '') + asset_id = agent_info.get('id', str(new_uuid)) hostname = asset.get('name', '') os = os_info.get('type', '') first_seen = asset.get('first_seen', '') @@ -39,9 +40,8 @@ def build_assets(assets): agent_last_seen = agent_info.get('agent_last_seen', '') #reformat agent_last_seen timestamp for runZero parsing if agent_last_seen != '': - strip_ms = agent_last_seen.split('.') - split_space = strip_ms[0].split(' ') - agent_last_seen = parse_time(split_space[0] + 'T' + split_space[1] + 'Z') + split_space = agent_last_seen.split(' ') + agent_last_seen = parse_time(split_space[0] + 'T' + split_space[1] + 'Z').unix agent_version = agent_info.get('agent_version', '') asset_type = asset.get('asset_type', '') bios_uuid = asset.get('bios_uuid', '') @@ -51,7 +51,7 @@ def build_assets(assets): #reformat last_seen timestamp for runZero parsing if last_seen != '': split_space = last_seen.split(' ') - last_seen = parse_time(split_space[0] + 'T' + split_space[1] + 'Z') + last_seen = parse_time(split_space[0] + 'T' + split_space[1] + 'Z').unix mssp_tenant = asset.get('mssp_tenant_name', '') orc_asset_type = orchestration_metadata.get('asset_type', '') orc_dev_name = orchestration_metadata.get('f5_device_hostname', '') @@ -61,6 +61,18 @@ def build_assets(assets): status = asset.get('status', '') worksite_mod = scoping_details.get('modified', '') worksite_name = scoping_details.get('name', '') + + labels = asset.get('labels', []) + label_guids = [v for item in labels for k,v in item.items() if k == 'id'] + label_names = [] + for guid in label_guids: + name = label_mapping.get(guid, None) + if not name: + new_mapping = get_labels(guid, token) + for k, v in new_mapping.items(): + label_mapping[k] = v + name = label_mapping.get(guid, '') + label_names.append(name) custom_attributes = { @@ -71,6 +83,7 @@ def build_assets(assets): 'biosUuid': bios_uuid, 'comments': comments, 'instanceId': instance_id, + 'labels': label_names, 'lastSeenTS': last_seen, 'msspTenantName': mssp_tenant, 'osInfo.fullKernelVersion': os_kernel, @@ -83,10 +96,6 @@ def build_assets(assets): 'orchestrationMetadata.vsName': orc_vs_name } - labels = asset.get('labels', []) - for item in labels: - for k, v in item.items(): - custom_attributes['label.' + str(labels.index(item)) + '.' + k] = v label_groups = asset.get('label_groups', []) for group in label_groups: for k, v in group.items(): @@ -125,6 +134,21 @@ def build_network_interface(ips, mac): else: return NetworkInterface(macAddress=mac, ipv4Addresses=ip4s, ipv6Addresses=ip6s) +def get_labels(guid, token): + url = CENTRA_BASE_URL + '/api/v4.0/labels/' + guid + '?' + headers = {'Accept': 'application/json', + 'Authorization': 'Bearer ' + token} + params = {'asset_limit': 1} + response = http_get(url, headers=headers, params=params) + if response.status_code != 200: + print('failed to retrieve label info for ' + guid, 'status code: ' + str(response.status_code)) + data = json_decode(response.body) + label_info = data['objects'] + label_key = label_info[0].get('key', '') + label_value = label_info[0].get('value', '') + label_mapping = { guid: label_key + ': ' + label_value } + return label_mapping + def get_assets(token): assets_all = [] results_per_page = 1000 @@ -203,7 +227,7 @@ def main(*args, **kwargs): assets = get_assets(token) # Format asset list for import into runZero - import_assets = build_assets(assets) + import_assets = build_assets(assets, token) if not import_assets: print('no assets') return None From 0d2791205be07efd579e46b7b6ae7388f5b80efd Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 10 Nov 2025 18:36:52 +0000 Subject: [PATCH 2/3] Auto: update integrations JSON and README --- docs/integrations.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/integrations.json b/docs/integrations.json index ebe495f..6bd5ad3 100644 --- a/docs/integrations.json +++ b/docs/integrations.json @@ -1,5 +1,5 @@ { - "lastUpdated": "2025-11-03T16:43:06.308528Z", + "lastUpdated": "2025-11-10T18:36:52.667035Z", "totalIntegrations": 28, "integrationDetails": [ { From 9d526b98ddc5b56ed50c66045fedd1cb6435f979 Mon Sep 17 00:00:00 2001 From: Tyler Diderich Date: Thu, 13 Nov 2025 11:38:13 -0600 Subject: [PATCH 3/3] nit picks --- {akamai_guardicore_centra => akamai-guardicore-centra}/README.md | 0 akamai-guardicore-centra/config.json | 1 + .../custom-integration-centra-v3-api.star | 0 .../custom-integration-centra-v4-api.star | 0 akamai_guardicore_centra/config.json | 1 - 5 files changed, 1 insertion(+), 1 deletion(-) rename {akamai_guardicore_centra => akamai-guardicore-centra}/README.md (100%) create mode 100644 akamai-guardicore-centra/config.json rename akamai_guardicore_centra/centrav3.star => akamai-guardicore-centra/custom-integration-centra-v3-api.star (100%) rename akamai_guardicore_centra/centrav4.star => akamai-guardicore-centra/custom-integration-centra-v4-api.star (100%) delete mode 100644 akamai_guardicore_centra/config.json diff --git a/akamai_guardicore_centra/README.md b/akamai-guardicore-centra/README.md similarity index 100% rename from akamai_guardicore_centra/README.md rename to akamai-guardicore-centra/README.md diff --git a/akamai-guardicore-centra/config.json b/akamai-guardicore-centra/config.json new file mode 100644 index 0000000..a3efea2 --- /dev/null +++ b/akamai-guardicore-centra/config.json @@ -0,0 +1 @@ +{ "name": "Akamai Guardicore Centra", "type": "inbound" } \ No newline at end of file diff --git a/akamai_guardicore_centra/centrav3.star b/akamai-guardicore-centra/custom-integration-centra-v3-api.star similarity index 100% rename from akamai_guardicore_centra/centrav3.star rename to akamai-guardicore-centra/custom-integration-centra-v3-api.star diff --git a/akamai_guardicore_centra/centrav4.star b/akamai-guardicore-centra/custom-integration-centra-v4-api.star similarity index 100% rename from akamai_guardicore_centra/centrav4.star rename to akamai-guardicore-centra/custom-integration-centra-v4-api.star diff --git a/akamai_guardicore_centra/config.json b/akamai_guardicore_centra/config.json deleted file mode 100644 index d70654b..0000000 --- a/akamai_guardicore_centra/config.json +++ /dev/null @@ -1 +0,0 @@ -{ "name": "Guardicore Centra", "type": "inbound" } \ No newline at end of file