Skip to content

Commit 2d70436

Browse files
committed
Add instance command with config subcommand
1 parent 704a864 commit 2d70436

File tree

3 files changed

+74
-0
lines changed

3 files changed

+74
-0
lines changed

ctfcli/__main__.py

+5
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
from ctfcli.cli.challenges import ChallengeCommand
1313
from ctfcli.cli.config import ConfigCommand
14+
from ctfcli.cli.instance import InstanceCommand
1415
from ctfcli.cli.pages import PagesCommand
1516
from ctfcli.cli.plugins import PluginsCommand
1617
from ctfcli.cli.templates import TemplatesCommand
@@ -101,6 +102,9 @@ def init(
101102
def config(self):
102103
return COMMANDS.get("config")
103104

105+
def instance(self):
106+
return COMMANDS.get("instance")
107+
104108
def challenge(self):
105109
return COMMANDS.get("challenge")
106110

@@ -120,6 +124,7 @@ def templates(self):
120124
"pages": PagesCommand(),
121125
"plugins": PluginsCommand(),
122126
"templates": TemplatesCommand(),
127+
"instance": InstanceCommand(),
123128
"cli": CTFCLI(),
124129
}
125130

ctfcli/cli/instance.py

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import logging
2+
3+
import click
4+
5+
from ctfcli.core.config import Config
6+
from ctfcli.core.instance.config import ServerConfig
7+
8+
log = logging.getLogger("ctfcli.cli.instance")
9+
10+
11+
class ConfigCommand:
12+
def get(self, key):
13+
"""Get the value of a specific remote instance config key"""
14+
return ServerConfig.get(key=key)
15+
16+
def set(self, key, value):
17+
"""Set the value of a specific remote instance config key"""
18+
ServerConfig.set(key=key, value=value)
19+
click.secho(f"Successfully set '{key}' to '{value}'", fg="green")
20+
21+
def pull(self):
22+
"""Copy remote instance configuration values to local config"""
23+
server_configs = ServerConfig.getall()
24+
25+
config = Config()
26+
if config.config.has_section("instance") is False:
27+
config.config.add_section("instance")
28+
29+
for k, v in server_configs.items():
30+
# We always store as a string because the CTFd Configs model is a string
31+
if v == "None":
32+
v = "null"
33+
config.config.set("instance", k, str(v))
34+
35+
with open(config.config_path, "w+") as f:
36+
config.write(f)
37+
38+
click.secho("Successfully pulled configuration", fg="green")
39+
40+
def push(self):
41+
"""Save local instance configuration values to remote CTFd instance"""
42+
config = Config()
43+
if config.config.has_section("instance") is False:
44+
config.config.add_section("instance")
45+
46+
configs = {}
47+
for k in config["instance"]:
48+
v = config["instance"][k]
49+
if v == "null":
50+
v = None
51+
configs[k] = v
52+
53+
failed_configs = ServerConfig.setall(configs=configs)
54+
for f in failed_configs:
55+
click.secho(f"Failed to push config {f}", fg="red")
56+
57+
if not failed_configs:
58+
click.secho("Successfully pushed config", fg="green")
59+
else:
60+
return 1
61+
62+
63+
class InstanceCommand:
64+
def config(self):
65+
return ConfigCommand

ctfcli/core/exceptions.py

+4
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,7 @@ class InvalidPageConfiguration(PageException):
5555

5656
class IllegalPageOperation(PageException):
5757
pass
58+
59+
60+
class InstanceConfigException(Exception):
61+
pass

0 commit comments

Comments
 (0)