Skip to content

Commit 5cb9403

Browse files
authored
feat: implement quota endpoint into cli (#12)
2 parents 7dc07c1 + 16483b8 commit 5cb9403

4 files changed

Lines changed: 135 additions & 10 deletions

File tree

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
*.pyc
22
dist/
3+
4+
.DS_Store

labctl/commands/admin/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import typer
22
from .users import app as users_app
33
from .vpn import app as vpn_app
4+
from .quota import app as quota_app
45

56
app = typer.Typer()
67

78
app.add_typer(users_app, name="users")
8-
app.add_typer(vpn_app, name="vpn")
9+
app.add_typer(vpn_app, name="vpn")
10+
app.add_typer(quota_app, name="quota")

labctl/commands/admin/quota.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
from typing import Optional
2+
import typer
3+
4+
from rich.table import Table
5+
6+
from labctl.core import Config, APIDriver, console
7+
8+
app = typer.Typer()
9+
10+
@app.command(name="show")
11+
def show_user(username: str):
12+
config = Config()
13+
api_driver = APIDriver()
14+
user_adjustements_list = api_driver.get(f"/quota/user/{username}/adjustements")
15+
if user_adjustements_list.status_code == 404:
16+
console.print(f"User {username} not found")
17+
return
18+
19+
data_total = {}
20+
21+
table_adjustements = Table(title="User quota adjustements")
22+
table_adjustements.add_column("ID", style="cyan")
23+
table_adjustements.add_column("Type", style="magenta")
24+
table_adjustements.add_column("Value", style="yellow")
25+
table_adjustements.add_column("Comment", style="green")
26+
27+
for quota_adjustement in user_adjustements_list.json():
28+
table_adjustements.add_row(
29+
str(quota_adjustement["id"]),
30+
quota_adjustement["type"],
31+
str(quota_adjustement["quantity"]),
32+
quota_adjustement["comment"],
33+
)
34+
if quota_adjustement["type"] not in data_total:
35+
data_total[quota_adjustement["type"]] = 0
36+
data_total[quota_adjustement["type"]] += quota_adjustement["quantity"]
37+
38+
console.print(table_adjustements)
39+
console.print("Total:")
40+
for key, value in data_total.items():
41+
console.print(f" {key}: {value}")
42+
43+
@app.command(name="add")
44+
def add_quota_adjustement(username: str, quota_type: str, quantity: int, comment: Optional[str] = None):
45+
payload = {
46+
"username": username,
47+
"type": quota_type,
48+
"quantity": quantity,
49+
"comment": comment,
50+
}
51+
rsp = APIDriver().post("/quota/adjust-user", json=payload)
52+
if rsp.status_code >= 400:
53+
console.print(f"[red]Error: {rsp.text}[/red]")
54+
return
55+
console.print(f"Adjustement added successfully")
56+
57+
@app.command(name="del")
58+
def delete_quota_adjustement(adjustement_id: int, confirm: bool = typer.Option(False, "--confirm", help="Confirm the deletion")):
59+
# todo add confirmation with a get before to validate the information of this id
60+
if not confirm:
61+
console.print("Deletion not confirmed")
62+
return
63+
rsp = APIDriver().delete(f"/quota/adjust-user/{adjustement_id}")
64+
if rsp.status_code >= 400:
65+
console.print(f"[red]Error: {rsp.text}[/red]")
66+
return
67+
console.print(f"Adjustement deleted successfully")

labctl/commands/openstack.py

Lines changed: 63 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,14 @@
1+
from typing import Optional
12
from typer import Typer
23
from labctl.core import cli_ready, Config, APIDriver, console
3-
from rich.progress import Progress
44
from rich.table import Table
55

66
app = Typer()
77
project = Typer()
8+
quota = Typer()
9+
810
app.add_typer(project, name="project")
9-
## OpenStack commands
10-
# reset-password
11-
# project list
12-
# project create <name>
13-
# project delete <name>
14-
# project add-user <project> <user>
15-
# project del-user <project> <user>
16-
# project list-users <project>
11+
app.add_typer(quota, name="quota")
1712

1813
@cli_ready
1914
@app.command(name="reset-password")
@@ -103,3 +98,62 @@ def del_user(project: str, user: str):
10398
console.print(f"[red]Error: {call.text}[/red]")
10499
return
105100
console.print(f"[green]User {user} deleted from project {project}[/green]")
101+
102+
# quota
103+
@cli_ready
104+
@quota.command(name="show-project")
105+
def show_project_quota(project: str):
106+
"""
107+
List OpenStack project quota
108+
"""
109+
call = APIDriver().get(f"/quota/project/{project}/adjustements")
110+
if call.status_code >= 400:
111+
console.print(f"[red]Error: {call.text}[/red]")
112+
return
113+
table = Table(title="Quotas for project " + project)
114+
115+
table.add_column("Id")
116+
table.add_column("Type")
117+
table.add_column("Quantity")
118+
table.add_column("User")
119+
table.add_column("Comment")
120+
121+
for quota in call.json():
122+
table.add_row(str(quota['id']), quota['type'], str(quota['quantity']), quota['username'], quota['comment'])
123+
124+
console.print(table)
125+
126+
# labctl openstack quota add PROJECT_NAME QUOTATYPE VALUE
127+
@cli_ready
128+
@quota.command(name="add")
129+
def add_quota(project: str, quota_type: str, quantity: int, comment: Optional[str] = None):
130+
"""
131+
Add quota to OpenStack project
132+
"""
133+
config = Config()
134+
console.print(f"[cyan]Adding {quota_type}={quantity} to OpenStack project {project}[/cyan]")
135+
payload = {
136+
"username": config.username,
137+
"project_name": project,
138+
"type": quota_type,
139+
"quantity": quantity,
140+
"comment": comment
141+
}
142+
call = APIDriver().post(f"/quota/adjust-project", json=payload)
143+
if call.status_code >= 400:
144+
console.print(f"[red]Error: {call.text}[/red]")
145+
return
146+
console.print(f"[green]Quota {quota_type}={quantity} added to project {project}[/green]")
147+
148+
@cli_ready
149+
@quota.command(name="del")
150+
def del_quota(id: int):
151+
"""
152+
Delete quota from OpenStack project
153+
"""
154+
console.print(f"[cyan]Deleting quota {id} from OpenStack project[/cyan]")
155+
call = APIDriver().delete(f"/quota/adjust-project/{id}/{Config().username}")
156+
if call.status_code >= 400:
157+
console.print(f"[red]Error: {call.text}[/red]")
158+
return
159+
console.print(f"[green]Quota {id} deleted from project[/green]")

0 commit comments

Comments
 (0)