Compare commits

..

13 Commits

Author SHA1 Message Date
4e0346d0a0 nix fmt
Some checks failed
checks-impure / test (pull_request) Successful in 29s
checks / test (pull_request) Failing after 1m29s
2023-12-09 18:57:55 +01:00
a93e6019c5 clan_cli: Added automated database population. Fixed incorrect error handling in backend 2023-12-09 18:57:20 +01:00
80269832e6 Improved README 2023-12-06 14:02:50 +01:00
20e6e551d4 Improved README 2023-12-06 14:02:50 +01:00
7d4d6f59c2 Better README 2023-12-06 14:02:50 +01:00
Georg-Stahn
f7cf1ff2b2 georgs6 (#34)
All checks were successful
checks-impure / test (push) Successful in 31s
checks / test (push) Successful in 1m14s
assets1 / test (push) Successful in 21s
Reviewed-on: #34
2023-12-04 22:45:33 +01:00
Georg-Stahn
171582e2e7 georgs5 (#31)
All checks were successful
assets1 / test (push) Successful in 23s
checks-impure / test (push) Successful in 32s
checks / test (push) Successful in 1m13s
Reviewed-on: #31
2023-12-04 22:22:22 +01:00
Georg-Stahn
f3096075d2 Merge pull request 'georgs4' (#30) from georgs4 into main
All checks were successful
assets1 / test (push) Successful in 20s
checks-impure / test (push) Successful in 30s
checks / test (push) Successful in 1m27s
Reviewed-on: #30
2023-12-03 14:32:27 +01:00
Georg-Stahn
ef74a557e8 add formatting
All checks were successful
checks-impure / test (pull_request) Successful in 31s
checks / test (pull_request) Successful in 3m12s
2023-12-03 14:17:20 +01:00
Georg-Stahn
0a902a843d add commit push fail
Some checks failed
checks-impure / test (pull_request) Successful in 29s
checks / test (pull_request) Failing after 1m56s
2023-12-02 14:55:12 +01:00
Georg-Stahn
6f435df7e9 added c2 and more services +4 2023-12-02 14:27:59 +01:00
Georg-Stahn
8325d80d39 added c2 and more services +4 2023-12-02 14:26:59 +01:00
Georg-Stahn
35c7702a3e try to fix tea 2023-12-02 14:26:59 +01:00
12 changed files with 300 additions and 13 deletions

View File

@@ -106,7 +106,7 @@ Let's set up your Git workflow to collaborate effectively:
- URL of Gitea instance: `https://gitea.gchq.icu`
- Name of new Login [gitea.gchq.icu]: `gitea.gchq.icu:7171`
- Do you have an access token? Yes
- Token: ****\*****
- Token: \***\*\*\*\***
- Set Optional settings: No
2. **Git Workflow**:

View File

@@ -22,6 +22,12 @@ def register_parser(parser: argparse.ArgumentParser) -> None:
parser.add_argument(
"--host", type=str, default="localhost", help="Host to listen on"
)
parser.add_argument(
"--no-populate",
action="store_true",
help="Don't populate the database with dummy data",
default=False,
)
parser.add_argument(
"--no-open", action="store_true", help="Don't open the browser", default=False
)

View File

@@ -33,10 +33,13 @@ async def lifespan(app: FastAPI) -> Any:
def setup_app() -> FastAPI:
# bind sql engine
sql_models.Base.metadata.drop_all(engine)
# TODO comment aut and add flag to run with pupulated data rm *.sql run pytest with marked then start clan webui
# https://docs.pytest.org/en/7.1.x/example/markers.html
# sql_models.Base.metadata.drop_all(engine)
sql_models.Base.metadata.create_all(bind=engine)
app = FastAPI(lifespan=lifespan)
app = FastAPI(lifespan=lifespan, swagger_ui_parameters={"tryItOutEnabled": True})
app.add_middleware(
CORSMiddleware,
allow_origins=origins,

View File

@@ -25,7 +25,7 @@ def sql_error_handler(request: Request, exc: SQLAlchemyError) -> JSONResponse:
def clan_error_handler(request: Request, exc: ClanError) -> JSONResponse:
log.error("ClanError: %s", exc)
log.exception(exc)
detail = [
{
"loc": [],

View File

@@ -1,8 +1,12 @@
import logging
import time
from typing import List, Optional
from fastapi import APIRouter, Depends
import httpx
from fastapi import APIRouter, BackgroundTasks, Depends
from sqlalchemy.orm import Session
from ...errors import ClanError
from .. import sql_crud, sql_db, sql_models
from ..schemas import (
Consumer,
@@ -18,6 +22,8 @@ from ..tags import Tags
router = APIRouter()
log = logging.getLogger(__name__)
#########################
# #
@@ -140,7 +146,6 @@ def get_repository(
def create_entity(
entity: EntityCreate, db: Session = Depends(sql_db.get_db)
) -> EntityCreate:
# todo checken ob schon da ...
return sql_crud.create_entity(db, entity)
@@ -155,9 +160,66 @@ def get_entities(
@router.get("/api/v1/get_entity", response_model=Optional[Entity], tags=[Tags.entities])
def get_entity(
entity_did: str = "did:sov:test:1234",
skip: int = 0,
limit: int = 100,
db: Session = Depends(sql_db.get_db),
) -> Optional[sql_models.Entity]:
entity = sql_crud.get_entity_by_did(db, did=entity_did)
return entity
@router.get(
"/api/v1/get_attached_entities",
response_model=List[Entity],
tags=[Tags.entities],
)
def get_attached_entities(
skip: int = 0, limit: int = 100, db: Session = Depends(sql_db.get_db)
) -> List[sql_models.Entity]:
entities = sql_crud.get_attached_entities(db, skip=skip, limit=limit)
return entities
@router.post("/api/v1/detach", response_model=Entity, tags=[Tags.entities])
async def detach(
background_tasks: BackgroundTasks,
entity_did: str = "did:sov:test:1234",
skip: int = 0,
limit: int = 100,
db: Session = Depends(sql_db.get_db),
) -> dict[str, str]:
entity = sql_crud.set_attached_by_entity_did(db, entity_did, False)
return entity
@router.post("/api/v1/attach", tags=[Tags.entities])
async def attach(
background_tasks: BackgroundTasks,
entity_did: str = "did:sov:test:1234",
skip: int = 0,
limit: int = 100,
db: Session = Depends(sql_db.get_db),
) -> dict[str, str]:
if sql_crud.get_entity_by_did(db, entity_did) is None:
raise ClanError(f"Entity with did '{entity_did}' not found")
background_tasks.add_task(attach_entity, db, entity_did)
return {"message": "Attaching in the background"}
def attach_entity(db: Session, entity_did: str) -> None:
db_entity = sql_crud.set_attached_by_entity_did(db, entity_did, True)
try:
while db_entity.attached:
# query status endpoint
# https://www.python-httpx.org/
response = httpx.get(f"http://{db_entity.ip}", timeout=2)
print(response)
# test with:
# while true ; do printf 'HTTP/1.1 200 OK\r\n\r\ncool, thanks' | nc -l -N localhost 5555 ; done
# client test (apt install python3-httpx):
# httpx http://localhost:5555
# except not reached set false
time.sleep(1)
except Exception:
log.warning(f"Entity {entity_did} not reachable. Setting attached to false")
db_entity = sql_crud.set_attached_by_entity_did(db, entity_did, False)

View File

@@ -27,7 +27,7 @@ class ProducerBase(BaseModel):
service_type: str = "3D Printing"
endpoint_url: str = "http://127.0.0.1:8000"
status: str = "unknown"
other: dict = {"test": "test"}
other: dict = {"action": ["register", "deregister", "delete", "create"]}
class ProducerCreate(ProducerBase):
@@ -91,7 +91,11 @@ class EntityBase(BaseModel):
name: str = "C1"
ip: str = "127.0.0.1"
attached: bool = False
other: dict = {"test": "test"}
visible: bool = True
other: dict = {
"network": "Carlo's Home Network",
"roles": ["service repository", "service prosumer"],
}
class EntityCreate(EntityBase):

View File

@@ -105,6 +105,27 @@ def start_server(args: argparse.Namespace) -> None:
if not args.no_open:
Thread(target=open_browser, args=(base_url, args.sub_url)).start()
# DELETE all data from the database
from . import sql_models
from .sql_db import engine
sql_models.Base.metadata.drop_all(engine)
if args.no_populate is False:
test_dir = Path(__file__).parent.parent.parent / "tests"
if not test_dir.is_dir():
raise ClanError(f"Could not find test dir: {test_dir}")
test_db_api = test_dir / "test_db_api.py"
if not test_db_api.is_file():
raise ClanError(f"Could not find test db api: {test_db_api}")
import subprocess
cmd = ["pytest", "-s", "-n0", str(test_db_api)]
subprocess.run(cmd, check=True)
uvicorn.run(
"clan_cli.webui.app:app",
host=args.host,

View File

@@ -1,7 +1,9 @@
from typing import List, Optional
from sqlalchemy.orm import Session
from sqlalchemy.sql.expression import true
from ..errors import ClanError
from . import schemas, sql_models
#########################
@@ -136,3 +138,34 @@ def get_entities(
def get_entity_by_did(db: Session, did: str) -> Optional[sql_models.Entity]:
return db.query(sql_models.Entity).filter(sql_models.Entity.did == did).first()
# get attached
def get_attached_entities(
db: Session, skip: int = 0, limit: int = 100
) -> List[sql_models.Entity]:
return (
db.query(sql_models.Entity)
.filter(sql_models.Entity.attached == true())
# https://stackoverflow.com/questions/18998010/flake8-complains-on-boolean-comparison-in-filter-clause
.offset(skip)
.limit(limit)
.all()
)
# Returns same entity if setting didnt changed something
def set_attached_by_entity_did(
db: Session, entity_did: str, value: bool
) -> sql_models.Entity:
db_entity = get_entity_by_did(db, entity_did)
if db_entity is None:
raise ClanError(f"Entity with did '{entity_did}' not found")
setattr(db_entity, "attached", value)
# save changes in db
db.add(db_entity)
db.commit()
db.refresh(db_entity)
return db_entity

View File

@@ -26,6 +26,7 @@ class Entity(Base):
name = Column(String, index=True)
ip = Column(String, index=True)
attached = Column(Boolean, index=True)
visible = Column(Boolean, index=True)
## Non queryable body ##
# In here we deposit: Network, Roles, Visible, etc.

View File

@@ -1,9 +1,14 @@
import urllib.parse as url
from typing import Any
from api import TestClient
default_entity_did_url = "entity_did=did%3Asov%3Atest%3A1234"
default_entity_did = "did:sov:test:1234"
default_entity_did2 = "did:sov:test:1235"
default_entity_did3 = "did:sov:test:1236"
default_entity_did4 = "did:sov:test:1237"
default_entity_did5 = "did:sov:test:1238"
def assert_extra_info(
@@ -72,7 +77,7 @@ def test_producer(api: TestClient) -> None:
"service_type": "3D Printing",
"endpoint_url": "http://127.0.0.1:8000",
"status": "unknown",
"other": {"test": "test"},
"other": {"action": ["register", "deregister", "delete", "create"]},
"entity_did": default_entity_did,
}
paramter = "producer"
@@ -80,6 +85,66 @@ def test_producer(api: TestClient) -> None:
make_test_post_and_get(api, request_body, paramter)
def test_producer2(api: TestClient) -> None:
request_body = {
"uuid": "8e285c0c-4e40-430a-a477-26b3b81e30d1",
"service_name": "Luis'''s Fax",
"service_type": "Fax",
"endpoint_url": "http://127.0.0.1:8001",
"status": "unknown",
"other": {"action": ["register", "deregister", "delete", "create"]},
"entity_did": default_entity_did2,
}
paramter = "producer"
get_request = "entity_did=" + url.quote(default_entity_did2)
make_test_post_and_get(api, request_body, paramter, get_request)
def test_producer3(api: TestClient) -> None:
request_body = {
"uuid": "8e285c0c-4e40-430a-a477-26b3b81e30d2",
"service_name": "Erdem'''s VR-Stream",
"service_type": "VR-Stream",
"endpoint_url": "http://127.0.0.1:8002",
"status": "unknown",
"other": {"action": ["register", "deregister", "delete", "create"]},
"entity_did": default_entity_did3,
}
paramter = "producer"
get_request = "entity_did=" + url.quote(default_entity_did3)
make_test_post_and_get(api, request_body, paramter, get_request)
def test_producer4(api: TestClient) -> None:
request_body = {
"uuid": "8e285c0c-4e40-430a-a477-26b3b81e30d3",
"service_name": "Onur'''s gallary",
"service_type": "gallary",
"endpoint_url": "http://127.0.0.1:8003",
"status": "unknown",
"other": {"action": ["register", "deregister", "delete", "create"]},
"entity_did": default_entity_did4,
}
paramter = "producer"
get_request = "entity_did=" + url.quote(default_entity_did4)
make_test_post_and_get(api, request_body, paramter, get_request)
def test_producer5(api: TestClient) -> None:
request_body = {
"uuid": "8e285c0c-4e40-430a-a477-26b3b81e30d4",
"service_name": "Sara'''s Game-Shop",
"service_type": "Game-Shop",
"endpoint_url": "http://127.0.0.1:8004",
"status": "unknown",
"other": {"action": ["register", "deregister", "delete", "create"]},
"entity_did": default_entity_did5,
}
paramter = "producer"
get_request = "entity_did=" + url.quote(default_entity_did5)
make_test_post_and_get(api, request_body, paramter, get_request)
#########################
# #
# Consumer #
@@ -96,6 +161,17 @@ def test_consumer(api: TestClient) -> None:
make_test_post_and_get(api, request_body, paramter)
def test_consumer2(api: TestClient) -> None:
request_body = {
"entity_did": default_entity_did2,
"producer_uuid": "8e285c0c-4e40-430a-a477-26b3b81e30d4",
"other": {"war": "games"},
}
paramter = "consumer"
get_request = "entity_did=" + url.quote(default_entity_did2)
make_test_post_and_get(api, request_body, paramter, get_request)
#########################
# #
# REPOSITORY #
@@ -116,6 +192,66 @@ def test_repository(api: TestClient) -> None:
make_test_post_and_get(api, request_body, paramter)
def test_repository2(api: TestClient) -> None:
request_body = {
"uuid": "8e285c0c-4e40-430a-a477-26b3b81e30d1",
"service_name": "Luis'''s Fax",
"service_type": "Fax",
"endpoint_url": "http://127.0.0.1:8001",
"status": "unknown",
"other": {"faxen": "dicke"},
"entity_did": default_entity_did2,
}
paramter = "repository"
get_request = "entity_did=" + url.quote(default_entity_did2)
make_test_post_and_get(api, request_body, paramter, get_request)
def test_repository3(api: TestClient) -> None:
request_body = {
"uuid": "8e285c0c-4e40-430a-a477-26b3b81e30d2",
"service_name": "Erdem'''s VR-Stream",
"service_type": "VR-Stream",
"endpoint_url": "http://127.0.0.1:8002",
"status": "unknown",
"other": {"oculos": "rift"},
"entity_did": default_entity_did3,
}
paramter = "repository"
get_request = "entity_did=" + url.quote(default_entity_did3)
make_test_post_and_get(api, request_body, paramter, get_request)
def test_repository4(api: TestClient) -> None:
request_body = {
"uuid": "8e285c0c-4e40-430a-a477-26b3b81e30d3",
"service_name": "Onur'''s gallary",
"service_type": "gallary",
"endpoint_url": "http://127.0.0.1:8003",
"status": "unknown",
"other": {"nice": "pics"},
"entity_did": default_entity_did4,
}
paramter = "repository"
get_request = "entity_did=" + url.quote(default_entity_did4)
make_test_post_and_get(api, request_body, paramter, get_request)
def test_repository5(api: TestClient) -> None:
request_body = {
"uuid": "8e285c0c-4e40-430a-a477-26b3b81e30d4",
"service_name": "Sara'''s Game-Shop",
"service_type": "Game-Shop",
"endpoint_url": "http://127.0.0.2:8004",
"status": "unknown",
"other": {"war": "games"},
"entity_did": default_entity_did5,
}
paramter = "repository"
get_request = "entity_did=" + url.quote(default_entity_did5)
make_test_post_and_get(api, request_body, paramter, get_request)
#########################
# #
# Entity #
@@ -127,8 +263,29 @@ def test_entity(api: TestClient) -> None:
"name": "C1",
"ip": "127.0.0.1",
"attached": False,
"other": {"test": "test"},
"visible": True,
"other": {
"network": "Carlo1's Home Network",
"roles": ["service repository", "service consumer"],
},
}
paramter = "entity"
# get_request = "entity_did=did%3Asov%3Atest%3A1234"
make_test_post_and_get(api, request_body, paramter)
def test_entity2(api: TestClient) -> None:
request_body = {
"did": default_entity_did2,
"name": "C2",
"ip": "127.0.0.2",
"attached": False,
"visible": True,
"other": {
"network": "Carlo2's Home Network",
"roles": ["service repository", "service prosumer"],
},
}
paramter = "entity"
get_request = "entity_did=" + url.quote(default_entity_did2)
make_test_post_and_get(api, request_body, paramter, get_request)

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env bash
set -euo pipefail
set -xeuo pipefail
remoteName="${1:-origin}"
targetBranch="${2:-main}"