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
45 changes: 0 additions & 45 deletions .devcontainer/Dockerfile

This file was deleted.

12 changes: 0 additions & 12 deletions .devcontainer/devcontainer.json

This file was deleted.

2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
*.pyc
dist/

.ruff_cache/
.DS_Store
23 changes: 22 additions & 1 deletion labctl/commands/quota.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def show_project_quota(project: str):

@cli_ready
@app.command(name="set")
def add_quota(project: str, quota_type: str, quantity: int, comment: Optional[str] = None):
def set_quota(project: str, quota_type: str, quantity: int, comment: Optional[str] = None):
"""
Add quota to OpenStack project
"""
Expand All @@ -48,3 +48,24 @@ def add_quota(project: str, quota_type: str, quantity: int, comment: Optional[st
console.print(f"[red]Error: {call.text}[/red]")
return
console.print(f"[green]Quota {quota_type}={quantity} set to project {project}[/green]")

@cli_ready
@app.command(name="unset")
def unset_quota(project: str, quota_type: str):
"""
Add quota to OpenStack project
"""
config = Config()
console.print(f"[cyan]Unsetting {quota_type} to OpenStack project {project}[/cyan]")
payload = {
"username": config.username,
"project_name": project,
"type": quota_type,
"quantity": 0,
"comment": ""
}
call = APIDriver().put(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} unset from project {project}[/green]")
25 changes: 24 additions & 1 deletion labctl/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,16 +69,39 @@ def me(
tree.add("[bold]Username:[/bold] " + data.get("username"))
tree.add("[bold]Email:[/bold] " + data.get("email"))

# show projects info
project_list = api_driver.get("/openstack/projects/" + config.username).json()
project_tree = tree.add(":open_file_folder: Projects")
for project in project_list:
project_tree_item = project_tree.add(":computer: " + project.get('name'))
project_tree_item.add("[bold]Owner:[/bold] " + project.get('owner', ''))
project_tree_item.add("Members: " + " ".join(project.get('members', [])))

# show quotas for project
project_quota_list = api_driver.get(f"/quota/project/{project.get('name')}/adjustements")
if project_quota_list.status_code >= 400:
project_tree_item.add(f":warning: Error fetching quotas for project {project.get('name')}")
continue

project_quota_tree = project_tree_item.add(":open_file_folder: Quotas for project")
quota_types = set([quota.get('type') for quota in project_quota_list.json()])
total_quotas = {quota_type: 0 for quota_type in quota_types}
self_quotas = {quota_type: 0 for quota_type in quota_types}
for quota in project_quota_list.json():
total_quotas[quota.get('type')] += quota.get('quantity')
if quota.get('username') == config.username:
self_quotas[quota.get('type')] += quota.get('quantity')

for quota_type, quantity in total_quotas.items():
if quantity == 0:
continue
project_quota_tree.add(f"{quota_type} Total: {quantity}")
project_quota_tree.add(f"{quota_type} You give: {self_quotas[quota_type]}")

if not project_list:
project_tree.add(":warning: No projects found")

quota_tree = tree.add(":open_file_folder: Quotas")
quota_tree = tree.add(":open_file_folder: Quotas owned")
quota_list = api_driver.get(f"/quota/user/{config.username}/total").json()
for quota in quota_list:
quota_tree.add(f"Type: {quota.get('type')} / {quota.get('quantity')}")
Expand Down
Loading