Skip to content

Commit

Permalink
updated docs and container for final grafana style
Browse files Browse the repository at this point in the history
  • Loading branch information
FloSch62 committed Apr 10, 2024
1 parent af14e1c commit fa4db31
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 73 deletions.
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ COPY clab2drawio.py /app/
COPY requirements.txt /app/
COPY entrypoint.sh /app/
COPY styles/ /app/styles/
COPY lib/ /app/lib/

# Install any needed packages specified in requirements.txt
RUN pip install --no-cache-dir -r /app/requirements.txt
Expand Down
25 changes: 7 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,29 +25,19 @@ To simplify dependency management and execution, the tools can be run inside a D
#### Pulling from dockerhub

```bash
docker pull flosch62/clab-io-draw:latest
docker pull ghcr.io/srl-labs/clab-io-draw:latest
```

#### Building the Docker Image by yourself

Navigate to the project directory and run:

```bash
docker build -t clab-io-draw .
```

This command builds the Docker image of clab-io-draw with the tag clab-io-draw, using the Dockerfile located in the docker/ directory.

#### Running the Tools

Run drawio2clab or clab2drawio within a Docker container by mounting the directory containing your .drawio/.yaml files as a volume. Specify the input and output file paths relative to the mounted volume:

```bash
docker run -v "$(pwd)":/data flosch62/clab-io-draw -i lab-examples/clos03/cfg-clos.clab.yml
docker run -v "$(pwd)":/data ghcr.io/srl-labs/clab-io-draw -i lab-examples/clos03/cfg-clos.clab.yml
```

```bash
docker run -v "$(pwd)":/data flosch62/clab-io-draw -i output.drawio
docker run -v "$(pwd)":/data ghcr.io/srl-labs/clab-io-draw -i output.drawio
```

Replace your_input_file.drawio and your_output_file.yaml with the names of your actual files. This command mounts your current directory to /data inside the container.
Expand Down Expand Up @@ -86,23 +76,22 @@ Detailed Usages: [drawio2clab.md](docs/drawio2clab.md#usage) and [clab2drawio.md
## drawio2clab

```bash
python drawio2clab.py -i <input_file.drawio> -o <output_file.yaml>
python drawio2clab.py -i <input_file.drawio>
```

`-i, --input`: Specifies the path to your input .drawio file.
`-o, --output`: Specifies the path for the output YAML file.
Make sure to replace `<input_file.drawio>` with the path to your .drawio file and `<output_file.yaml>` with the desired output YAML file path.
Make sure to replace `<input_file.drawio>` with the path to your .drawio file

For more comprehensive guidance, including additional command-line options, please see the Usage section in [drawio2clab.md](docs/drawio2clab.md#usage)

## clab2drawio

```bash
python clab2drawio.py -i <input_file.yaml> -o <output_file.drawio>
python clab2drawio.py -i <input_file.yaml>
```

`-i, --input`: Specifies the path to your input YAML file.
`-o, --output`: Specifies the path for the output drawio file.
Make sure to replace `<input_file.yaml>` with the path to your .drawio file and `<output_file.drawio>` with the desired output YAML file path.
Make sure to replace `<input_file.yaml>` with the path to your .drawio file

For more comprehensive guidance, including additional command-line options, please see the Usage section in [clab2drawio.md](docs/clab2drawio.md#usage)
35 changes: 18 additions & 17 deletions clab2drawio.py
Original file line number Diff line number Diff line change
Expand Up @@ -457,30 +457,30 @@ def adjust_node_levels(diagram):
used_levels = diagram.get_used_levels()
max_level = diagram.get_max_level()
min_level = diagram.get_min_level()
print(f"Initial used levels: {used_levels}")
#print(f"Initial used levels: {used_levels}")
if len(used_levels) <= 1:
print("Only one level present, no adjustment needed.")
#print("Only one level present, no adjustment needed.")
return # Only one level present, no adjustment needed

current_level = min_level
while current_level < max_level + 1:
#if level is the first used level or the last used level, skip it
if current_level == min_level:
print(f"Skip Level: {current_level} because it is the first or last level")
#print(f"Skip Level: {current_level} because it is the first or last level")
current_level += 1
continue

nodes_at_current_level = diagram.get_nodes_by_level(current_level)
nodes_at_next_level = diagram.get_nodes_by_level(current_level + 1)
print(f"Processing level {current_level}:")
print(f"Nodes at current level: {{current_level}} {[node.name for node in nodes_at_current_level.values()]}")
#print(f"Processing level {current_level}:")
#print(f"Nodes at current level: {{current_level}} {[node.name for node in nodes_at_current_level.values()]}")
next_level = current_level + 1
before_level = current_level - 1
nodes_to_move = []
# if nodes_at_next_level:

if len(nodes_at_current_level.items()) == 1:
print(f"Only one node found at level {current_level}. No adjustment needed.")
#print(f"Only one node found at level {current_level}. No adjustment needed.")
current_level += 1
continue
for node_name , node in nodes_at_current_level.items():
Expand All @@ -489,33 +489,33 @@ def adjust_node_levels(diagram):

if not has_upstream_connection:
nodes_to_move.append(node)
else:
print(f"Node {node_name} has {len(node.get_upstream_links_towards_level(before_level))} upstream links against Level {before_level} No adjustment needed.")
#else:
#print(f"Node {node_name} has {len(node.get_upstream_links_towards_level(before_level))} upstream links against Level {before_level} No adjustment needed.")

if (len(nodes_to_move) == len(nodes_at_current_level) ):
print(f"Nothing to move here")
#print(f"Nothing to move here")
current_level += 1
continue
else:
for node in nodes_to_move:
print(f"!Node {node.name} does not have an upstream connection to level {before_level}. Marked for movement.")
#else:
#for node in nodes_to_move:
#print(f"!Node {node.name} does not have an upstream connection to level {before_level}. Marked for movement.")


if nodes_to_move:
print(f"Because we need to move, we are increasing all node_graphlevels from the next Levels Nodes by one level")
#print(f"Because we need to move, we are increasing all node_graphlevels from the next Levels Nodes by one level")

for level in range(max_level, current_level, -1):
nodes_at_level = diagram.get_nodes_by_level(level)
for node in nodes_at_level.values():
node.graph_level += 1
print(f" Moving node {node.name} from level {level} to level {level + 1}.")
#print(f" Moving node {node.name} from level {level} to level {level + 1}.")

# Move the nodes marked for movement to the next level
for node in nodes_to_move:
node.graph_level += 1
print(f" Moving node {node.name} from level {current_level} to level {next_level}")
#print(f" Moving node {node.name} from level {current_level} to level {next_level}")

print(f"Moved nodes at level {current_level} to level {next_level}.")
#print(f"Moved nodes at level {current_level} to level {next_level}.")
update_links(diagram.get_links_from_nodes())
max_level = diagram.get_max_level()

Expand All @@ -539,7 +539,7 @@ def adjust_node_levels(diagram):
level_diff = node.graph_level - link.target.graph_level
if level_diff > 1:
node.graph_level -= 1
print(f" Moving node {node.name} from level {level} to level {level - 1} due to upstream link with level difference > 1")
#print(f" Moving node {node.name} from level {level} to level {level - 1} due to upstream link with level difference > 1")
update_links(diagram.get_links_from_nodes())
max_level = diagram.get_max_level()
break # Stop moving the node after adjusting its level once
Expand Down Expand Up @@ -568,6 +568,7 @@ def assign_graphlevels(diagram, verbose=False):
already_set = True
else:
already_set = False
print("Not all graph levels set in the .clab file. Assigning graph levels based on downstream links. Expect experimental output. Please consider assigning graph levels to your .clab file, or use it with -I for interactive mode. Find more information here: https://github.com/srl-labs/clab-io-draw/blob/grafana_style/docs/clab2drawio.md#influencing-node-placement")

# Helper function to assign graphlevel by recursively checking connections
def set_graphlevel(node, current_graphlevel, visited=None):
Expand Down
36 changes: 15 additions & 21 deletions docs/clab2drawio.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,13 @@
- **Graph-icon Support**: Enhances node visualization by allowing users to specify graph-icon labels such as router, switch, or host to define custom icons for nodes in the generated diagrams.
- **Customizable Styles**: Supports customization of node and link styles within the diagrams.

## Installation

Clone the repository to your local machine:

```bash
git clone https://github.com/FloSch62/clab2drawio.git
cd clab2drawio
```

Ensure you have Python 3.x installed on your system. You can then install the required dependencies:
```bash
pip install -r requirements.txt
```

## Usage
To generate a network topology diagram from a containerlab YAML file, run the following command:

```bash
python clab2drawio.py -i <path_to_your_yaml_file> -o <path_to_output_file>
python clab2drawio.py -i <path_to_your_yaml_file>
```
The output will be a Draw.io diagram file saved in the output path. You can open this file with Draw.io to view and further edit your network topology diagram.
The output will be a Draw.io diagram file saved in the output path. In case without -o, the file will be saved in folder of the input file. You can open this file with Draw.io to view and further edit your network topology diagram.

## Advanced Usage

Expand Down Expand Up @@ -73,17 +59,21 @@ Using graph-level helps manage the vertical alignment of nodes in the generated
```bash
python clab2drawio.py -i <path_to_your_yaml_file> -o <path_to_output_file>
```
- `-g, --gf_dashboard`: Generates a grafana dashboard in grafana style. (WIP)

```bash
python clab2drawio.py -i <path_to_your_yaml_file> -g
```
- `--include-unlinked-nodes`: Include nodes without any links in the topology diagram. By default, only nodes with at least one connection are included.

- `--no-links`: Do not draw links between nodes in the topology diagram. This option can be useful for focusing on node placement or when the connectivity between nodes is not relevant.

- `--layout`: Specifies the layout of the topology diagram (either `vertical` or `horizontal`). The default layout is `vertical`.

- `--theme`: Specifies the theme for the diagram (`bright` or `dark`) or the path to a custom style config file. By default, the `bright` theme is used. Users can also create their own style file and place it in any directory, specifying its path with this option.
- `--theme`: Specifies the theme for the diagram (`nokia_bright` or `nokia_dark`) or the path to a custom style config file. By default, the `bright` theme is used. Users can also create their own style file and place it in any directory, specifying its path with this option. Feel free to contribute your own styles.

```bash
python clab2drawio.py --theme dark -i <path_to_your_yaml_file>
python clab2drawio.py --theme nokia_dark -i <path_to_your_yaml_file>
```

Or using a custom style file:
Expand All @@ -99,10 +89,14 @@ Using graph-level helps manage the vertical alignment of nodes in the generated
The tool allows for customization of node and link styles within the generated diagrams, making it possible to adjust the appearance to fit specific requirements or preferences.

### Custom Styles
To customize styles, you can edit the `clab2drawio_styles.yaml` configuration file. This file defines the base style, link style, source and target label styles, and custom styles for different types of nodes based on their roles (e.g., routers, switches, servers).
To customize styles, you can edit or copy the `nokia_bright.yaml` configuration file. This file defines the base style, link style, source and target label styles, and custom styles for different types of nodes based on their roles (e.g., routers, switches, servers).

An example snippet from `clab2drawio_styles.yaml`:
An example snippet from `nokia_bright.yaml`:
```yaml
#General Diagram settings:
pagew: "auto"
pageh: "auto"
base_style: "shape=image;imageAlign=center;imageVerticalAlign=middle;labelPosition=left;align=right;verticalLabelPosition=top;spacingLeft=0;verticalAlign=bottom;spacingTop=0;spacing=0;"
link_style: "endArrow=none;jumpStyle=gap;"
src_label_style: "verticalLabelPosition=bottom;verticalAlign=top;align=left;spacingLeft=1;spacingTop=1;spacingBottom=0;"
Expand All @@ -120,7 +114,7 @@ icon_to_group_mapping:
```

### Applying Styles
Custom styles are applied to nodes and links based on the configurations specified in the style configuration files (`bright.yaml` for the bright theme and `dark.yaml` for the dark theme), located in the `styles` directory by default. To apply a new style to a node type, update its corresponding style definition in the appropriate YAML file. These styles determine the appearance of nodes and links in the generated diagram, including shapes, colors, and icons.
Custom styles are applied to nodes and links based on the configurations specified in the style configuration files (`nokia_bright.yaml` for the bright theme and `nokia_dark.yaml` for the dark theme), located in the `styles` directory by default. To apply a new style to a node type, update its corresponding style definition in the appropriate YAML file. These styles determine the appearance of nodes and links in the generated diagram, including shapes, colors, and icons.

If you wish to create a completely new style, you can create a new YAML file with your custom configurations. This file can be placed in any directory, and you can specify its path when running the script using the `--theme` option.

Expand Down
9 changes: 5 additions & 4 deletions docs/drawio2clab.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ python drawio2clab.py -i input_file.xml -o output_file.yaml --diagram-name "Diag
```

### Arguments
- -i, --input: Input .drawio XML file.
- -o, --output: Output YAML file.
- --style: YAML style (block or flow). Default is block.
- --diagram-name: Name of the diagram to parse.

- `-i`, `--input`: Input `.drawio` XML file.
- `-o`, `--output`: Output YAML file.
- `--style`: YAML style (`block` or `flow`). Default is `block`.
- `--diagram-name`: Name of the diagram to parse.
26 changes: 13 additions & 13 deletions entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ get_extension() {
# Function to show help message
show_help() {
cat << EOF
Usage: docker run [DOCKER_OPTIONS] flosch62/clab-io-draw -i INPUT_FILE -o OUTPUT_FILE
Usage: docker run -v "$(pwd)":/data ghcr.io/srl-labs/clab-io-draw -i INPUT_FILE
This tool automatically converts between .drawio and .yaml file formats for Container Lab diagrams.
Expand All @@ -19,15 +19,21 @@ Options:
-o, --output Specify the path for the output file. The output format is determined by the input file type.
Examples:
Convert .drawio to .yaml: docker run -v "\$(pwd)":/data flosch62/clab-io-draw -i input.drawio -o output.yaml
Convert .yaml to .drawio: docker run -v "\$(pwd)":/data flosch62/clab-io-draw -i input.yaml -o output.drawio
Convert .drawio to .yaml: docker run -v "\$(pwd)":/data ghcr.io/srl-labs/clab-io-draw -i input.drawio -o output.yaml
Convert .yaml to .drawio: docker run -v "\$(pwd)":/data ghcr.io/srl-labs/clab-io-draw -i input.yaml -o output.drawio
clab2drawio.py help:
$(python -u "/app/clab2drawio.py" -h)
drawio2clab.py help:
$(python -u "/app/drawio2clab.py" -h)
EOF
}

# Check if no arguments were provided
if [ $# -eq 0 ]; then
# Check if no arguments were provided or if help option is specified
if [ $# -eq 0 ] || [[ " $@ " =~ " -h " ]] || [[ " $@ " =~ " --help " ]]; then
show_help
exit 1
exit 0
fi

script_name=""
Expand All @@ -42,12 +48,6 @@ for arg in "$@"; do
prev_arg="$arg"
done

# Check for help option
if [[ " $@ " =~ " -h " ]] || [[ " $@ " =~ " --help " ]]; then
show_help
exit 0
fi

# Determine the script based on file extension
if [ ! -z "$input_file" ]; then
case $(get_extension "$input_file") in
Expand All @@ -68,4 +68,4 @@ else
fi

# Execute the determined script with all passed arguments
python -u "/app/${script_name}" "$@"
python -u "/app/${script_name}" "$@"

0 comments on commit fa4db31

Please sign in to comment.