mrok 0.2.3__py3-none-any.whl → 0.4.0__py3-none-any.whl
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.
- mrok/agent/devtools/__init__.py +0 -0
- mrok/agent/devtools/__main__.py +34 -0
- mrok/agent/devtools/inspector/__init__.py +0 -0
- mrok/agent/devtools/inspector/__main__.py +25 -0
- mrok/agent/devtools/inspector/app.py +556 -0
- mrok/agent/devtools/inspector/server.py +18 -0
- mrok/agent/sidecar/app.py +9 -10
- mrok/agent/sidecar/main.py +35 -16
- mrok/agent/ziticorn.py +27 -18
- mrok/cli/commands/__init__.py +2 -1
- mrok/cli/commands/admin/list/instances.py +24 -4
- mrok/cli/commands/admin/register/extensions.py +2 -2
- mrok/cli/commands/admin/register/instances.py +3 -3
- mrok/cli/commands/admin/unregister/extensions.py +2 -2
- mrok/cli/commands/admin/unregister/instances.py +2 -2
- mrok/cli/commands/agent/__init__.py +2 -0
- mrok/cli/commands/agent/dev/__init__.py +7 -0
- mrok/cli/commands/agent/dev/console.py +25 -0
- mrok/cli/commands/agent/dev/web.py +37 -0
- mrok/cli/commands/agent/run/asgi.py +35 -16
- mrok/cli/commands/agent/run/sidecar.py +29 -13
- mrok/cli/commands/agent/utils.py +5 -0
- mrok/cli/commands/controller/run.py +1 -5
- mrok/cli/commands/proxy/__init__.py +6 -0
- mrok/cli/commands/proxy/run.py +49 -0
- mrok/cli/utils.py +5 -0
- mrok/conf.py +6 -0
- mrok/controller/auth.py +2 -2
- mrok/controller/routes/extensions.py +9 -7
- mrok/datastructures.py +159 -0
- mrok/http/config.py +3 -6
- mrok/http/constants.py +22 -0
- mrok/http/forwarder.py +62 -23
- mrok/http/lifespan.py +29 -0
- mrok/http/middlewares.py +143 -0
- mrok/http/types.py +43 -0
- mrok/http/utils.py +90 -0
- mrok/logging.py +22 -0
- mrok/master.py +269 -0
- mrok/metrics.py +139 -0
- mrok/proxy/__init__.py +3 -0
- mrok/proxy/app.py +73 -0
- mrok/proxy/dataclasses.py +12 -0
- mrok/proxy/main.py +58 -0
- mrok/proxy/streams.py +124 -0
- mrok/proxy/types.py +12 -0
- mrok/proxy/ziti.py +173 -0
- mrok/ziti/identities.py +50 -20
- mrok/ziti/services.py +8 -8
- {mrok-0.2.3.dist-info → mrok-0.4.0.dist-info}/METADATA +7 -1
- mrok-0.4.0.dist-info/RECORD +92 -0
- {mrok-0.2.3.dist-info → mrok-0.4.0.dist-info}/WHEEL +1 -1
- mrok/http/master.py +0 -132
- mrok-0.2.3.dist-info/RECORD +0 -66
- {mrok-0.2.3.dist-info → mrok-0.4.0.dist-info}/entry_points.txt +0 -0
- {mrok-0.2.3.dist-info → mrok-0.4.0.dist-info}/licenses/LICENSE.txt +0 -0
mrok/agent/sidecar/main.py
CHANGED
|
@@ -1,27 +1,46 @@
|
|
|
1
|
-
import
|
|
2
|
-
import contextlib
|
|
3
|
-
from functools import partial
|
|
1
|
+
import logging
|
|
4
2
|
from pathlib import Path
|
|
5
3
|
|
|
6
4
|
from mrok.agent.sidecar.app import ForwardApp
|
|
7
|
-
from mrok.
|
|
8
|
-
from mrok.http.master import Master
|
|
9
|
-
from mrok.http.server import MrokServer
|
|
5
|
+
from mrok.master import MasterBase
|
|
10
6
|
|
|
7
|
+
logger = logging.getLogger("mrok.proxy")
|
|
11
8
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
9
|
+
|
|
10
|
+
class SidecarAgent(MasterBase):
|
|
11
|
+
def __init__(
|
|
12
|
+
self,
|
|
13
|
+
identity_file: str,
|
|
14
|
+
target_addr: str | Path | tuple[str, int],
|
|
15
|
+
workers: int = 4,
|
|
16
|
+
publishers_port: int = 50000,
|
|
17
|
+
subscribers_port: int = 50001,
|
|
18
|
+
):
|
|
19
|
+
super().__init__(
|
|
20
|
+
identity_file,
|
|
21
|
+
workers,
|
|
22
|
+
False,
|
|
23
|
+
publishers_port,
|
|
24
|
+
subscribers_port,
|
|
25
|
+
)
|
|
26
|
+
self.target_address = target_addr
|
|
27
|
+
|
|
28
|
+
def get_asgi_app(self):
|
|
29
|
+
return ForwardApp(self.target_address)
|
|
17
30
|
|
|
18
31
|
|
|
19
32
|
def run(
|
|
20
33
|
identity_file: str,
|
|
21
34
|
target_addr: str | Path | tuple[str, int],
|
|
22
|
-
workers=4,
|
|
23
|
-
|
|
35
|
+
workers: int = 4,
|
|
36
|
+
publishers_port: int = 50000,
|
|
37
|
+
subscribers_port: int = 50001,
|
|
24
38
|
):
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
39
|
+
agent = SidecarAgent(
|
|
40
|
+
identity_file,
|
|
41
|
+
target_addr,
|
|
42
|
+
workers=workers,
|
|
43
|
+
publishers_port=publishers_port,
|
|
44
|
+
subscribers_port=subscribers_port,
|
|
45
|
+
)
|
|
46
|
+
agent.run()
|
mrok/agent/ziticorn.py
CHANGED
|
@@ -1,29 +1,38 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import os
|
|
4
|
-
from functools import partial
|
|
1
|
+
from mrok.http.types import ASGIApp
|
|
2
|
+
from mrok.master import MasterBase
|
|
5
3
|
|
|
6
|
-
from mrok.http.config import ASGIApplication, MrokBackendConfig
|
|
7
|
-
from mrok.http.master import Master
|
|
8
|
-
from mrok.http.server import MrokServer
|
|
9
4
|
|
|
5
|
+
class ZiticornAgent(MasterBase):
|
|
6
|
+
def __init__(
|
|
7
|
+
self,
|
|
8
|
+
app: ASGIApp | str,
|
|
9
|
+
identity_file: str,
|
|
10
|
+
workers: int = 4,
|
|
11
|
+
reload: bool = False,
|
|
12
|
+
publishers_port: int = 50000,
|
|
13
|
+
subscribers_port: int = 50001,
|
|
14
|
+
):
|
|
15
|
+
super().__init__(identity_file, workers, reload, publishers_port, subscribers_port)
|
|
16
|
+
self.app = app
|
|
10
17
|
|
|
11
|
-
def
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
sys.path.insert(0, os.getcwd())
|
|
15
|
-
config = MrokBackendConfig(app, identity_file)
|
|
16
|
-
server = MrokServer(config)
|
|
17
|
-
with contextlib.suppress(KeyboardInterrupt, asyncio.CancelledError):
|
|
18
|
-
server.run()
|
|
18
|
+
def get_asgi_app(self):
|
|
19
|
+
return self.app
|
|
19
20
|
|
|
20
21
|
|
|
21
22
|
def run(
|
|
22
|
-
app:
|
|
23
|
+
app: ASGIApp | str,
|
|
23
24
|
identity_file: str,
|
|
24
25
|
workers: int = 4,
|
|
25
26
|
reload: bool = False,
|
|
27
|
+
publishers_port: int = 50000,
|
|
28
|
+
subscribers_port: int = 50001,
|
|
26
29
|
):
|
|
27
|
-
|
|
28
|
-
|
|
30
|
+
master = ZiticornAgent(
|
|
31
|
+
app,
|
|
32
|
+
identity_file,
|
|
33
|
+
workers=workers,
|
|
34
|
+
reload=reload,
|
|
35
|
+
publishers_port=publishers_port,
|
|
36
|
+
subscribers_port=subscribers_port,
|
|
37
|
+
)
|
|
29
38
|
master.run()
|
mrok/cli/commands/__init__.py
CHANGED
|
@@ -21,7 +21,11 @@ from mrok.ziti.constants import (
|
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
async def get_instances(
|
|
24
|
-
settings: Settings,
|
|
24
|
+
settings: Settings,
|
|
25
|
+
detailed: bool,
|
|
26
|
+
extension: str | None = None,
|
|
27
|
+
tags: list[str] | None = None,
|
|
28
|
+
online_only: bool = False,
|
|
25
29
|
) -> list[dict]:
|
|
26
30
|
async with ZitiManagementAPI(settings) as api:
|
|
27
31
|
tags = tags or []
|
|
@@ -29,6 +33,9 @@ async def get_instances(
|
|
|
29
33
|
identities = [
|
|
30
34
|
identity async for identity in api.identities(params={"filter": tags_to_filter(tags)})
|
|
31
35
|
]
|
|
36
|
+
if online_only:
|
|
37
|
+
identities = list(filter(lambda i: i["hasEdgeRouterConnection"], identities))
|
|
38
|
+
|
|
32
39
|
if detailed or extension:
|
|
33
40
|
for identity in identities:
|
|
34
41
|
identity["services"] = [
|
|
@@ -60,10 +67,11 @@ async def get_instances(
|
|
|
60
67
|
def render_tsv(instances: list[dict], detailed: bool) -> None:
|
|
61
68
|
console = get_console()
|
|
62
69
|
if detailed:
|
|
63
|
-
console.print("id\tname\tservices\tpolicies\ttags\tcreated\tupdated")
|
|
70
|
+
console.print("id\tname\tstatus\tservices\tpolicies\ttags\tcreated\tupdated")
|
|
64
71
|
for instance in instances:
|
|
65
72
|
console.print(
|
|
66
73
|
f"{instance['id']}\t{instance['name']}\t"
|
|
74
|
+
f"{'online' if instance['hasEdgeRouterConnection'] else 'offline'}\t"
|
|
67
75
|
f"{extract_names(instance['services'], ', ')}\t"
|
|
68
76
|
f"{extract_names(instance['policies'], ', ')}\t"
|
|
69
77
|
f"{format_tags(instance['tags'], ', ')}\t"
|
|
@@ -71,10 +79,11 @@ def render_tsv(instances: list[dict], detailed: bool) -> None:
|
|
|
71
79
|
f"{format_timestamp(instance['updatedAt'])}"
|
|
72
80
|
)
|
|
73
81
|
else:
|
|
74
|
-
console.print("id\tname\ttags\tcreated")
|
|
82
|
+
console.print("id\tname\tstatus\ttags\tcreated")
|
|
75
83
|
for instance in instances:
|
|
76
84
|
console.print(
|
|
77
85
|
f"{instance['id']}\t{instance['name']}\t"
|
|
86
|
+
f"{'online' if instance['hasEdgeRouterConnection'] else 'offline'}\t"
|
|
78
87
|
f"{format_tags(instance['tags'], ', ')}\t"
|
|
79
88
|
f"{format_timestamp(instance['createdAt'])}\t"
|
|
80
89
|
)
|
|
@@ -90,6 +99,7 @@ def render_table(instances: list[dict], detailed: bool) -> None:
|
|
|
90
99
|
)
|
|
91
100
|
table.add_column("Id", style="green")
|
|
92
101
|
table.add_column("Name", style="bold cyan")
|
|
102
|
+
table.add_column("Status", justify="center")
|
|
93
103
|
if detailed:
|
|
94
104
|
table.add_column("Associated services")
|
|
95
105
|
table.add_column("Associated service policies")
|
|
@@ -102,6 +112,7 @@ def render_table(instances: list[dict], detailed: bool) -> None:
|
|
|
102
112
|
row = [
|
|
103
113
|
instance["id"],
|
|
104
114
|
instance["name"],
|
|
115
|
+
"🟢" if instance["hasEdgeRouterConnection"] else "⚪",
|
|
105
116
|
]
|
|
106
117
|
if detailed:
|
|
107
118
|
row += [
|
|
@@ -142,6 +153,15 @@ def register(app: typer.Typer) -> None:
|
|
|
142
153
|
show_default=True,
|
|
143
154
|
),
|
|
144
155
|
] = None,
|
|
156
|
+
online_only: Annotated[
|
|
157
|
+
bool,
|
|
158
|
+
typer.Option(
|
|
159
|
+
"--online-only",
|
|
160
|
+
"-o",
|
|
161
|
+
help="Show only connected instances",
|
|
162
|
+
show_default=True,
|
|
163
|
+
),
|
|
164
|
+
] = False,
|
|
145
165
|
detailed: bool = typer.Option(
|
|
146
166
|
False,
|
|
147
167
|
"--detailed",
|
|
@@ -155,7 +175,7 @@ def register(app: typer.Typer) -> None:
|
|
|
155
175
|
),
|
|
156
176
|
):
|
|
157
177
|
"""List instances in OpenZiti (identities)."""
|
|
158
|
-
instances = asyncio.run(get_instances(ctx.obj, detailed, extension, tags))
|
|
178
|
+
instances = asyncio.run(get_instances(ctx.obj, detailed, extension, tags, online_only))
|
|
159
179
|
|
|
160
180
|
if len(instances) == 0:
|
|
161
181
|
get_console().print("No instances found.")
|
|
@@ -8,14 +8,14 @@ from rich import print
|
|
|
8
8
|
from mrok.cli.commands.admin.utils import parse_tags
|
|
9
9
|
from mrok.conf import Settings
|
|
10
10
|
from mrok.ziti.api import ZitiManagementAPI
|
|
11
|
-
from mrok.ziti.services import
|
|
11
|
+
from mrok.ziti.services import register_service
|
|
12
12
|
|
|
13
13
|
RE_EXTENSION_ID = re.compile(r"(?i)EXT-\d{4}-\d{4}")
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
async def do_register(settings: Settings, extension_id: str, tags: list[str] | None):
|
|
17
17
|
async with ZitiManagementAPI(settings) as api:
|
|
18
|
-
await
|
|
18
|
+
await register_service(settings, api, extension_id, tags=parse_tags(tags))
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
def validate_extension_id(extension_id: str) -> str:
|
|
@@ -9,7 +9,7 @@ import typer
|
|
|
9
9
|
from mrok.cli.commands.admin.utils import parse_tags
|
|
10
10
|
from mrok.conf import Settings
|
|
11
11
|
from mrok.ziti.api import ZitiClientAPI, ZitiManagementAPI
|
|
12
|
-
from mrok.ziti.identities import
|
|
12
|
+
from mrok.ziti.identities import register_identity
|
|
13
13
|
|
|
14
14
|
RE_EXTENSION_ID = re.compile(r"(?i)EXT-\d{4}-\d{4}")
|
|
15
15
|
|
|
@@ -18,8 +18,8 @@ async def do_register(
|
|
|
18
18
|
settings: Settings, extension_id: str, instance_id: str, tags: list[str] | None
|
|
19
19
|
):
|
|
20
20
|
async with ZitiManagementAPI(settings) as mgmt_api, ZitiClientAPI(settings) as client_api:
|
|
21
|
-
return await
|
|
22
|
-
mgmt_api, client_api, extension_id, instance_id, tags=parse_tags(tags)
|
|
21
|
+
return await register_identity(
|
|
22
|
+
settings, mgmt_api, client_api, extension_id, instance_id, tags=parse_tags(tags)
|
|
23
23
|
)
|
|
24
24
|
|
|
25
25
|
|
|
@@ -5,14 +5,14 @@ import typer
|
|
|
5
5
|
|
|
6
6
|
from mrok.conf import Settings
|
|
7
7
|
from mrok.ziti.api import ZitiManagementAPI
|
|
8
|
-
from mrok.ziti.services import
|
|
8
|
+
from mrok.ziti.services import unregister_service
|
|
9
9
|
|
|
10
10
|
RE_EXTENSION_ID = re.compile(r"(?i)EXT-\d{4}-\d{4}")
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
async def do_unregister(settings: Settings, extension_id: str):
|
|
14
14
|
async with ZitiManagementAPI(settings) as api:
|
|
15
|
-
await
|
|
15
|
+
await unregister_service(settings, api, extension_id)
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
def validate_extension_id(extension_id: str):
|
|
@@ -5,14 +5,14 @@ import typer
|
|
|
5
5
|
|
|
6
6
|
from mrok.conf import Settings
|
|
7
7
|
from mrok.ziti.api import ZitiManagementAPI
|
|
8
|
-
from mrok.ziti.identities import
|
|
8
|
+
from mrok.ziti.identities import unregister_identity
|
|
9
9
|
|
|
10
10
|
RE_EXTENSION_ID = re.compile(r"(?i)EXT-\d{4}-\d{4}")
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
async def do_unregister(settings: Settings, extension_id: str, instance_id: str):
|
|
14
14
|
async with ZitiManagementAPI(settings) as api:
|
|
15
|
-
await
|
|
15
|
+
await unregister_identity(settings, api, extension_id, instance_id)
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
def validate_extension_id(extension_id: str):
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from typing import Annotated
|
|
2
|
+
|
|
3
|
+
import typer
|
|
4
|
+
|
|
5
|
+
from mrok.agent.devtools.inspector.app import InspectorApp
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def register(app: typer.Typer) -> None:
|
|
9
|
+
@app.command("console")
|
|
10
|
+
def run_dev_console(
|
|
11
|
+
subscriber_port: Annotated[
|
|
12
|
+
int,
|
|
13
|
+
typer.Option(
|
|
14
|
+
"--subscriber-port",
|
|
15
|
+
"-s",
|
|
16
|
+
help=(
|
|
17
|
+
"TCP port where the mrok inspector console application "
|
|
18
|
+
"should connect to subscribe to request/response messages."
|
|
19
|
+
),
|
|
20
|
+
show_default=True,
|
|
21
|
+
),
|
|
22
|
+
] = 50001,
|
|
23
|
+
):
|
|
24
|
+
app = InspectorApp(subscriber_port)
|
|
25
|
+
app.run()
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
from typing import Annotated
|
|
2
|
+
|
|
3
|
+
import typer
|
|
4
|
+
|
|
5
|
+
from mrok.agent.devtools.inspector.server import InspectorServer
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def register(app: typer.Typer) -> None:
|
|
9
|
+
@app.command("web")
|
|
10
|
+
def run_web_console(
|
|
11
|
+
port: Annotated[
|
|
12
|
+
int,
|
|
13
|
+
typer.Option(
|
|
14
|
+
"--port",
|
|
15
|
+
"-p",
|
|
16
|
+
help="TCP port where the mrok inspector web application will listen for requests.",
|
|
17
|
+
show_default=True,
|
|
18
|
+
),
|
|
19
|
+
] = 7777,
|
|
20
|
+
subscriber_port: Annotated[
|
|
21
|
+
int,
|
|
22
|
+
typer.Option(
|
|
23
|
+
"--subscriber-port",
|
|
24
|
+
"-s",
|
|
25
|
+
help=(
|
|
26
|
+
"TCP port where the mrok inspector web application "
|
|
27
|
+
"should connect to subscribe to request/response messages."
|
|
28
|
+
),
|
|
29
|
+
show_default=True,
|
|
30
|
+
),
|
|
31
|
+
] = 50001,
|
|
32
|
+
):
|
|
33
|
+
server = InspectorServer(
|
|
34
|
+
port=port,
|
|
35
|
+
subscriber_port=subscriber_port,
|
|
36
|
+
)
|
|
37
|
+
server.serve()
|
|
@@ -1,16 +1,10 @@
|
|
|
1
|
-
import multiprocessing
|
|
2
1
|
from pathlib import Path
|
|
3
2
|
from typing import Annotated
|
|
4
3
|
|
|
5
4
|
import typer
|
|
6
5
|
|
|
7
|
-
# from app.logging import get_logging_config
|
|
8
6
|
from mrok.agent import ziticorn
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
def number_of_workers():
|
|
12
|
-
return (multiprocessing.cpu_count() * 2) + 1
|
|
13
|
-
|
|
7
|
+
from mrok.cli.utils import number_of_workers
|
|
14
8
|
|
|
15
9
|
default_workers = number_of_workers()
|
|
16
10
|
|
|
@@ -18,14 +12,8 @@ default_workers = number_of_workers()
|
|
|
18
12
|
def register(app: typer.Typer) -> None:
|
|
19
13
|
@app.command("asgi")
|
|
20
14
|
def run_asgi(
|
|
21
|
-
app: str
|
|
22
|
-
|
|
23
|
-
help="ASGI application",
|
|
24
|
-
),
|
|
25
|
-
identity_file: Path = typer.Argument(
|
|
26
|
-
...,
|
|
27
|
-
help="Identity json file",
|
|
28
|
-
),
|
|
15
|
+
app: Annotated[str, typer.Argument(..., help="ASGI application")],
|
|
16
|
+
identity_file: Annotated[Path, typer.Argument(..., help="Identity json file")],
|
|
29
17
|
workers: Annotated[
|
|
30
18
|
int,
|
|
31
19
|
typer.Option(
|
|
@@ -44,6 +32,37 @@ def register(app: typer.Typer) -> None:
|
|
|
44
32
|
show_default=True,
|
|
45
33
|
),
|
|
46
34
|
] = False,
|
|
35
|
+
publishers_port: Annotated[
|
|
36
|
+
int,
|
|
37
|
+
typer.Option(
|
|
38
|
+
"--publishers-port",
|
|
39
|
+
"-p",
|
|
40
|
+
help=(
|
|
41
|
+
"TCP port where the mrok agent "
|
|
42
|
+
"should connect to publish to request/response messages."
|
|
43
|
+
),
|
|
44
|
+
show_default=True,
|
|
45
|
+
),
|
|
46
|
+
] = 50000,
|
|
47
|
+
subscribers_port: Annotated[
|
|
48
|
+
int,
|
|
49
|
+
typer.Option(
|
|
50
|
+
"--subscribers-port",
|
|
51
|
+
"-s",
|
|
52
|
+
help=(
|
|
53
|
+
"TCP port where the mrok agent should listen for incoming subscribers "
|
|
54
|
+
"connections for request/response messages."
|
|
55
|
+
),
|
|
56
|
+
show_default=True,
|
|
57
|
+
),
|
|
58
|
+
] = 50001,
|
|
47
59
|
):
|
|
48
60
|
"""Run an ASGI application exposing it through OpenZiti network."""
|
|
49
|
-
ziticorn.run(
|
|
61
|
+
ziticorn.run(
|
|
62
|
+
app,
|
|
63
|
+
str(identity_file),
|
|
64
|
+
workers=workers,
|
|
65
|
+
reload=reload,
|
|
66
|
+
publishers_port=publishers_port,
|
|
67
|
+
subscribers_port=subscribers_port,
|
|
68
|
+
)
|
|
@@ -1,15 +1,10 @@
|
|
|
1
|
-
import multiprocessing
|
|
2
1
|
from pathlib import Path
|
|
3
2
|
from typing import Annotated
|
|
4
3
|
|
|
5
4
|
import typer
|
|
6
5
|
|
|
7
6
|
from mrok.agent import sidecar
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
def number_of_workers():
|
|
11
|
-
return (multiprocessing.cpu_count() * 2) + 1
|
|
12
|
-
|
|
7
|
+
from mrok.cli.utils import number_of_workers
|
|
13
8
|
|
|
14
9
|
default_workers = number_of_workers()
|
|
15
10
|
|
|
@@ -34,15 +29,30 @@ def register(app: typer.Typer) -> None:
|
|
|
34
29
|
show_default=True,
|
|
35
30
|
),
|
|
36
31
|
] = default_workers,
|
|
37
|
-
|
|
38
|
-
|
|
32
|
+
publishers_port: Annotated[
|
|
33
|
+
int,
|
|
34
|
+
typer.Option(
|
|
35
|
+
"--publishers-port",
|
|
36
|
+
"-p",
|
|
37
|
+
help=(
|
|
38
|
+
"TCP port where the mrok agent "
|
|
39
|
+
"should connect to publish to request/response messages."
|
|
40
|
+
),
|
|
41
|
+
show_default=True,
|
|
42
|
+
),
|
|
43
|
+
] = 50000,
|
|
44
|
+
subscribers_port: Annotated[
|
|
45
|
+
int,
|
|
39
46
|
typer.Option(
|
|
40
|
-
"--
|
|
41
|
-
"-
|
|
42
|
-
help=
|
|
47
|
+
"--subscribers-port",
|
|
48
|
+
"-s",
|
|
49
|
+
help=(
|
|
50
|
+
"TCP port where the mrok agent should listen for incoming subscribers "
|
|
51
|
+
"connections for request/response messages."
|
|
52
|
+
),
|
|
43
53
|
show_default=True,
|
|
44
54
|
),
|
|
45
|
-
] =
|
|
55
|
+
] = 50001,
|
|
46
56
|
):
|
|
47
57
|
"""Run a Sidecar Proxy to expose a web application through OpenZiti."""
|
|
48
58
|
if ":" in str(target):
|
|
@@ -51,4 +61,10 @@ def register(app: typer.Typer) -> None:
|
|
|
51
61
|
else:
|
|
52
62
|
target_addr = str(target) # type: ignore
|
|
53
63
|
|
|
54
|
-
sidecar.run(
|
|
64
|
+
sidecar.run(
|
|
65
|
+
str(identity_file),
|
|
66
|
+
target_addr,
|
|
67
|
+
workers=workers,
|
|
68
|
+
publishers_port=publishers_port,
|
|
69
|
+
subscribers_port=subscribers_port,
|
|
70
|
+
)
|
|
@@ -1,18 +1,14 @@
|
|
|
1
|
-
import multiprocessing
|
|
2
1
|
from collections.abc import Callable
|
|
3
2
|
from typing import Annotated, Any
|
|
4
3
|
|
|
5
4
|
import typer
|
|
6
5
|
from gunicorn.app.base import BaseApplication
|
|
7
6
|
|
|
7
|
+
from mrok.cli.utils import number_of_workers
|
|
8
8
|
from mrok.controller.app import app as asgi_app
|
|
9
9
|
from mrok.logging import get_logging_config
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
def number_of_workers():
|
|
13
|
-
return (multiprocessing.cpu_count() * 2) + 1
|
|
14
|
-
|
|
15
|
-
|
|
16
12
|
class StandaloneApplication(BaseApplication): # pragma: no cover
|
|
17
13
|
def __init__(self, application: Callable, options: dict[str, Any] | None = None):
|
|
18
14
|
self.options = options or {}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
from typing import Annotated
|
|
3
|
+
|
|
4
|
+
import typer
|
|
5
|
+
|
|
6
|
+
from mrok import proxy
|
|
7
|
+
from mrok.cli.utils import number_of_workers
|
|
8
|
+
|
|
9
|
+
default_workers = number_of_workers()
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def register(app: typer.Typer) -> None:
|
|
13
|
+
@app.command("run")
|
|
14
|
+
def run_proxy(
|
|
15
|
+
ctx: typer.Context,
|
|
16
|
+
identity_file: Path = typer.Argument(
|
|
17
|
+
...,
|
|
18
|
+
help="Identity json file",
|
|
19
|
+
),
|
|
20
|
+
host: Annotated[
|
|
21
|
+
str,
|
|
22
|
+
typer.Option(
|
|
23
|
+
"--host",
|
|
24
|
+
"-h",
|
|
25
|
+
help="Host to bind to. Default: 127.0.0.1",
|
|
26
|
+
show_default=True,
|
|
27
|
+
),
|
|
28
|
+
] = "127.0.0.1",
|
|
29
|
+
port: Annotated[
|
|
30
|
+
int,
|
|
31
|
+
typer.Option(
|
|
32
|
+
"--port",
|
|
33
|
+
"-P",
|
|
34
|
+
help="Port to bind to. Default: 8000",
|
|
35
|
+
show_default=True,
|
|
36
|
+
),
|
|
37
|
+
] = 8000,
|
|
38
|
+
workers: Annotated[
|
|
39
|
+
int,
|
|
40
|
+
typer.Option(
|
|
41
|
+
"--workers",
|
|
42
|
+
"-w",
|
|
43
|
+
help=f"Number of workers. Default: {default_workers}",
|
|
44
|
+
show_default=True,
|
|
45
|
+
),
|
|
46
|
+
] = default_workers,
|
|
47
|
+
):
|
|
48
|
+
"""Run the mrok proxy with Gunicorn and Uvicorn workers."""
|
|
49
|
+
proxy.run(identity_file, host, port, workers)
|
mrok/cli/utils.py
ADDED
mrok/conf.py
CHANGED
|
@@ -15,6 +15,12 @@ DEFAULT_SETTINGS = {
|
|
|
15
15
|
"ssl_verify": False,
|
|
16
16
|
},
|
|
17
17
|
"PAGINATION": {"limit": 50},
|
|
18
|
+
"SIDECAR": {
|
|
19
|
+
"textual_port": 4040,
|
|
20
|
+
"store_port": 5051,
|
|
21
|
+
"store_size": 1000,
|
|
22
|
+
"textual_command": "python mrok/agent/sidecar/inspector.py",
|
|
23
|
+
},
|
|
18
24
|
}
|
|
19
25
|
|
|
20
26
|
_settings = None
|
mrok/controller/auth.py
CHANGED
|
@@ -80,8 +80,8 @@ async def authenticate(
|
|
|
80
80
|
)
|
|
81
81
|
return payload
|
|
82
82
|
except jwt.InvalidKeyError as e:
|
|
83
|
-
logger.error(f"Invalid jwt token: {e}")
|
|
83
|
+
logger.error(f"Invalid jwt token: {e} ({credentials.credentials})")
|
|
84
84
|
raise UNAUTHORIZED_EXCEPTION
|
|
85
85
|
except jwt.InvalidTokenError as e:
|
|
86
|
-
logger.error(f"Invalid jwt token: {e}")
|
|
86
|
+
logger.error(f"Invalid jwt token: {e} ({credentials.credentials})")
|
|
87
87
|
raise UNAUTHORIZED_EXCEPTION
|