-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathempire-bin.py
executable file
·209 lines (156 loc) · 5.74 KB
/
empire-bin.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
#!/usr/bin/env python3
import argparse
import http.client
import subprocess
import sys
import time
from os import environ
from pathlib import Path
from textwrap import dedent
VERSION = "0.0.1"
class Style:
RED = "\033[31m"
GREEN = "\033[32m"
BLUE = "\033[34m"
RESET = "\033[0m"
DEFAULT_PATH = "~/.empire"
# This is not currently configurable.
# There is hardcoded references to ~/.empire in the docker-compose file.
ENV_PATH = environ.get("EMPIRE_HOME_DIR")
path = Path(ENV_PATH or DEFAULT_PATH).expanduser().resolve()
docker_compose_file = path / "docker-compose.yaml"
server_config_file = path / "app-data" / "server-config.yaml"
dot_env_file = path / ".env"
base_command = ["sudo", "-E", "docker", "compose", "-f", docker_compose_file]
rm_rf = ["rm", "-rf"]
def main():
if not docker_compose_file.exists():
printr(f"Docker compose file not found at {docker_compose_file}.")
exit(1)
parser = argparse.ArgumentParser(
description=dedent(
f"""
Empire Launcher v{VERSION}
Docker Compose File: {docker_compose_file}
"""
),
formatter_class=argparse.RawTextHelpFormatter,
)
subparsers = parser.add_subparsers(help="Available commands")
parser_up = subparsers.add_parser("up", help="Starts the Empire server and mysql db")
parser_up.set_defaults(func=empire_up)
parser_down = subparsers.add_parser("down", help="Stops the Empire server and mysql db")
parser_down.set_defaults(func=empire_down)
parser_destroy = subparsers.add_parser("destroy", help="Stops the Empire server and mysql db and removes the data")
parser_destroy.set_defaults(func=empire_destroy)
# empire server
parser_server = subparsers.add_parser("server", help="Server-related commands")
server_subparsers = parser_server.add_subparsers(help="Server commands")
# empire server logs
parser_server_logs = server_subparsers.add_parser("logs", help="Show server logs")
parser_server_logs.add_argument(
"-f",
"--follow",
action="store_true",
help="Follow the logs (like tail -f)",
)
parser_server_logs.set_defaults(func=empire_server_logs)
# empire client
parser_client = subparsers.add_parser("client", help="Client-related commands")
parser_client.set_defaults(func=empire_client)
# empire use
parser_use = subparsers.add_parser("use", help="Change the Empire version")
parser_use.add_argument("version", help="The version of Empire to use")
parser_use.set_defaults(func=empire_use)
# Parse the arguments
args = parser.parse_args()
# If no arguments were provided, print help
if len(sys.argv) == 1:
parser.print_help(sys.stderr)
sys.exit(1)
args.func(args)
def empire_up(args):
printg("Starting Empire")
printg("It may take up to a minute.")
command = base_command + ["up", "-d"]
subprocess.run(command, check=True)
server_config = server_config_file.read_text()
port = "1337"
for line in server_config.split("\n"):
if "port:" in line:
port = line.split("port: ")[1]
time.sleep(5)
for _i in range(60):
is_running = check_server_status(f"localhost:{port}", "/index.html")
if is_running:
printg("Empire is running!")
printg(f"Starkiller at http://localhost:{port}/index.html")
exit(0)
else:
printg("Empire is still starting...")
time.sleep(3)
printr("Empire failed to start.")
def empire_down(args):
printg("Shutting down Empire...")
command = base_command + ["down"]
subprocess.run(command, check=True)
exit(0)
def empire_destroy(args):
printg("Are you sure you want to destroy your Empire instance?")
printg("This will delete all data and cannot be undone.")
printg("Type 'destroy' to continue.")
response = input("> ")
if response != "destroy":
print("Aborting.")
exit(0)
printg("Shutting down containers and destroying volumes...")
command = base_command + ["down", "--volumes"]
subprocess.run(command, check=True)
printg("Clearing app-data directory...")
command = rm_rf + [str(path / "app-data" / "server")]
subprocess.run(command, check=True)
command = rm_rf + [str(path / "app-data" / "client")]
subprocess.run(command, check=True)
printg("Cleared app-data directory")
exit(0)
def empire_server_logs(args):
if args.follow:
command = base_command + ["logs", "-f"]
else:
command = base_command + ["logs"]
subprocess.run(command, check=True)
def empire_client(args):
# todo what if the server isn't using default credentials?
# what if i want to connect as a different user?
# What if the server is running on a different machine, should we still support?
command = base_command + ["exec", "empire_server", "./ps-empire", "client"]
subprocess.run(command, check=True)
def empire_use(args):
printg("Changing Empire version to " + args.version)
lines = dot_env_file.read_text().splitlines()
new_tag = args.version
new_lines = [
f"SERVER_TAG={new_tag}" if line.startswith("SERVER_TAG=") else line
for line in lines
]
dot_env_file.write_text("\n".join(new_lines))
exit(0)
def check_server_status(host, path):
conn = http.client.HTTPConnection(host)
try:
conn.request("GET", path)
response = conn.getresponse()
if response.status == 200:
return True
else:
return False
except Exception:
return False
finally:
conn.close()
def printg(text):
print(f"{Style.GREEN}{text}{Style.RESET}")
def printr(text):
print(f"{Style.RED}{text}{Style.RESET}")
if __name__ == "__main__":
main()