mrok 0.5.0__py3-none-any.whl → 0.6.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/proxy/master.py CHANGED
@@ -1,5 +1,3 @@
1
- import asyncio
2
- import contextlib
3
1
  import logging
4
2
  import os
5
3
  import signal
@@ -10,20 +8,14 @@ from pathlib import Path
10
8
  from uuid import uuid4
11
9
 
12
10
  import zmq
13
- import zmq.asyncio
14
- from uvicorn.importer import import_from_string
15
11
  from watchfiles import watch
16
12
  from watchfiles.filters import PythonFilter
17
13
  from watchfiles.run import CombinedProcess, start_process
18
14
 
19
15
  from mrok.conf import get_settings
20
16
  from mrok.logging import setup_logging
21
- from mrok.proxy.config import MrokBackendConfig
22
- from mrok.proxy.datastructures import Event, HTTPResponse, Status, ZitiIdentity
23
- from mrok.proxy.metrics import WorkerMetricsCollector
24
- from mrok.proxy.middlewares import CaptureMiddleware, LifespanMiddleware, MetricsMiddleware
25
- from mrok.proxy.server import MrokServer
26
- from mrok.proxy.types import ASGIApp
17
+ from mrok.proxy.worker import Worker
18
+ from mrok.types.proxy import ASGIApp
27
19
 
28
20
  logger = logging.getLogger("mrok.agent")
29
21
 
@@ -62,76 +54,41 @@ def start_uvicorn_worker(
62
54
  worker_id: str,
63
55
  app: ASGIApp | str,
64
56
  identity_file: str,
57
+ events_enabled: bool,
65
58
  events_pub_port: int,
66
59
  metrics_interval: float = 5.0,
67
60
  ):
68
61
  import sys
69
62
 
70
63
  sys.path.insert(0, os.getcwd())
71
- asgi_app = app if not isinstance(app, str) else import_from_string(app)
72
64
 
73
- setup_logging(get_settings())
74
- identity = ZitiIdentity.load_from_file(identity_file)
75
- ctx = zmq.asyncio.Context()
76
- pub = ctx.socket(zmq.PUB)
77
- pub.connect(f"tcp://localhost:{events_pub_port}")
78
- metrics = WorkerMetricsCollector(worker_id)
79
-
80
- task = None
81
-
82
- async def status_sender(): # pragma: no cover
83
- while True:
84
- snap = await metrics.snapshot()
85
- event = Event(type="status", data=Status(meta=identity.mrok, metrics=snap))
86
- await pub.send_string(event.model_dump_json())
87
- await asyncio.sleep(metrics_interval)
88
-
89
- async def on_startup(): # pragma: no cover
90
- nonlocal task
91
- await asyncio.sleep(0)
92
- task = asyncio.create_task(status_sender())
93
-
94
- async def on_shutdown(): # pragma: no cover
95
- await asyncio.sleep(0)
96
- if task:
97
- task.cancel()
98
-
99
- async def on_response_complete(response: HTTPResponse): # pragma: no cover
100
- event = Event(type="response", data=response)
101
- await pub.send_string(event.model_dump_json())
102
-
103
- config = MrokBackendConfig(
104
- LifespanMiddleware(
105
- MetricsMiddleware(
106
- CaptureMiddleware(
107
- asgi_app,
108
- on_response_complete,
109
- ),
110
- metrics,
111
- ),
112
- on_startup=on_startup,
113
- on_shutdown=on_shutdown,
114
- ),
65
+ worker = Worker(
66
+ worker_id,
67
+ app,
115
68
  identity_file,
69
+ events_enabled=events_enabled,
70
+ event_publisher_port=events_pub_port,
71
+ metrics_interval=metrics_interval,
116
72
  )
117
- server = MrokServer(config)
118
- with contextlib.suppress(KeyboardInterrupt, asyncio.CancelledError):
119
- server.run()
73
+ worker.run()
120
74
 
121
75
 
122
76
  class MasterBase(ABC):
123
77
  def __init__(
124
78
  self,
125
79
  identity_file: str,
126
- workers: int,
127
- reload: bool,
128
- events_pub_port: int,
129
- events_sub_port: int,
80
+ *,
81
+ workers: int = 4,
82
+ reload: bool = False,
83
+ events_enabled: bool = True,
84
+ events_pub_port: int = 50000,
85
+ events_sub_port: int = 50001,
130
86
  metrics_interval: float = 5.0,
131
87
  ):
132
88
  self.identity_file = identity_file
133
89
  self.workers = workers
134
90
  self.reload = reload
91
+ self.events_enabled = events_enabled
135
92
  self.events_pub_port = events_pub_port
136
93
  self.events_sub_port = events_sub_port
137
94
  self.metrics_interval = metrics_interval
@@ -171,6 +128,7 @@ class MasterBase(ABC):
171
128
  worker_id,
172
129
  self.get_asgi_app(),
173
130
  self.identity_file,
131
+ self.events_enabled,
174
132
  self.events_pub_port,
175
133
  self.metrics_interval,
176
134
  ),
mrok/proxy/metrics.py CHANGED
@@ -8,7 +8,7 @@ import time
8
8
  import psutil
9
9
  from hdrh.histogram import HdrHistogram
10
10
 
11
- from mrok.proxy.datastructures import (
11
+ from mrok.proxy.models import (
12
12
  DataTransferMetrics,
13
13
  ProcessMetrics,
14
14
  RequestsMetrics,
@@ -49,7 +49,7 @@ async def get_process_metrics(interval: float = 0.1) -> ProcessMetrics:
49
49
  return await asyncio.to_thread(_collect_process_usage, interval)
50
50
 
51
51
 
52
- class WorkerMetricsCollector:
52
+ class MetricsCollector:
53
53
  def __init__(self, worker_id: str, lowest=1, highest=60000, sigfigs=3):
54
54
  self.worker_id = worker_id
55
55
  self.total_requests = 0
@@ -3,18 +3,17 @@ import logging
3
3
  import time
4
4
 
5
5
  from mrok.proxy.constants import MAX_REQUEST_BODY_BYTES, MAX_RESPONSE_BODY_BYTES
6
- from mrok.proxy.datastructures import FixedSizeByteBuffer, HTTPHeaders, HTTPRequest, HTTPResponse
7
- from mrok.proxy.metrics import WorkerMetricsCollector
8
- from mrok.proxy.types import (
6
+ from mrok.proxy.metrics import MetricsCollector
7
+ from mrok.proxy.models import FixedSizeByteBuffer, HTTPHeaders, HTTPRequest, HTTPResponse
8
+ from mrok.proxy.utils import must_capture_request, must_capture_response
9
+ from mrok.types.proxy import (
9
10
  ASGIApp,
10
11
  ASGIReceive,
11
12
  ASGISend,
12
- LifespanCallback,
13
13
  Message,
14
14
  ResponseCompleteCallback,
15
15
  Scope,
16
16
  )
17
- from mrok.proxy.utils import must_capture_request, must_capture_response
18
17
 
19
18
  logger = logging.getLogger("mrok.proxy")
20
19
 
@@ -99,7 +98,7 @@ class CaptureMiddleware:
99
98
 
100
99
 
101
100
  class MetricsMiddleware:
102
- def __init__(self, app: ASGIApp, metrics: WorkerMetricsCollector):
101
+ def __init__(self, app: ASGIApp, metrics: MetricsCollector):
103
102
  self.app = app
104
103
  self.metrics = metrics
105
104
 
@@ -133,32 +132,3 @@ class MetricsMiddleware:
133
132
  await self.app(scope, wrapped_receive, wrapped_send)
134
133
  finally:
135
134
  await self.metrics.on_request_end(start_time, status_code)
136
-
137
-
138
- class LifespanMiddleware:
139
- def __init__(
140
- self,
141
- app,
142
- on_startup: LifespanCallback | None = None,
143
- on_shutdown: LifespanCallback | None = None,
144
- ):
145
- self.app = app
146
- self.on_startup = on_startup
147
- self.on_shutdown = on_shutdown
148
-
149
- async def __call__(self, scope, receive, send):
150
- if scope["type"] == "lifespan":
151
- while True:
152
- event = await receive()
153
- if event["type"] == "lifespan.startup":
154
- if self.on_startup: # pragma: no branch
155
- await self.on_startup()
156
- await send({"type": "lifespan.startup.complete"})
157
-
158
- elif event["type"] == "lifespan.shutdown":
159
- if self.on_shutdown: # pragma: no branch
160
- await self.on_shutdown()
161
- await send({"type": "lifespan.shutdown.complete"})
162
- break
163
- else:
164
- await self.app(scope, receive, send)
@@ -8,7 +8,7 @@ from pydantic import BaseModel, ConfigDict, Field, field_validator
8
8
  from pydantic_core import core_schema
9
9
 
10
10
 
11
- class ZitiId(BaseModel):
11
+ class X509Credentials(BaseModel):
12
12
  key: str
13
13
  cert: str
14
14
  ca: str
@@ -21,7 +21,7 @@ class ZitiId(BaseModel):
21
21
  return value
22
22
 
23
23
 
24
- class ZitiMrokMeta(BaseModel):
24
+ class ServiceMetadata(BaseModel):
25
25
  model_config = ConfigDict(extra="ignore")
26
26
  identity: str
27
27
  extension: str
@@ -30,21 +30,21 @@ class ZitiMrokMeta(BaseModel):
30
30
  tags: dict[str, str | bool | None] | None = None
31
31
 
32
32
 
33
- class ZitiIdentity(BaseModel):
33
+ class Identity(BaseModel):
34
34
  model_config = ConfigDict(extra="ignore")
35
35
  zt_api: str = Field(validation_alias="ztAPI")
36
- id: ZitiId
36
+ id: X509Credentials
37
37
  zt_apis: str | None = Field(default=None, validation_alias="ztAPIs")
38
38
  config_types: str | None = Field(default=None, validation_alias="configTypes")
39
39
  enable_ha: bool = Field(default=False, validation_alias="enableHa")
40
- mrok: ZitiMrokMeta | None = None
40
+ mrok: ServiceMetadata | None = None
41
41
 
42
42
  @staticmethod
43
- def load_from_file(path: str | Path) -> ZitiIdentity:
43
+ def load_from_file(path: str | Path) -> Identity:
44
44
  path = Path(path)
45
45
  with path.open("r", encoding="utf-8") as f:
46
46
  data = json.load(f)
47
- return ZitiIdentity.model_validate(data)
47
+ return Identity.model_validate(data)
48
48
 
49
49
 
50
50
  class FixedSizeByteBuffer:
@@ -183,7 +183,7 @@ class WorkerMetrics(BaseModel):
183
183
 
184
184
  class Status(BaseModel):
185
185
  type: Literal["status"] = "status"
186
- meta: ZitiMrokMeta
186
+ meta: ServiceMetadata
187
187
  metrics: WorkerMetrics
188
188
 
189
189
 
@@ -1,8 +1,24 @@
1
1
  import asyncio
2
+ import select
3
+ import sys
4
+ from typing import Any
2
5
 
3
6
  from httpcore import AsyncNetworkStream
4
7
 
5
- from mrok.proxy.types import ASGIReceive
8
+ from mrok.types.proxy import ASGIReceive
9
+
10
+
11
+ def is_readable(sock): # pragma: no cover
12
+ # Stolen from
13
+ # https://github.com/python-trio/trio/blob/20ee2b1b7376db637435d80e266212a35837ddcc/trio/_socket.py#L471C1-L478C31
14
+
15
+ # use select.select on Windows, and select.poll everywhere else
16
+ if sys.platform == "win32":
17
+ rready, _, _ = select.select([sock], [], [], 0)
18
+ return bool(rready)
19
+ p = select.poll()
20
+ p.register(sock, select.POLLIN)
21
+ return bool(p.poll(0))
6
22
 
7
23
 
8
24
  class AIONetworkStream(AsyncNetworkStream):
@@ -21,6 +37,13 @@ class AIONetworkStream(AsyncNetworkStream):
21
37
  self._writer.close()
22
38
  await self._writer.wait_closed()
23
39
 
40
+ def get_extra_info(self, info: str) -> Any:
41
+ transport = self._writer.transport
42
+ if info == "is_readable":
43
+ sock = transport.get_extra_info("socket")
44
+ return is_readable(sock)
45
+ return transport.get_extra_info(info)
46
+
24
47
 
25
48
  class ASGIRequestBodyStream:
26
49
  def __init__(self, receive: ASGIReceive):
mrok/proxy/worker.py ADDED
@@ -0,0 +1,64 @@
1
+ import asyncio
2
+ import contextlib
3
+ import logging
4
+ from pathlib import Path
5
+
6
+ from uvicorn.importer import import_from_string
7
+
8
+ from mrok.conf import get_settings
9
+ from mrok.logging import setup_logging
10
+ from mrok.proxy.asgi import ASGIAppWrapper
11
+ from mrok.proxy.event_publisher import EventPublisher
12
+ from mrok.proxy.models import Identity
13
+ from mrok.proxy.ziticorn import BackendConfig, Server
14
+ from mrok.types.proxy import ASGIApp
15
+
16
+ logger = logging.getLogger("mrok.proxy")
17
+
18
+
19
+ class Worker:
20
+ def __init__(
21
+ self,
22
+ worker_id: str,
23
+ app: ASGIApp | str,
24
+ identity_file: str | Path,
25
+ *,
26
+ events_enabled: bool = True,
27
+ event_publisher_port: int = 50000,
28
+ metrics_interval: float = 5.0,
29
+ ):
30
+ self._worker_id = worker_id
31
+ self._identity_file = identity_file
32
+ self._identity = Identity.load_from_file(self._identity_file)
33
+ self._app = app
34
+
35
+ self._events_enabled = events_enabled
36
+ self._event_publisher = (
37
+ EventPublisher(
38
+ worker_id=worker_id,
39
+ meta=self._identity.mrok,
40
+ event_publisher_port=event_publisher_port,
41
+ metrics_interval=metrics_interval,
42
+ )
43
+ if events_enabled
44
+ else None
45
+ )
46
+
47
+ def setup_app(self):
48
+ app = ASGIAppWrapper(
49
+ self._app if not isinstance(self._app, str) else import_from_string(self._app),
50
+ lifespan=self._event_publisher.lifespan if self._events_enabled else None,
51
+ )
52
+
53
+ if self._events_enabled:
54
+ self._event_publisher.setup_middleware(app)
55
+ return app
56
+
57
+ def run(self):
58
+ setup_logging(get_settings())
59
+ app = self.setup_app()
60
+
61
+ config = BackendConfig(app, self._identity_file)
62
+ server = Server(config)
63
+ with contextlib.suppress(KeyboardInterrupt, asyncio.CancelledError):
64
+ server.run()
@@ -6,17 +6,40 @@ from pathlib import Path
6
6
  from typing import Any
7
7
 
8
8
  import openziti
9
- from uvicorn import config
9
+ from uvicorn import config, server
10
+ from uvicorn.lifespan.on import LifespanOn
11
+ from uvicorn.protocols.http.httptools_impl import HttpToolsProtocol as UvHttpToolsProtocol
10
12
 
11
- from mrok.proxy.protocol import MrokHttpToolsProtocol
12
- from mrok.proxy.types import ASGIApp
13
+ from mrok.types.proxy import ASGIApp
13
14
 
14
15
  logger = logging.getLogger("mrok.proxy")
15
16
 
16
- config.LIFESPAN["auto"] = "mrok.proxy.lifespan:MrokLifespan"
17
+ config.LIFESPAN["auto"] = "mrok.proxy.ziticorn:Lifespan"
17
18
 
18
19
 
19
- class MrokBackendConfig(config.Config):
20
+ class Lifespan(LifespanOn):
21
+ def __init__(self, lf_config: config.Config) -> None:
22
+ super().__init__(lf_config)
23
+ self.logger = logging.getLogger("mrok.proxy")
24
+
25
+
26
+ class HttpToolsProtocol(UvHttpToolsProtocol):
27
+ def __init__(self, *args, **kwargs):
28
+ super().__init__(*args, **kwargs)
29
+ self.logger = logging.getLogger("mrok.proxy")
30
+ self.access_logger = logging.getLogger("mrok.access")
31
+ self.access_log = self.access_logger.hasHandlers()
32
+
33
+
34
+ class Server(server.Server):
35
+ async def serve(self, sockets: list[socket.socket] | None = None) -> None:
36
+ if not sockets:
37
+ sockets = [self.config.bind_socket()]
38
+ with self.capture_signals():
39
+ await self._serve(sockets)
40
+
41
+
42
+ class BackendConfig(config.Config):
20
43
  def __init__(
21
44
  self,
22
45
  app: ASGIApp | Callable[..., Any] | str,
@@ -32,7 +55,7 @@ class MrokBackendConfig(config.Config):
32
55
  super().__init__(
33
56
  app,
34
57
  loop="asyncio",
35
- http=MrokHttpToolsProtocol,
58
+ http=HttpToolsProtocol,
36
59
  backlog=backlog,
37
60
  )
38
61
 
mrok/types/__init__.py ADDED
File without changes
@@ -1,9 +1,10 @@
1
1
  from __future__ import annotations
2
2
 
3
- from collections.abc import Awaitable, Callable, Coroutine, MutableMapping
3
+ from collections.abc import Awaitable, Callable, Coroutine, Mapping, MutableMapping
4
+ from contextlib import AbstractAsyncContextManager
4
5
  from typing import Any, Never
5
6
 
6
- from mrok.proxy.datastructures import HTTPResponse
7
+ from mrok.proxy.models import HTTPResponse
7
8
 
8
9
  Scope = MutableMapping[str, Any]
9
10
  Message = MutableMapping[str, Any]
@@ -11,5 +12,9 @@ Message = MutableMapping[str, Any]
11
12
  ASGIReceive = Callable[[], Awaitable[Message]]
12
13
  ASGISend = Callable[[Message], Awaitable[None]]
13
14
  ASGIApp = Callable[[Scope, ASGIReceive, ASGISend], Awaitable[None]]
15
+ StatelessLifespan = Callable[[ASGIApp], AbstractAsyncContextManager[None]]
16
+ StatefulLifespan = Callable[[ASGIApp], AbstractAsyncContextManager[Mapping[str, Any]]]
17
+ Lifespan = StatelessLifespan | StatefulLifespan
18
+
14
19
  LifespanCallback = Callable[[], Awaitable[None]]
15
20
  ResponseCompleteCallback = Callable[[HTTPResponse], Coroutine[Any, Any, Never]]
mrok/types/ziti.py ADDED
@@ -0,0 +1 @@
1
+ Tags = dict[str, str | bool | None]
mrok/ziti/api.py CHANGED
@@ -11,12 +11,11 @@ from typing import Any, Literal
11
11
  import httpx
12
12
 
13
13
  from mrok.conf import Settings
14
+ from mrok.types.ziti import Tags
14
15
  from mrok.ziti.constants import MROK_VERSION_TAG, MROK_VERSION_TAG_NAME
15
16
 
16
17
  logger = logging.getLogger(__name__)
17
18
 
18
- TagsType = dict[str, str | bool | None]
19
-
20
19
 
21
20
  class ZitiAPIError(Exception):
22
21
  pass
@@ -70,7 +69,7 @@ class BaseZitiAPI(ABC):
70
69
  ),
71
70
  )
72
71
 
73
- async def create(self, endpoint: str, payload: dict[str, Any], tags: TagsType | None) -> str:
72
+ async def create(self, endpoint: str, payload: dict[str, Any], tags: Tags | None) -> str:
74
73
  payload["tags"] = self._merge_tags(tags)
75
74
  response: httpx.Response = await self.httpx_client.post(
76
75
  endpoint,
@@ -156,8 +155,8 @@ class BaseZitiAPI(ABC):
156
155
  ) -> None:
157
156
  return await self.httpx_client.__aexit__(exc_type, exc_val, exc_tb)
158
157
 
159
- def _merge_tags(self, tags: TagsType | None) -> TagsType:
160
- prepared_tags: TagsType = tags or {}
158
+ def _merge_tags(self, tags: Tags | None) -> Tags:
159
+ prepared_tags: Tags = tags or {}
161
160
  prepared_tags.update(MROK_VERSION_TAG)
162
161
  return prepared_tags
163
162
 
@@ -281,9 +280,7 @@ class ZitiManagementAPI(BaseZitiAPI):
281
280
  async def search_config(self, id_or_name) -> dict[str, Any] | None:
282
281
  return await self.search_by_id_or_name("/configs", id_or_name)
283
282
 
284
- async def create_config(
285
- self, name: str, config_type_id: str, tags: TagsType | None = None
286
- ) -> str:
283
+ async def create_config(self, name: str, config_type_id: str, tags: Tags | None = None) -> str:
287
284
  return await self.create(
288
285
  "/configs",
289
286
  {
@@ -302,7 +299,7 @@ class ZitiManagementAPI(BaseZitiAPI):
302
299
  async def delete_config(self, config_id: str) -> None:
303
300
  return await self.delete("/configs", config_id)
304
301
 
305
- async def create_config_type(self, name: str, tags: TagsType | None = None) -> str:
302
+ async def create_config_type(self, name: str, tags: Tags | None = None) -> str:
306
303
  return await self.create(
307
304
  "/config-types",
308
305
  {
@@ -316,7 +313,7 @@ class ZitiManagementAPI(BaseZitiAPI):
316
313
  self,
317
314
  name: str,
318
315
  config_id: str,
319
- tags: TagsType | None = None,
316
+ tags: Tags | None = None,
320
317
  ) -> str:
321
318
  return await self.create(
322
319
  "/services",
@@ -332,7 +329,7 @@ class ZitiManagementAPI(BaseZitiAPI):
332
329
  self,
333
330
  name: str,
334
331
  service_id: str,
335
- tags: TagsType | None = None,
332
+ tags: Tags | None = None,
336
333
  ) -> str:
337
334
  return await self.create(
338
335
  "/service-edge-router-policies",
@@ -351,7 +348,7 @@ class ZitiManagementAPI(BaseZitiAPI):
351
348
  self,
352
349
  name: str,
353
350
  identity_id: str,
354
- tags: TagsType | None = None,
351
+ tags: Tags | None = None,
355
352
  ) -> str:
356
353
  return await self.create(
357
354
  "/edge-router-policies",
@@ -385,10 +382,10 @@ class ZitiManagementAPI(BaseZitiAPI):
385
382
  async def delete_service(self, service_id: str) -> None:
386
383
  return await self.delete("/services", service_id)
387
384
 
388
- async def create_user_identity(self, name: str, tags: TagsType | None = None) -> str:
385
+ async def create_user_identity(self, name: str, tags: Tags | None = None) -> str:
389
386
  return await self._create_identity(name, "User", tags=tags)
390
387
 
391
- async def create_device_identity(self, name: str, tags: TagsType | None = None) -> str:
388
+ async def create_device_identity(self, name: str, tags: Tags | None = None) -> str:
392
389
  return await self._create_identity(name, "Device", tags=tags)
393
390
 
394
391
  async def search_identity(self, id_or_name: str) -> dict[str, Any] | None:
@@ -412,12 +409,12 @@ class ZitiManagementAPI(BaseZitiAPI):
412
409
  return response.text
413
410
 
414
411
  async def create_dial_service_policy(
415
- self, name: str, service_id: str, identity_id: str, tags: TagsType | None = None
412
+ self, name: str, service_id: str, identity_id: str, tags: Tags | None = None
416
413
  ) -> str:
417
414
  return await self._create_service_policy("Dial", name, service_id, identity_id, tags)
418
415
 
419
416
  async def create_bind_service_policy(
420
- self, name: str, service_id: str, identity_id: str, tags: TagsType | None = None
417
+ self, name: str, service_id: str, identity_id: str, tags: Tags | None = None
421
418
  ) -> str:
422
419
  return await self._create_service_policy("Bind", name, service_id, identity_id, tags)
423
420
 
@@ -433,7 +430,7 @@ class ZitiManagementAPI(BaseZitiAPI):
433
430
  name: str,
434
431
  service_id: str,
435
432
  identity_id: str,
436
- tags: TagsType | None = None,
433
+ tags: Tags | None = None,
437
434
  ) -> str:
438
435
  return await self.create(
439
436
  "/service-policies",
@@ -451,7 +448,7 @@ class ZitiManagementAPI(BaseZitiAPI):
451
448
  self,
452
449
  name: str,
453
450
  type: Literal["User", "Device", "Default"],
454
- tags: TagsType | None = None,
451
+ tags: Tags | None = None,
455
452
  ) -> str:
456
453
  return await self.create(
457
454
  "/identities",
mrok/ziti/bootstrap.py CHANGED
@@ -1,7 +1,8 @@
1
1
  import logging
2
2
  from typing import Any
3
3
 
4
- from mrok.ziti.api import TagsType, ZitiClientAPI, ZitiManagementAPI
4
+ from mrok.types.ziti import Tags
5
+ from mrok.ziti.api import ZitiClientAPI, ZitiManagementAPI
5
6
  from mrok.ziti.identities import enroll_proxy_identity
6
7
 
7
8
  logger = logging.getLogger(__name__)
@@ -13,7 +14,7 @@ async def bootstrap_identity(
13
14
  identity_name: str,
14
15
  mode: str,
15
16
  forced: bool,
16
- tags: TagsType | None,
17
+ tags: Tags | None,
17
18
  ) -> tuple[str, dict[str, Any] | None]:
18
19
  logger.info(f"Bootstrapping '{identity_name}' identity...")
19
20
 
mrok/ziti/identities.py CHANGED
@@ -5,8 +5,9 @@ from typing import Any
5
5
  import jwt
6
6
 
7
7
  from mrok.conf import Settings
8
+ from mrok.types.ziti import Tags
8
9
  from mrok.ziti import pki
9
- from mrok.ziti.api import TagsType, ZitiClientAPI, ZitiManagementAPI
10
+ from mrok.ziti.api import ZitiClientAPI, ZitiManagementAPI
10
11
  from mrok.ziti.constants import (
11
12
  MROK_IDENTITY_TYPE_TAG_NAME,
12
13
  MROK_IDENTITY_TYPE_TAG_VALUE_INSTANCE,
@@ -29,7 +30,7 @@ async def register_identity(
29
30
  client_api: ZitiClientAPI,
30
31
  service_external_id: str,
31
32
  identity_external_id: str,
32
- tags: TagsType | None = None,
33
+ tags: Tags | None = None,
33
34
  ):
34
35
  service_name = service_external_id.lower()
35
36
  identity_tags = copy.copy(tags or {})
@@ -39,7 +40,7 @@ async def register_identity(
39
40
  if not service:
40
41
  raise ServiceNotFoundError(f"A service with name `{service_external_id}` does not exists.")
41
42
 
42
- identity_name = f"{identity_external_id.lower()}.{service_name}"
43
+ identity_name = identity_external_id.lower()
43
44
  service_policy_name = f"{identity_name}:bind"
44
45
  self_service_policy_name = f"self.{service_policy_name}"
45
46
 
@@ -129,7 +130,7 @@ async def enroll_proxy_identity(
129
130
  mgmt_api: ZitiManagementAPI,
130
131
  client_api: ZitiClientAPI,
131
132
  identity_name: str,
132
- tags: TagsType | None = None,
133
+ tags: Tags | None = None,
133
134
  ):
134
135
  identity = await mgmt_api.search_identity(identity_name)
135
136
  if identity:
mrok/ziti/services.py CHANGED
@@ -2,7 +2,8 @@ import logging
2
2
  from typing import Any
3
3
 
4
4
  from mrok.conf import Settings
5
- from mrok.ziti.api import TagsType, ZitiManagementAPI
5
+ from mrok.types.ziti import Tags
6
+ from mrok.ziti.api import ZitiManagementAPI
6
7
  from mrok.ziti.errors import (
7
8
  ConfigTypeNotFoundError,
8
9
  ProxyIdentityNotFoundError,
@@ -14,7 +15,7 @@ logger = logging.getLogger(__name__)
14
15
 
15
16
 
16
17
  async def register_service(
17
- settings: Settings, mgmt_api: ZitiManagementAPI, external_id: str, tags: TagsType | None
18
+ settings: Settings, mgmt_api: ZitiManagementAPI, external_id: str, tags: Tags | None
18
19
  ) -> dict[str, Any]:
19
20
  service_name = external_id.lower()
20
21
  registered = False
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mrok
3
- Version: 0.5.0
3
+ Version: 0.6.0
4
4
  Summary: MPT Extensions OpenZiti Orchestrator
5
5
  Author: SoftwareOne AG
6
6
  License: Apache License