Skip to content

Commit 24d0b73

Browse files
authored
Refactor: init command for GYB (#8)
2 parents b787a5b + 8074fc1 commit 24d0b73

File tree

6 files changed

+108
-46
lines changed

6 files changed

+108
-46
lines changed

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,15 @@ Initial setup of a GAMADV-XTD3 project and GYB project is required to provide ne
4444
4545
```bash
4646
$ compiler-admin init -h
47-
usage: compiler-admin init [-h] username
47+
usage: compiler-admin init [-h] [--gam] [--gyb] username
4848
4949
positional arguments:
50-
username The user's account name, sans domain.
50+
username A Compiler user account name, sans domain.
5151
5252
options:
5353
-h, --help show this help message and exit
54+
--gam If provided, initialize a new GAM project.
55+
--gyb If provided, initialize a new GYB project.
5456
```
5557
5658
The `init` commands follows the steps in the [GAMADV-XTD3 Wiki](https://github.com/taers232c/GAMADV-XTD3/wiki/#requirements).

compiler_admin/commands/init.py

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,44 +7,56 @@
77
from compiler_admin.services.google import USER_ARCHIVE, CallGAMCommand
88

99

10-
CONFIG_DIR = os.environ.get("GAMCFGDIR", "./.config")
11-
CONFIG_PATH = Path(CONFIG_DIR)
12-
CONFIG_PATH_NAME = str(CONFIG_PATH)
10+
GAM_CONFIG_DIR = os.environ.get("GAMCFGDIR", "./.config/gam")
11+
GAM_CONFIG_PATH = Path(GAM_CONFIG_DIR)
12+
GYB_CONFIG_PATH = GAM_CONFIG_PATH.parent / "gyb"
1313

1414

15-
def _clean_config_dir():
16-
for path in CONFIG_PATH.glob("**/*"):
15+
def _clean_config_dir(config_dir: Path) -> None:
16+
config_dir.mkdir(parents=True, exist_ok=True)
17+
for path in config_dir.glob("**/*"):
1718
if path.is_file():
1819
path.unlink()
1920
elif path.is_dir():
2021
rmtree(path)
2122

2223

23-
def init(admin_user: str) -> int:
24+
def init(admin_user: str, gam: bool = False, gyb: bool = False) -> int:
2425
"""Initialize a new GAM project.
2526
2627
See https://github.com/taers232c/GAMADV-XTD3/wiki/How-to-Install-Advanced-GAM
2728
2829
Args:
2930
admin_user (str): The Compiler admin with which to initialize a new project.
31+
32+
gam (bool): If True, initialize a new GAM project.
33+
34+
gyb (bool): If True, initialize a new GYB project.
35+
3036
Returns:
3137
A value indicating if the operation succeeded or failed.
3238
"""
33-
if CONFIG_PATH.exists():
34-
_clean_config_dir()
35-
36-
res = CallGAMCommand(("config", "drive_dir", CONFIG_PATH_NAME, "verify"))
37-
res += CallGAMCommand(("create", "project"))
38-
res += CallGAMCommand(("oauth", "create"))
39-
res += CallGAMCommand(("user", admin_user, "check", "serviceaccount"))
40-
41-
# download GYB installer to config directory
42-
gyb = CONFIG_PATH / "gyb-install.sh"
43-
with gyb.open("w+") as dest:
44-
res += subprocess.call(("curl", "-s", "-S", "-L", "https://gyb-shortn.jaylee.us/gyb-install"), stdout=dest)
45-
46-
# install, giving values to options that prompt by default
47-
# https://github.com/GAM-team/got-your-back/blob/main/install-gyb.sh
48-
res += subprocess.call((gyb, "-u", admin_user, "-r", USER_ARCHIVE))
39+
res = RESULT_SUCCESS
40+
41+
if gam:
42+
_clean_config_dir(GAM_CONFIG_PATH)
43+
# GAM is already installed via pyproject.toml
44+
res += CallGAMCommand(("config", "drive_dir", str(GAM_CONFIG_PATH), "verify"))
45+
res += CallGAMCommand(("create", "project"))
46+
res += CallGAMCommand(("oauth", "create"))
47+
res += CallGAMCommand(("user", admin_user, "check", "serviceaccount"))
48+
49+
if gyb:
50+
_clean_config_dir(GYB_CONFIG_PATH)
51+
# download GYB installer to config directory
52+
gyb = GYB_CONFIG_PATH / "gyb-install.sh"
53+
with gyb.open("w+") as dest:
54+
res += subprocess.call(("curl", "-s", "-S", "-L", "https://gyb-shortn.jaylee.us/gyb-install"), stdout=dest)
55+
56+
# install, giving values to some options
57+
# https://github.com/GAM-team/got-your-back/blob/main/install-gyb.sh
58+
#
59+
# use GYB_CONFIG_PATH.parent for the install directory option, otherwise we get a .config/gyb/gyb directory structure
60+
res += subprocess.call((gyb, "-u", admin_user, "-r", USER_ARCHIVE, "-d", str(GYB_CONFIG_PATH.parent)))
4961

5062
return RESULT_SUCCESS if res == RESULT_SUCCESS else RESULT_FAILURE

compiler_admin/main.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,12 @@ def _subcmd(name, help, add_username_arg=True) -> argparse.ArgumentParser:
3535

3636
_subcmd("info", help="Print configuration and debugging information.", add_username_arg=False)
3737

38-
_subcmd(
38+
init_parser = _subcmd(
3939
"init",
4040
help="Initialize a new admin project. This command should be run once before any others.",
4141
)
42+
init_parser.add_argument("--gam", action="store_true", help="If provided, initialize a new GAM project.")
43+
init_parser.add_argument("--gyb", action="store_true", help="If provided, initialize a new GYB project.")
4244

4345
_subcmd("create", help="Create a new user in the Compiler domain.")
4446

@@ -70,7 +72,7 @@ def _subcmd(name, help, add_username_arg=True) -> argparse.ArgumentParser:
7072
elif args.command == "delete":
7173
return delete(args.username)
7274
elif args.command == "init":
73-
return init(args.username)
75+
return init(args.username, gam=args.gam, gyb=args.gyb)
7476
elif args.command == "offboard":
7577
return offboard(args.username, args.alias)
7678
elif args.command == "restore":

compose.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ services:
55
dockerfile: .devcontainer/Dockerfile
66
image: compiler_admin:dev
77
environment:
8-
GAMCFGDIR: /home/compiler/.config/gam
8+
GAMCFGDIR: /home/compiler/.config/compiler-admin/gam
99
entrypoint: sleep infinity
1010
volumes:
11-
- ./:/home/compiler/admin
12-
- ./.config/:/home/compiler/.config/gam
13-
- ./.downloads/:/home/compiler/Downloads
11+
- .:/home/compiler/admin
12+
- ./.config:/home/compiler/.config/compiler-admin
13+
- ./.downloads:/home/compiler/Downloads

tests/commands/test_init.py

Lines changed: 43 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,21 @@
11
import pytest
22

3-
from compiler_admin.commands.init import init, __name__ as MODULE
3+
from compiler_admin.commands.init import _clean_config_dir, init, __name__ as MODULE
44

55

66
@pytest.fixture
7-
def mock_CONFIG_PATH(mocker):
8-
return mocker.patch(f"{MODULE}.CONFIG_PATH")
7+
def mock_rmtree(mocker):
8+
return mocker.patch(f"{MODULE}.rmtree")
9+
10+
11+
@pytest.fixture
12+
def mock_GAM_CONFIG_PATH(mocker):
13+
return mocker.patch(f"{MODULE}.GAM_CONFIG_PATH")
14+
15+
16+
@pytest.fixture
17+
def mock_GYB_CONFIG_PATH(mocker):
18+
return mocker.patch(f"{MODULE}.GYB_CONFIG_PATH")
919

1020

1121
@pytest.fixture
@@ -23,23 +33,43 @@ def mock_subprocess_call(mocker):
2333
return mocker.patch(f"{MODULE}.subprocess.call")
2434

2535

26-
def test_init_config_path_exists(mock_CONFIG_PATH, mock_clean_config_dir, mock_google_CallGAMCommand, mock_subprocess_call):
27-
mock_CONFIG_PATH.exists.return_value = True
36+
def test_clean_config_dir(mocker, mock_GAM_CONFIG_PATH, mock_rmtree):
37+
mock_file = mocker.Mock(is_file=mocker.Mock(return_value=True))
38+
mock_dir = mocker.Mock(is_file=mocker.Mock(return_value=False), is_dir=mocker.Mock(return_value=True))
2839

29-
init("username")
40+
mock_GAM_CONFIG_PATH.glob.return_value = [mock_file, mock_dir]
3041

31-
mock_clean_config_dir.assert_called_once()
32-
assert mock_google_CallGAMCommand.call_count > 0
33-
assert mock_subprocess_call.call_count > 0
42+
_clean_config_dir(mock_GAM_CONFIG_PATH)
3443

44+
mock_GAM_CONFIG_PATH.mkdir.assert_called_once()
45+
mock_GAM_CONFIG_PATH.glob.assert_called_once()
46+
mock_file.is_file.assert_called_once()
47+
mock_file.unlink.assert_called_once()
48+
mock_dir.is_file.assert_called_once()
49+
mock_dir.is_dir.assert_called_once()
50+
mock_rmtree.assert_called_once()
51+
assert mock_dir in mock_rmtree.call_args.args
3552

36-
def test_init_config_path_does_not_exist(
37-
mock_CONFIG_PATH, mock_clean_config_dir, mock_google_CallGAMCommand, mock_subprocess_call
38-
):
39-
mock_CONFIG_PATH.exists.return_value = False
4053

54+
def test_init_default(mock_clean_config_dir, mock_google_CallGAMCommand, mock_subprocess_call):
4155
init("username")
4256

4357
assert mock_clean_config_dir.call_count == 0
58+
assert mock_google_CallGAMCommand.call_count == 0
59+
assert mock_subprocess_call.call_count == 0
60+
61+
62+
def test_init_gam(mock_GAM_CONFIG_PATH, mock_clean_config_dir, mock_google_CallGAMCommand):
63+
init("username", gam=True, gyb=False)
64+
65+
mock_clean_config_dir.assert_called_once()
66+
assert mock_GAM_CONFIG_PATH in mock_clean_config_dir.call_args.args
4467
assert mock_google_CallGAMCommand.call_count > 0
68+
69+
70+
def test_init_gyb(mock_GYB_CONFIG_PATH, mock_clean_config_dir, mock_subprocess_call):
71+
init("username", gam=False, gyb=True)
72+
73+
mock_clean_config_dir.assert_called_once()
74+
assert mock_GYB_CONFIG_PATH in mock_clean_config_dir.call_args.args
4575
assert mock_subprocess_call.call_count > 0

tests/test_main.py

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,12 +108,28 @@ def test_main_info_default(mock_commands_info):
108108
mock_commands_info.assert_called_once()
109109

110110

111-
def test_main_init(mock_commands_init):
111+
def test_main_init_default(mock_commands_init):
112112
main(argv=["init", "username"])
113113

114114
mock_commands_init.assert_called_once()
115-
call_args = mock_commands_init.call_args.args
116-
assert "username" in call_args
115+
assert mock_commands_init.call_args.args == ("username",)
116+
assert mock_commands_init.call_args.kwargs == {"gam": False, "gyb": False}
117+
118+
119+
def test_main_init_gam(mock_commands_init):
120+
main(argv=["init", "username", "--gam"])
121+
122+
mock_commands_init.assert_called_once()
123+
assert mock_commands_init.call_args.args == ("username",)
124+
assert mock_commands_init.call_args.kwargs == {"gam": True, "gyb": False}
125+
126+
127+
def test_main_init_gyb(mock_commands_init):
128+
main(argv=["init", "username", "--gyb"])
129+
130+
mock_commands_init.assert_called_once()
131+
assert mock_commands_init.call_args.args == ("username",)
132+
assert mock_commands_init.call_args.kwargs == {"gam": False, "gyb": True}
117133

118134

119135
def test_main_init_no_username(mock_commands_init):

0 commit comments

Comments
 (0)