Last active
April 24, 2025 09:53
-
-
Save laidbackware/91919173c3cafe48b007238000badfea to your computer and use it in GitHub Desktop.
Generate Bosh pcap commands from app guid
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import json, os, shutil, subprocess, sys | |
def main(app_guids): | |
check_binary("cf") | |
check_binary("bosh") | |
# Checking cf logged in | |
target = subprocess.run(['cf', 'target'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) | |
if target.returncode != 0: | |
print(f"cf commands fail with {target.stderr}") | |
sys.exit(1) | |
spec_apps = [] | |
for app_guid in app_guids.split(','): | |
app_json = subprocess.run(['cf', 'curl', f'/v3/apps/{app_guid}'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) | |
if b"CF-ResourceNotFound" in app_json.stdout: | |
print(f"App guid {app_guid} does not exist") | |
sys.exit(1) | |
app = json.loads(app_json.stdout) | |
spec_apps.append({'guid': app_guid, 'name': app['name'], 'guid_slice': app_guid.split("-")[0]}) | |
continue | |
pcap(spec_apps) | |
def pcap(spec_apps): | |
app_commands = [] | |
app_ips = [] | |
diego_instance_names = get_diego_instance_names() | |
cf_dep_name = get_cf_dep_name() | |
for spec_app in spec_apps: | |
print(f"Collecting details for {spec_app['name']}:{spec_app['guid']}") | |
processes = get_ips(spec_app['guid']) | |
for resources in processes['resources']: | |
app_ips.append(resources['instance_internal_ip']) | |
app_commands.append(get_instance_command(resources['host'], resources['instance_internal_ip'], | |
diego_instance_names, cf_dep_name, spec_app)) | |
print("Commands below:\n\n") | |
router_hosts = ' or host '.join(app_ips) | |
print(f"bosh -d {cf_dep_name} pcap router -o router.pcap -f 'host {router_hosts}' -s 128") | |
for app_command in app_commands: | |
print(app_command) | |
def get_cf_dep_name(): | |
deps = subprocess.run(['bosh', 'deps', "--json"], stdout=subprocess.PIPE, env=os.environ.copy()) | |
for deployment in json.loads(deps.stdout)['Tables']: | |
for dep in deployment['Rows']: | |
if 'cf-' in dep['name']: | |
return dep['name'] | |
return "parp" | |
def get_diego_instance_names(): | |
vms_out = subprocess.run(['bosh', 'vms', "--json"], stdout=subprocess.PIPE, env=os.environ.copy()) | |
if vms_out.returncode != 0: | |
print(f"bosh commands fail with {vms_out.stdout}") | |
sys.exit(1) | |
ip_to_instance_name = {} | |
vms = json.loads(vms_out.stdout) | |
for deployment in vms['Tables']: | |
for vm in deployment['Rows']: | |
ip_to_instance_name.update({vm['ips']: vm['instance']}) | |
return ip_to_instance_name | |
def get_ips(app_guid): | |
result = subprocess.run(['cf', 'curl', f"/v3/processes/{app_guid}/stats"], stdout=subprocess.PIPE) | |
return json.loads(result.stdout) | |
def get_instance_command(host_ip, container_ip, diego_instance_names, cf_dep_name, spec_app): | |
print(f"Collecting interface for instance {container_ip}") | |
deigo_cell = diego_instance_names[host_ip] | |
cmd = ['bosh', '-d', cf_dep_name, 'ssh', deigo_cell, '-c', | |
f'/var/vcap/packages/cfdot/bin/cfdot actual-lrps --bbsURL https://bbs.service.cf.internal:8889 --caCertFile /var/vcap/jobs/cfdot/config/certs/cfdot/ca.crt --clientCertFile /var/vcap/jobs/cfdot/config/certs/cfdot/client.crt --clientKeyFile /var/vcap/jobs/cfdot/config/certs/cfdot/client.key |grep {container_ip}', | |
'--json'] | |
bosh_out = subprocess.run(cmd, stdout=subprocess.PIPE, env=os.environ.copy()) | |
command_lines = json.loads(bosh_out.stdout)['Blocks'] | |
for line in command_lines: | |
if "process_guid" in line: | |
process_details = json.loads(line) | |
port_name = process_details['instance_guid'][:15] | |
return_cmd = f"bosh -d {cf_dep_name} pcap {deigo_cell} -o app_{spec_app['name']}_{spec_app['guid_slice']}_{container_ip}.pcap -i {port_name} -s 128" | |
return return_cmd | |
def check_binary(binary_name): | |
if shutil.which(binary_name) == None: | |
print(f"{binary_name} is not available via the PATH") | |
sys.exit(1) | |
if __name__ == '__main__': | |
if len(sys.argv) < 2: | |
print("you must pass in a comma separated string of app IPs") | |
print("E.g: python pcap.py 326f2a4f-3a00-4d82-945a-bd2efeeb4371,326f2a4f-3a00-4d82-945a-bd2efeeb4372") | |
sys.exit(1) | |
app_guids = sys.argv[1] | |
main(app_guids) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment