diracx-cli 0.0.1a6__tar.gz → 0.0.1a8__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. {diracx-cli-0.0.1a6 → diracx-cli-0.0.1a8}/PKG-INFO +1 -1
  2. diracx-cli-0.0.1a8/src/diracx/cli/internal/__init__.py +188 -0
  3. {diracx-cli-0.0.1a6 → diracx-cli-0.0.1a8}/src/diracx_cli.egg-info/PKG-INFO +1 -1
  4. diracx-cli-0.0.1a8/tests/test_internal.py +226 -0
  5. diracx-cli-0.0.1a6/src/diracx/cli/internal/__init__.py +0 -104
  6. diracx-cli-0.0.1a6/tests/test_internal.py +0 -72
  7. {diracx-cli-0.0.1a6 → diracx-cli-0.0.1a8}/README.md +0 -0
  8. {diracx-cli-0.0.1a6 → diracx-cli-0.0.1a8}/pyproject.toml +0 -0
  9. {diracx-cli-0.0.1a6 → diracx-cli-0.0.1a8}/setup.cfg +0 -0
  10. {diracx-cli-0.0.1a6 → diracx-cli-0.0.1a8}/src/diracx/cli/__init__.py +0 -0
  11. {diracx-cli-0.0.1a6 → diracx-cli-0.0.1a8}/src/diracx/cli/__main__.py +0 -0
  12. {diracx-cli-0.0.1a6 → diracx-cli-0.0.1a8}/src/diracx/cli/internal/legacy.py +0 -0
  13. {diracx-cli-0.0.1a6 → diracx-cli-0.0.1a8}/src/diracx/cli/jobs.py +0 -0
  14. {diracx-cli-0.0.1a6 → diracx-cli-0.0.1a8}/src/diracx/cli/py.typed +0 -0
  15. {diracx-cli-0.0.1a6 → diracx-cli-0.0.1a8}/src/diracx/cli/utils.py +0 -0
  16. {diracx-cli-0.0.1a6 → diracx-cli-0.0.1a8}/src/diracx_cli.egg-info/SOURCES.txt +0 -0
  17. {diracx-cli-0.0.1a6 → diracx-cli-0.0.1a8}/src/diracx_cli.egg-info/dependency_links.txt +0 -0
  18. {diracx-cli-0.0.1a6 → diracx-cli-0.0.1a8}/src/diracx_cli.egg-info/entry_points.txt +0 -0
  19. {diracx-cli-0.0.1a6 → diracx-cli-0.0.1a8}/src/diracx_cli.egg-info/requires.txt +0 -0
  20. {diracx-cli-0.0.1a6 → diracx-cli-0.0.1a8}/src/diracx_cli.egg-info/top_level.txt +0 -0
  21. {diracx-cli-0.0.1a6 → diracx-cli-0.0.1a8}/tests/legacy/cs_sync/convert_integration_test.yaml +0 -0
  22. {diracx-cli-0.0.1a6 → diracx-cli-0.0.1a8}/tests/legacy/cs_sync/integration_test.cfg +0 -0
  23. {diracx-cli-0.0.1a6 → diracx-cli-0.0.1a8}/tests/legacy/cs_sync/integration_test.yaml +0 -0
  24. {diracx-cli-0.0.1a6 → diracx-cli-0.0.1a8}/tests/legacy/cs_sync/integration_test_secret.cfg +0 -0
  25. {diracx-cli-0.0.1a6 → diracx-cli-0.0.1a8}/tests/legacy/cs_sync/test_cssync.py +0 -0
  26. {diracx-cli-0.0.1a6 → diracx-cli-0.0.1a8}/tests/legacy/test_legacy.py +0 -0
  27. {diracx-cli-0.0.1a6 → diracx-cli-0.0.1a8}/tests/test_jobs.py +0 -0
  28. {diracx-cli-0.0.1a6 → diracx-cli-0.0.1a8}/tests/test_login.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: diracx-cli
3
- Version: 0.0.1a6
3
+ Version: 0.0.1a8
4
4
  Summary: TODO
5
5
  License: GPL-3.0-only
6
6
  Classifier: Intended Audience :: Science/Research
@@ -0,0 +1,188 @@
1
+ from pathlib import Path
2
+ from typing import Annotated, Optional
3
+
4
+ import git
5
+ import typer
6
+ import yaml
7
+ from pydantic import parse_obj_as
8
+
9
+ from diracx.core.config import ConfigSource, ConfigSourceUrl
10
+ from diracx.core.config.schema import (
11
+ Config,
12
+ DIRACConfig,
13
+ GroupConfig,
14
+ IdpConfig,
15
+ OperationsConfig,
16
+ RegistryConfig,
17
+ UserConfig,
18
+ )
19
+
20
+ from ..utils import AsyncTyper
21
+ from . import legacy
22
+
23
+ app = AsyncTyper()
24
+ app.add_typer(legacy.app, name="legacy")
25
+
26
+
27
+ @app.command()
28
+ def generate_cs(
29
+ config_repo: str,
30
+ ):
31
+ """Generate a minimal DiracX configuration repository"""
32
+ # TODO: The use of parse_obj_as should be moved in to typer itself
33
+ config_repo = parse_obj_as(ConfigSourceUrl, config_repo)
34
+ if config_repo.scheme != "git+file":
35
+ raise NotImplementedError("Only git+file:// URLs are supported")
36
+ repo_path = Path(config_repo.path)
37
+ if repo_path.exists() and list(repo_path.iterdir()):
38
+ typer.echo(f"ERROR: Directory {repo_path} already exists", err=True)
39
+ raise typer.Exit(1)
40
+
41
+ config = Config(
42
+ Registry={},
43
+ DIRAC=DIRACConfig(),
44
+ Operations={"Defaults": OperationsConfig()},
45
+ )
46
+
47
+ update_config_and_commit(
48
+ repo_path=repo_path, config=config, message="Initial commit"
49
+ )
50
+ typer.echo(f"Successfully created repo in {config_repo}", err=True)
51
+
52
+
53
+ @app.command()
54
+ def add_vo(
55
+ config_repo: str,
56
+ *,
57
+ vo: Annotated[str, typer.Option()],
58
+ default_group: Optional[str] = "user",
59
+ idp_url: Annotated[str, typer.Option()],
60
+ idp_client_id: Annotated[str, typer.Option()],
61
+ ):
62
+ """Add a registry entry (vo) to an existing configuration repository"""
63
+
64
+ # TODO: The use of parse_obj_as should be moved in to typer itself
65
+ config_repo = parse_obj_as(ConfigSourceUrl, config_repo)
66
+ repo_path = Path(config_repo.path)
67
+
68
+ # A VO should at least contain a default group
69
+ new_registry = RegistryConfig(
70
+ IdP=IdpConfig(URL=idp_url, ClientID=idp_client_id),
71
+ DefaultGroup=default_group,
72
+ Users={},
73
+ Groups={
74
+ default_group: GroupConfig(
75
+ Properties={"NormalUser"}, Quota=None, Users=set()
76
+ )
77
+ },
78
+ )
79
+
80
+ config = ConfigSource.create_from_url(backend_url=repo_path).read_config()
81
+
82
+ if vo in config.Registry:
83
+ typer.echo(f"ERROR: VO {vo} already exists", err=True)
84
+ raise typer.Exit(1)
85
+
86
+ config.Registry[vo] = new_registry
87
+
88
+ update_config_and_commit(
89
+ repo_path=repo_path,
90
+ config=config,
91
+ message=f"Added vo {vo} registry (default group {default_group} and idp {idp_url})",
92
+ )
93
+ typer.echo(f"Successfully added vo to {config_repo}", err=True)
94
+
95
+
96
+ @app.command()
97
+ def add_group(
98
+ config_repo: str,
99
+ *,
100
+ vo: Annotated[str, typer.Option()],
101
+ group: Annotated[str, typer.Option()],
102
+ properties: list[str] = ["NormalUser"],
103
+ ):
104
+ """Add a group to an existing vo in the configuration repository"""
105
+
106
+ # TODO: The use of parse_obj_as should be moved in to typer itself
107
+ config_repo = parse_obj_as(ConfigSourceUrl, config_repo)
108
+ repo_path = Path(config_repo.path)
109
+
110
+ new_group = GroupConfig(Properties=set(properties), Quota=None, Users=set())
111
+
112
+ config = ConfigSource.create_from_url(backend_url=repo_path).read_config()
113
+
114
+ if vo not in config.Registry:
115
+ typer.echo(f"ERROR: Virtual Organization {vo} does not exist", err=True)
116
+ raise typer.Exit(1)
117
+
118
+ if group in config.Registry[vo].Groups.keys():
119
+ typer.echo(f"ERROR: Group {group} already exists in {vo}", err=True)
120
+ raise typer.Exit(1)
121
+
122
+ config.Registry[vo].Groups[group] = new_group
123
+
124
+ update_config_and_commit(
125
+ repo_path=repo_path, config=config, message=f"Added group {group} in {vo}"
126
+ )
127
+ typer.echo(f"Successfully added group to {config_repo}", err=True)
128
+
129
+
130
+ @app.command()
131
+ def add_user(
132
+ config_repo: str,
133
+ *,
134
+ vo: Annotated[str, typer.Option()],
135
+ groups: Annotated[Optional[list[str]], typer.Option("--group")] = None,
136
+ sub: Annotated[str, typer.Option()],
137
+ preferred_username: Annotated[str, typer.Option()],
138
+ ):
139
+ """Add a user to an existing vo and group"""
140
+
141
+ # TODO: The use of parse_obj_as should be moved in to typer itself
142
+ config_repo = parse_obj_as(ConfigSourceUrl, config_repo)
143
+
144
+ repo_path = Path(config_repo.path)
145
+
146
+ new_user = UserConfig(PreferedUsername=preferred_username)
147
+
148
+ config = ConfigSource.create_from_url(backend_url=repo_path).read_config()
149
+
150
+ if vo not in config.Registry:
151
+ typer.echo(f"ERROR: Virtual Organization {vo} does not exist", err=True)
152
+ raise typer.Exit(1)
153
+
154
+ if sub in config.Registry[vo].Users:
155
+ typer.echo(f"ERROR: User {sub} already exists", err=True)
156
+ raise typer.Exit(1)
157
+
158
+ config.Registry[vo].Users[sub] = new_user
159
+
160
+ if not groups:
161
+ groups = [config.Registry[vo].DefaultGroup]
162
+
163
+ for group in set(groups):
164
+ if group not in config.Registry[vo].Groups:
165
+ typer.echo(f"ERROR: Group {group} does not exist in {vo}", err=True)
166
+ raise typer.Exit(1)
167
+ if sub in config.Registry[vo].Groups[group].Users:
168
+ typer.echo(f"ERROR: User {sub} already exists in group {group}", err=True)
169
+ raise typer.Exit(1)
170
+
171
+ config.Registry[vo].Groups[group].Users.add(sub)
172
+
173
+ update_config_and_commit(
174
+ repo_path=repo_path,
175
+ config=config,
176
+ message=f"Added user {sub} ({preferred_username}) to vo {vo} and groups {groups}",
177
+ )
178
+ typer.echo(f"Successfully added user to {config_repo}", err=True)
179
+
180
+
181
+ def update_config_and_commit(repo_path: Path, config: Config, message: str):
182
+ """Update the yaml file in the repo and commit it"""
183
+ repo = git.Repo.init(repo_path)
184
+ yaml_path = repo_path / "default.yml"
185
+ typer.echo(f"Writing back configuration to {yaml_path}", err=True)
186
+ yaml_path.write_text(yaml.safe_dump(config.dict(exclude_unset=True)))
187
+ repo.index.add([yaml_path.relative_to(repo_path)])
188
+ repo.index.commit(message)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: diracx-cli
3
- Version: 0.0.1a6
3
+ Version: 0.0.1a8
4
4
  Summary: TODO
5
5
  License: GPL-3.0-only
6
6
  Classifier: Intended Audience :: Science/Research
@@ -0,0 +1,226 @@
1
+ from __future__ import annotations
2
+
3
+ import pytest
4
+ from typer.testing import CliRunner
5
+
6
+ from diracx.cli import app
7
+ from diracx.core.config import ConfigSource
8
+
9
+ runner = CliRunner()
10
+
11
+
12
+ @pytest.mark.parametrize("protocol", [None, "git+file://"])
13
+ def test_generate_cs(tmp_path, protocol):
14
+ cs_repo = f"{tmp_path}"
15
+ if protocol is None:
16
+ cs_repo = f"git+file://{cs_repo}"
17
+
18
+ result = runner.invoke(app, ["internal", "generate-cs", cs_repo])
19
+ assert result.exit_code == 0
20
+ assert (tmp_path / ".git").is_dir()
21
+ assert (tmp_path / "default.yml").is_file()
22
+
23
+ # Running a second time should fail
24
+ result = runner.invoke(app, ["internal", "generate-cs", cs_repo])
25
+ assert result.exit_code != 0
26
+
27
+
28
+ def test_add_vo(tmp_path):
29
+ cs_repo = f"git+file://{tmp_path}"
30
+
31
+ # Create the CS
32
+ runner.invoke(app, ["internal", "generate-cs", cs_repo])
33
+
34
+ # Add a VO to it
35
+ vo1 = "testvo"
36
+ result = runner.invoke(
37
+ app,
38
+ [
39
+ "internal",
40
+ "add-vo",
41
+ cs_repo,
42
+ f"--vo={vo1}",
43
+ "--idp-url=https://idp.invalid",
44
+ "--idp-client-id=idp-client-id",
45
+ ],
46
+ )
47
+ assert result.exit_code == 0, result.output
48
+
49
+ config = ConfigSource.create_from_url(backend_url=cs_repo).read_config()
50
+
51
+ assert vo1 in config.Registry
52
+ assert config.Registry[vo1].DefaultGroup == "user"
53
+ assert config.Registry[vo1].IdP.URL == "https://idp.invalid"
54
+ assert config.Registry[vo1].IdP.ClientID == "idp-client-id"
55
+
56
+ # Add a second VO to it
57
+ vo2 = "lhcb"
58
+ result = runner.invoke(
59
+ app,
60
+ [
61
+ "internal",
62
+ "add-vo",
63
+ cs_repo,
64
+ f"--vo={vo2}",
65
+ "--idp-url=https://idp.example.invalid",
66
+ "--idp-client-id=idp-client-id2",
67
+ "--default-group",
68
+ "admin",
69
+ ],
70
+ )
71
+
72
+ config = ConfigSource.create_from_url(backend_url=cs_repo).read_config()
73
+ assert result.exit_code == 0, result.output
74
+
75
+ assert vo2 in config.Registry
76
+ assert config.Registry[vo2].DefaultGroup == "admin"
77
+ assert config.Registry[vo2].IdP.URL == "https://idp.example.invalid"
78
+ assert config.Registry[vo2].IdP.ClientID == "idp-client-id2"
79
+
80
+ # Try to insert a VO that already exists
81
+ result = runner.invoke(
82
+ app,
83
+ [
84
+ "internal",
85
+ "add-vo",
86
+ cs_repo,
87
+ f"--vo={vo1}",
88
+ "--idp-url=https://idp.invalid",
89
+ "--idp-client-id=idp-client-id",
90
+ ],
91
+ )
92
+ assert result.exit_code != 0, result.output
93
+
94
+
95
+ def test_add_group(tmp_path):
96
+ cs_repo = f"git+file://{tmp_path}"
97
+ vo = "testvo"
98
+ group1 = "testgroup1"
99
+ group2 = "testgroup2"
100
+
101
+ # Create the CS
102
+ runner.invoke(app, ["internal", "generate-cs", cs_repo])
103
+ runner.invoke(
104
+ app,
105
+ [
106
+ "internal",
107
+ "add-vo",
108
+ cs_repo,
109
+ f"--vo={vo}",
110
+ "--idp-url=https://idp.invalid",
111
+ "--idp-client-id=idp-client-id",
112
+ ],
113
+ )
114
+
115
+ # Add a group to it
116
+ result = runner.invoke(
117
+ app, ["internal", "add-group", cs_repo, f"--vo={vo}", f"--group={group1}"]
118
+ )
119
+ assert result.exit_code == 0, result.output
120
+
121
+ config = ConfigSource.create_from_url(backend_url=cs_repo).read_config()
122
+
123
+ assert group1 in config.Registry[vo].Groups
124
+ assert config.Registry[vo].Groups[group1].JobShare == 1000
125
+ assert config.Registry[vo].Groups[group1].Properties == {"NormalUser"}
126
+ assert config.Registry[vo].Groups[group1].Users == set()
127
+
128
+ # Add a second group to it
129
+ result = runner.invoke(
130
+ app,
131
+ [
132
+ "internal",
133
+ "add-group",
134
+ cs_repo,
135
+ f"--vo={vo}",
136
+ f"--group={group2}",
137
+ "--properties",
138
+ "NormalUser",
139
+ "--properties",
140
+ "AdminUser",
141
+ ],
142
+ )
143
+ config = ConfigSource.create_from_url(backend_url=cs_repo).read_config()
144
+ assert result.exit_code == 0, result.output
145
+
146
+ assert group2 in config.Registry[vo].Groups
147
+ assert config.Registry[vo].Groups[group2].JobShare == 1000
148
+ assert config.Registry[vo].Groups[group2].Properties == {"AdminUser", "NormalUser"}
149
+ assert config.Registry[vo].Groups[group2].Users == set()
150
+
151
+ # Try to insert a group that already exists
152
+ result = runner.invoke(
153
+ app, ["internal", "add-group", cs_repo, f"--vo={vo}", f"--group={group1}"]
154
+ )
155
+ assert result.exit_code != 0, result.output
156
+
157
+ # Try to insert a group with a non-existing VO
158
+ result = runner.invoke(
159
+ app,
160
+ ["internal", "add-group", cs_repo, "--vo=nonexistingvo", f"--group={group1}"],
161
+ )
162
+ assert result.exit_code != 0, result.output
163
+
164
+
165
+ @pytest.mark.parametrize("vo", ["nonexistingvo", "testvo"])
166
+ @pytest.mark.parametrize(
167
+ "user_group", [["nonexisting_group"], ["user"], ["user", "admin"], []]
168
+ )
169
+ def test_add_user(tmp_path, vo, user_group):
170
+ cs_repo = f"git+file://{tmp_path}"
171
+
172
+ sub = "lhcb:chaen"
173
+ preferred_username = "dontCallMeShirley"
174
+
175
+ # Create the CS
176
+ runner.invoke(app, ["internal", "generate-cs", cs_repo])
177
+ runner.invoke(
178
+ app,
179
+ [
180
+ "internal",
181
+ "add-vo",
182
+ cs_repo,
183
+ "--vo=testvo",
184
+ "--idp-url=https://idp.invalid",
185
+ "--idp-client-id=idp-client-id",
186
+ ],
187
+ )
188
+ runner.invoke(
189
+ app, ["internal", "add-group", cs_repo, "--vo=testvo", "--group=user"]
190
+ )
191
+ runner.invoke(
192
+ app, ["internal", "add-group", cs_repo, "--vo=testvo", "--group=admin"]
193
+ )
194
+
195
+ config = ConfigSource.create_from_url(backend_url=cs_repo).read_config()
196
+
197
+ # Check the user isn't in it
198
+ if vo in config.Registry:
199
+ assert sub not in config.Registry[vo].Users
200
+
201
+ # Add a user to it
202
+ result = runner.invoke(
203
+ app,
204
+ [
205
+ "internal",
206
+ "add-user",
207
+ cs_repo,
208
+ f"--vo={vo}",
209
+ f"--sub={sub}",
210
+ f"--preferred-username={preferred_username}",
211
+ ]
212
+ + [f"--group={x}" for x in user_group],
213
+ )
214
+
215
+ if "nonexistingvo" in vo or "nonexisting_group" in user_group:
216
+ assert result.exit_code != 0
217
+ return
218
+
219
+ assert result.exit_code == 0, result.output
220
+
221
+ config = ConfigSource.create_from_url(backend_url=cs_repo).read_config()
222
+ # check the user is defined
223
+ assert vo in config.Registry
224
+ assert sub in config.Registry[vo].Users
225
+ for group in user_group or ["user"]:
226
+ assert config.Registry[vo].Groups[group].Users == {sub}
@@ -1,104 +0,0 @@
1
- from pathlib import Path
2
-
3
- import git
4
- import typer
5
- import yaml
6
- from pydantic import parse_obj_as
7
-
8
- from diracx.core.config import ConfigSource, ConfigSourceUrl
9
- from diracx.core.config.schema import (
10
- Config,
11
- DIRACConfig,
12
- GroupConfig,
13
- IdpConfig,
14
- OperationsConfig,
15
- RegistryConfig,
16
- UserConfig,
17
- )
18
-
19
- from ..utils import AsyncTyper
20
- from . import legacy
21
-
22
- app = AsyncTyper()
23
- app.add_typer(legacy.app, name="legacy")
24
-
25
-
26
- @app.command()
27
- def generate_cs(
28
- config_repo: str,
29
- *,
30
- vo: str = "testvo",
31
- user_group: str = "user",
32
- idp_url: str = "https://idp.invalid",
33
- idp_client_id: str = "idp-client-id",
34
- ):
35
- """Generate a minimal DiracX configuration repository"""
36
- # TODO: The use of parse_obj_as should be moved in to typer itself
37
- config_repo = parse_obj_as(ConfigSourceUrl, config_repo)
38
- if config_repo.scheme != "git+file":
39
- raise NotImplementedError("Only git+file:// URLs are supported")
40
- repo_path = Path(config_repo.path)
41
- if repo_path.exists() and list(repo_path.iterdir()):
42
- typer.echo(f"ERROR: Directory {repo_path} already exists", err=True)
43
- raise typer.Exit(1)
44
-
45
- registry = RegistryConfig(
46
- IdP=IdpConfig(URL=idp_url, ClientID=idp_client_id),
47
- DefaultGroup=user_group,
48
- Users={},
49
- Groups={
50
- user_group: GroupConfig(Properties={"NormalUser"}, Quota=None, Users=set())
51
- },
52
- )
53
- config = Config(
54
- Registry={vo: registry},
55
- DIRAC=DIRACConfig(),
56
- Operations={"Defaults": OperationsConfig()},
57
- )
58
-
59
- repo = git.Repo.init(repo_path, initial_branch="master")
60
- yaml_path = repo_path / "default.yml"
61
- typer.echo(f"Writing configuration to {yaml_path}", err=True)
62
- yaml_path.write_text(yaml.safe_dump(config.dict(exclude_unset=True)))
63
- repo.index.add([yaml_path.relative_to(repo_path)])
64
- repo.index.commit("Initial commit")
65
- typer.echo(f"Successfully created repo in {config_repo}", err=True)
66
-
67
-
68
- @app.command()
69
- def add_user(
70
- config_repo: str,
71
- *,
72
- vo: str = "testvo",
73
- user_group: str = "user",
74
- sub: str = "usersub",
75
- preferred_username: str = "preferred_username",
76
- ):
77
- """Add a user to an existing vo and group"""
78
-
79
- # TODO: The use of parse_obj_as should be moved in to typer itself
80
- config_repo = parse_obj_as(ConfigSourceUrl, config_repo)
81
-
82
- repo_path = Path(config_repo.path)
83
-
84
- new_user = UserConfig(PreferedUsername=preferred_username)
85
-
86
- config = ConfigSource.create_from_url(backend_url=repo_path).read_config()
87
-
88
- if sub in config.Registry[vo].Users:
89
- typer.echo(f"ERROR: User {sub} already exists", err=True)
90
- raise typer.Exit(1)
91
-
92
- config.Registry[vo].Users[sub] = new_user
93
-
94
- config.Registry[vo].Groups[user_group].Users.add(sub)
95
-
96
- repo = git.Repo.init(repo_path)
97
- yaml_path = repo_path / "default.yml"
98
- typer.echo(f"Writing back configuration to {yaml_path}", err=True)
99
- yaml_path.write_text(yaml.safe_dump(config.dict(exclude_unset=True)))
100
- repo.index.add([yaml_path.relative_to(repo_path)])
101
- repo.index.commit(
102
- f"Added user {sub} ({preferred_username}) to vo {vo} and user_group {user_group}"
103
- )
104
- typer.echo(f"Successfully added user to {config_repo}", err=True)
@@ -1,72 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import pytest
4
- from typer.testing import CliRunner
5
-
6
- from diracx.cli import app
7
- from diracx.core.config import ConfigSource
8
-
9
- runner = CliRunner()
10
-
11
-
12
- @pytest.mark.parametrize("protocol", [None, "git+file://"])
13
- def test_generate_cs(tmp_path, protocol):
14
- cs_repo = f"{tmp_path}"
15
- if protocol is None:
16
- cs_repo = f"git+file://{cs_repo}"
17
-
18
- result = runner.invoke(app, ["internal", "generate-cs", cs_repo])
19
- assert result.exit_code == 0
20
- assert (tmp_path / ".git").is_dir()
21
- assert (tmp_path / "default.yml").is_file()
22
-
23
- # Running a second time should fail
24
- result = runner.invoke(app, ["internal", "generate-cs", cs_repo])
25
- assert result.exit_code != 0
26
-
27
-
28
- @pytest.mark.parametrize("vo", ["nonexistingvo", "testvo"])
29
- @pytest.mark.parametrize("user_group", ["nonexisting_group", "user"])
30
- def test_add_user(tmp_path, vo, user_group):
31
- cs_repo = f"git+file://{tmp_path}"
32
-
33
- sub = "lhcb:chaen"
34
- preferred_username = "dontCallMeShirley"
35
-
36
- # Create the CS
37
- runner.invoke(app, ["internal", "generate-cs", cs_repo])
38
-
39
- config = ConfigSource.create_from_url(backend_url=cs_repo).read_config()
40
-
41
- # Check the user isn't in it
42
- if vo in config.Registry:
43
- assert sub not in config.Registry[vo].Users
44
-
45
- # Add a user to it
46
- result = runner.invoke(
47
- app,
48
- [
49
- "internal",
50
- "add-user",
51
- cs_repo,
52
- "--vo",
53
- vo,
54
- "--user-group",
55
- user_group,
56
- "--sub",
57
- sub,
58
- "--preferred-username",
59
- preferred_username,
60
- ],
61
- )
62
-
63
- if "nonexisting" in vo or "nonexisting" in user_group:
64
- assert result.exit_code != 0
65
- return
66
-
67
- assert result.exit_code == 0, result.output
68
-
69
- config = ConfigSource.create_from_url(backend_url=cs_repo).read_config()
70
- # check the user is defined
71
- assert vo in config.Registry
72
- assert sub in config.Registry[vo].Users
File without changes
File without changes