diff --git a/d3fendtools/as_mermaid/__init__.py b/d3fendtools/as_mermaid/__init__.py index 5e0bca8..53218d4 100644 --- a/d3fendtools/as_mermaid/__init__.py +++ b/d3fendtools/as_mermaid/__init__.py @@ -139,6 +139,7 @@ class RDF2Mermaid: K8S.Namespace, K8S.Registry, K8S.Application, + K8S.Service, # DC are groups. K8S.DeploymentConfig, K8S.Deployment, @@ -333,11 +334,11 @@ def render(self): return ret @staticmethod - def create_tree(tree): + def create_tree(tree: dict): """Create a tree of subgraphs according to mermaid syntax.""" rendered = set() - def _render_tree(parent, data): + def _render_tree(parent, data, is_namespace=False): label = data.get("label") or "" parent_type = data.get("type") children = data.get("children") or [] @@ -352,7 +353,7 @@ def _render_tree(parent, data): continue if child == parent: continue - if parent_type == K8S.Namespace: + if (is_namespace, parent_type) == (False, K8S.Namespace): # Namespace should be processed last. # Deployment* and Service* should be processed # under Application. @@ -402,5 +403,7 @@ def _render_tree(parent, data): tree_namespace.append((parent, data)) continue yield from _render_tree(parent, data) + + # Render namespaces last. for parent, data in tree_namespace: - yield from _render_tree(parent, data) + yield from _render_tree(parent, data, is_namespace=True) diff --git a/d3fendtools/as_mermaid/__main__.py b/d3fendtools/as_mermaid/__main__.py index b923ae7..e35bb90 100644 --- a/d3fendtools/as_mermaid/__main__.py +++ b/d3fendtools/as_mermaid/__main__.py @@ -12,7 +12,7 @@ @click.command() -@click.argument("files", nargs=-1, type=click.Path(exists=True)) +@click.argument("files", nargs=-1, type=click.Path(exists=True), required=True) @click.option("--output", "-o", help="Output markdown file") def main(files, output): output_md = Path(output) diff --git a/d3fendtools/kuberdf/base.py b/d3fendtools/kuberdf/base.py index f1283bb..51359d0 100644 --- a/d3fendtools/kuberdf/base.py +++ b/d3fendtools/kuberdf/base.py @@ -224,6 +224,9 @@ def __init__(self, manifest: dict | None = None, ns: str = None) -> None: self.kind = manifest["kind"] self.metadata = manifest["metadata"] self.name = self.metadata["name"] + from urllib.parse import quote + + self.name = quote(self.name, safe="") self.namespace = manifest["metadata"].get("namespace", ns or "default") self.ns = URIRef(f"https://k8s.local/{self.namespace}") self.spec = manifest.get("spec", {})