Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
*.pyc
dist/

.DS_Store
4 changes: 3 additions & 1 deletion labctl/commands/admin/__init__.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import typer
from .users import app as users_app
from .vpn import app as vpn_app
from .quota import app as quota_app

app = typer.Typer()

app.add_typer(users_app, name="users")
app.add_typer(vpn_app, name="vpn")
app.add_typer(vpn_app, name="vpn")
app.add_typer(quota_app, name="quota")
67 changes: 67 additions & 0 deletions labctl/commands/admin/quota.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
from typing import Optional
import typer

from rich.table import Table

from labctl.core import Config, APIDriver, console

app = typer.Typer()

@app.command(name="show")
def show_user(username: str):
config = Config()
api_driver = APIDriver()
user_adjustements_list = api_driver.get(f"/quota/user/{username}/adjustements")
if user_adjustements_list.status_code == 404:
console.print(f"User {username} not found")
return

data_total = {}

table_adjustements = Table(title="User quota adjustements")
table_adjustements.add_column("ID", style="cyan")
table_adjustements.add_column("Type", style="magenta")
table_adjustements.add_column("Value", style="yellow")
table_adjustements.add_column("Comment", style="green")

for quota_adjustement in user_adjustements_list.json():
table_adjustements.add_row(
str(quota_adjustement["id"]),
quota_adjustement["type"],
str(quota_adjustement["quantity"]),
quota_adjustement["comment"],
)
if quota_adjustement["type"] not in data_total:
data_total[quota_adjustement["type"]] = 0
data_total[quota_adjustement["type"]] += quota_adjustement["quantity"]

console.print(table_adjustements)
console.print("Total:")
for key, value in data_total.items():
console.print(f" {key}: {value}")

@app.command(name="add")
def add_quota_adjustement(username: str, quota_type: str, quantity: int, comment: Optional[str] = None):
payload = {
"username": username,
"type": quota_type,
"quantity": quantity,
"comment": comment,
}
rsp = APIDriver().post("/quota/adjust-user", json=payload)
if rsp.status_code >= 400:
console.print(f"[red]Error: {rsp.text}[/red]")
return
console.print(f"Adjustement added successfully")

@app.command(name="del")
def delete_quota_adjustement(adjustement_id: int, confirm: bool = typer.Option(False, "--confirm", help="Confirm the deletion")):
# todo add confirmation with a get before to validate the information of this id
if not confirm:
console.print("Deletion not confirmed")
return
rsp = APIDriver().delete(f"/quota/adjust-user/{adjustement_id}")
if rsp.status_code >= 400:
console.print(f"[red]Error: {rsp.text}[/red]")
return
console.print(f"Adjustement deleted successfully")
72 changes: 63 additions & 9 deletions labctl/commands/openstack.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
from typing import Optional
from typer import Typer
from labctl.core import cli_ready, Config, APIDriver, console
from rich.progress import Progress
from rich.table import Table

app = Typer()
project = Typer()
quota = Typer()

app.add_typer(project, name="project")
## OpenStack commands
# reset-password
# project list
# project create <name>
# project delete <name>
# project add-user <project> <user>
# project del-user <project> <user>
# project list-users <project>
app.add_typer(quota, name="quota")

@cli_ready
@app.command(name="reset-password")
Expand Down Expand Up @@ -103,3 +98,62 @@ def del_user(project: str, user: str):
console.print(f"[red]Error: {call.text}[/red]")
return
console.print(f"[green]User {user} deleted from project {project}[/green]")

# quota
@cli_ready
@quota.command(name="show-project")
def show_project_quota(project: str):
"""
List OpenStack project quota
"""
call = APIDriver().get(f"/quota/project/{project}/adjustements")
if call.status_code >= 400:
console.print(f"[red]Error: {call.text}[/red]")
return
table = Table(title="Quotas for project " + project)

table.add_column("Id")
table.add_column("Type")
table.add_column("Quantity")
table.add_column("User")
table.add_column("Comment")

for quota in call.json():
table.add_row(str(quota['id']), quota['type'], str(quota['quantity']), quota['username'], quota['comment'])

console.print(table)

# labctl openstack quota add PROJECT_NAME QUOTATYPE VALUE
@cli_ready
@quota.command(name="add")
def add_quota(project: str, quota_type: str, quantity: int, comment: Optional[str] = None):
"""
Add quota to OpenStack project
"""
config = Config()
console.print(f"[cyan]Adding {quota_type}={quantity} to OpenStack project {project}[/cyan]")
payload = {
"username": config.username,
"project_name": project,
"type": quota_type,
"quantity": quantity,
"comment": comment
}
call = APIDriver().post(f"/quota/adjust-project", json=payload)
if call.status_code >= 400:
console.print(f"[red]Error: {call.text}[/red]")
return
console.print(f"[green]Quota {quota_type}={quantity} added to project {project}[/green]")

@cli_ready
@quota.command(name="del")
def del_quota(id: int):
"""
Delete quota from OpenStack project
"""
console.print(f"[cyan]Deleting quota {id} from OpenStack project[/cyan]")
call = APIDriver().delete(f"/quota/adjust-project/{id}/{Config().username}")
if call.status_code >= 400:
console.print(f"[red]Error: {call.text}[/red]")
return
console.print(f"[green]Quota {id} deleted from project[/green]")
Loading