From 04f41a94b6a5d3da5b6ccd6d5fddc315bfba85b1 Mon Sep 17 00:00:00 2001 From: Esteban Beltran Date: Thu, 29 Jul 2021 13:18:30 +0200 Subject: [PATCH] Add fleet command --- src/commands/fleet.py | 101 ++++++++++++++++++++++++++++++++++++++++++ src/main.py | 2 + src/util.py | 24 +++++++--- 3 files changed, 121 insertions(+), 6 deletions(-) create mode 100644 src/commands/fleet.py diff --git a/src/commands/fleet.py b/src/commands/fleet.py new file mode 100644 index 0000000..922412e --- /dev/null +++ b/src/commands/fleet.py @@ -0,0 +1,101 @@ +import subprocess +import ipaddress +from termcolor import colored +from src.util import is_es_running, is_kibana_running +import click +import re + +_RE_COMBINE_WHITESPACE = re.compile(r"\s+") + + +@click.command() +@click.option( + "--snapshot", + default="docker.elastic.co/beats/elastic-agent:8.0.0-SNAPSHOT", + help=( + "If you want to specify a different snapshot. Default to" + " docker.elastic.co/beats/elastic-agent:8.0.0-SNAPSHOT " + ), +) +@click.option( + "--docker-ip", + help=( + "The docker host IP. Kibbe will try to autodetect it but you can overwrite it" + " with this option" + ), +) +@click.option( + "--run", + is_flag=True, + help=( + "It will attempt to run fleet server locally. You should have kibana and" + " elastic search running locally already" + ), +) +def fleet(run, snapshot, docker_ip): + """ + Utilities to work with the security solutions fleet server locally + """ + if run: + if not is_kibana_running(): + click.echo( + colored( + "Kibana is not running. Kibana must be runnnig to run fleet via" + " this helper", + "red", + ) + ) + raise click.ClickException("Kibana not running") + if not is_es_running(): + click.echo( + colored( + "Elasticsearch is not running. Elasticsearch must be runnnig to" + " run fleet via this helper", + "red", + ) + ) + raise click.ClickException("Elasticsearch not running") + + docker_ip = get_docker_ip(docker_ip) + click.echo(" - Autodetected docker host ip: " + colored(docker_ip, "blue")) + + docker_command = """docker run \ + --add-host kibana:{host_ip} \ + --add-host elasticsearch:{host_ip} \ + --add-host fleetserver:127.0.0.1 \ + -e KIBANA_HOST=http://kibana:5601 \ + -e KIBANA_USERNAME=elastic \ + -e KIBANA_PASSWORD=changeme \ + -e ELASTICSEARCH_HOST=http://elasticsearch:9200 \ + -e ELASTICSEARCH_USERNAME=elastic \ + -e ELASTICSEARCH_PASSWORD=changeme \ + -e FLEET_SERVER_HOST=0.0.0.0 \ + -e FLEET_INSECURE=1 \ + -e KIBANA_FLEET_SETUP=1 \ + -e FLEET_SERVER_ENABLE=1 \ + -e FLEET_SERVER_INSECURE_HTTP=1 \ + -p 8220:8220 {snapshot} + """.replace( + "\n", "" + ) + docker_command = docker_command.format(host_ip=docker_ip, snapshot=snapshot) + docker_command = _RE_COMBINE_WHITESPACE.sub(" ", docker_command).strip() + + click.echo(" - Will run docker with:\n") + click.echo(colored(docker_command, "yellow")) + docker_command = docker_command.split(" ") + subprocess.run(docker_command) + + +def get_docker_ip(default_ip): + ip = default_ip if default_ip and len(default_ip > 0) else "172.17.0.1" + possible_ip = subprocess.getoutput( + "docker network inspect bridge -f '{{range .IPAM.Config}}{{.Gateway}}{{end}}'" + ) + try: + ipaddress.ip_address(possible_ip) + ip = possible_ip + except ValueError: + pass + + return ip diff --git a/src/main.py b/src/main.py index f1f960f..a895e15 100644 --- a/src/main.py +++ b/src/main.py @@ -1,3 +1,4 @@ +from src.commands.fleet import fleet import click from src.commands.check import check @@ -34,3 +35,4 @@ def cli(config_file): cli.add_command(es) cli.add_command(kibana) cli.add_command(setmeup) +cli.add_command(fleet) diff --git a/src/util.py b/src/util.py index 8d132da..9336132 100644 --- a/src/util.py +++ b/src/util.py @@ -17,6 +17,22 @@ def is_tool(name): return which(name) is not None +def is_es_running(): + try: + requests.get("http://localhost:9200") + return True + except requests.ConnectionError: + return False + + +def is_kibana_running(): + try: + requests.get("http://localhost:5601") + return True + except requests.ConnectionError: + return False + + def force_kibana_root(): if not is_kibana_repo(): raise click.ClickException( @@ -140,13 +156,9 @@ def wait_for_elastic_search(): with click.progressbar(numbers) as bar: for item in bar: current = item - try: - requests.get("http://localhost:9200") + if is_es_running(): break - except requests.ConnectionError: - pass - finally: - time.sleep(1) + time.sleep(1) # progress = click.progressbar(length=total, label="Waiting for elasticsearch") # while timeout >= 0: