diff --git a/README.md b/README.md
index e5267c2..ae7e9a0 100644
--- a/README.md
+++ b/README.md
@@ -18,12 +18,12 @@ Install it via:
`pip3 install compose_plantuml`
After that use it like:
-`compose_plantuml docker-compose.yml`
+`compose_plantuml --link-graph docker-compose.yml`
### Via Docker
Use it like:
-`cat docker-compose.yml | docker run -i funkwerk/compose_plantuml`
+`cat docker-compose.yml | docker run -i funkwerk/compose_plantuml --link-graph`
## Link Graph
@@ -52,6 +52,33 @@ Rendered it looks like:
+## Boundaries
+
+Boundaries visualize the external boundaries a system has.
+
+Consider the following docker-compose.yml
+
+```
+version: '2'
+services:
+ service:
+ ports:
+ - 8080:80
+```
+
+When calling 'compose_plantuml --boundaries docker-compose.yml' it will generate the following plantuml:
+
+```
+rectangle system {
+ [service]
+}
+[service] --> 8080 : 80
+```
+
+Rendered it looks like:
+
+
+
## Related Links
- draw compose
diff --git a/bin/compose_plantuml b/bin/compose_plantuml
index 3de7b8a..7c15937 100755
--- a/bin/compose_plantuml
+++ b/bin/compose_plantuml
@@ -9,31 +9,36 @@ if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument(
- '--replace', action='store_const', const=True,
- help='should the original file be replaced?', default=False, )
+ '--link-graph', action='store_const', const=True,
+ help='prints a link graph', default=False, )
parser.add_argument(
- '--ignore_changes', action='store_const', const=False,
- help='ignore changes for return code',
- default=True,
- )
- parser.add_argument(
- '--non_strict', action='store_const', const=True,
- help='if this is provided, unknown keys errors are ignored',
+ '--boundaries', action='store_const', const=True,
+ help='prints the system boundaries',
default=False,
)
parser.add_argument('files', nargs=argparse.REMAINDER)
args = parser.parse_args()
plantuml = ComposePlantuml()
- if len(args.files) == 0:
- assert args.replace is False, 'replace makes no sense when reading from stdin'
+ if not args.link_graph and not args.boundaries:
+ print('specify an output option. link_graph or boundaries')
+ sys.exit(1)
- data = sys.stdin.read()
- formatted = plantuml.print_links(data)
-
- for path in args.files:
+ def execute(data):
try:
- plantuml.print_links_from_file(path)
+ parsed = plantuml.parse(data)
except VersionException as exception:
print('docker-compose version exception: {0}'.format(exception.message))
sys.exit(1)
+
+ if args.link_graph:
+ print(plantuml.link_graph(parsed))
+ if args.boundaries:
+ print(plantuml.boundaries(parsed))
+
+ if len(args.files) == 0:
+ execute(sys.stdin.read())
+
+ for path in args.files:
+ with open(path, 'r') as file:
+ execute(file.read())
diff --git a/compose_plantuml/__init__.py b/compose_plantuml/__init__.py
index a183502..8e3dda4 100755
--- a/compose_plantuml/__init__.py
+++ b/compose_plantuml/__init__.py
@@ -7,19 +7,34 @@ class ComposePlantuml:
def __init__(self):
pass
- def print_links_from_file(self, path):
- with open(path, 'r') as file:
- self.print_links(file.read())
-
- def print_links(self, data):
+ def parse(self, data):
compose = load(data)
self.require_version_2(compose)
+ return compose
+
+ def link_graph(self, compose):
+ result = 'skinparam componentStyle uml2\n'
for component in sorted(self.components(compose)):
- print('[{0}]'.format(component))
+ result += '[{0}]\n'.format(component)
for source, destination in sorted(self.links(compose)):
- print('[{0}] --> [{1}]'.format(source, destination))
+ result += '[{0}] --> [{1}]\n'.format(source, destination)
+ return result.strip()
+
+ def boundaries(self, compose):
+ result = 'skinparam componentStyle uml2\n'
+
+ result += 'rectangle system {\n'
+ for component in sorted(self.components(compose)):
+ result += ' [{0}]\n'.format(component)
+ result += '}\n'
+ for service, host, container in sorted(self.ports(compose)):
+ port = host
+ if container is not None:
+ port = '{0} : {1}'.format(host, container)
+ result += '[{0}] --> {1}\n'.format(service, port)
+ return result.strip()
@staticmethod
def components(compose):
@@ -37,6 +52,21 @@ def links(compose):
result.append((component_name, link))
return result
+ @staticmethod
+ def ports(compose):
+ result = []
+
+ for component_name in compose.get('services', []):
+ component = compose['services'][component_name]
+
+ for port in component.get('ports', []):
+ port = str(port)
+ host, container = (port, None)
+ if ':' in port:
+ host, container = port.split(':')
+ result.append((component_name, host, container))
+ return result
+
@staticmethod
def require_version_2(compose):
if 'version' not in compose:
diff --git a/features/boundaries.feature b/features/boundaries.feature
new file mode 100644
index 0000000..ace24b1
--- /dev/null
+++ b/features/boundaries.feature
@@ -0,0 +1,44 @@
+Feature: Boundaries
+ As a DevOps,
+ I want to see the boundaries of a system
+ so that I know how to interact with it.
+
+ Scenario: Exposed ports
+ Given a file named "compose.yml" with:
+ """
+ version: "2"
+ services:
+ service:
+ ports:
+ - 8080
+ """
+ When I run `bin/compose_plantuml --boundaries compose.yml`
+ Then it should pass with exactly:
+ """
+ skinparam componentStyle uml2
+ rectangle system {
+ [service]
+ }
+ [service] --> 8080
+
+ """
+
+ Scenario: Alias Ports
+ Given a file named "compose.yml" with:
+ """
+ version: "2"
+ services:
+ service:
+ ports:
+ - 8080:80
+ """
+ When I run `bin/compose_plantuml --boundaries compose.yml`
+ Then it should pass with exactly:
+ """
+ skinparam componentStyle uml2
+ rectangle system {
+ [service]
+ }
+ [service] --> 8080 : 80
+
+ """
diff --git a/features/link_graph.feature b/features/link_graph.feature
index 38a9bfe..f536976 100644
--- a/features/link_graph.feature
+++ b/features/link_graph.feature
@@ -1,31 +1,7 @@
Feature: Link Graph
- As a DevOps
- I want to have readable, formatted docker-compose files
- so that I see errors soon
-
- Scenario: Requires Version
- Given a file named "compose.yml" with:
- """
- foo:
- image: bar
- """
- When I run `bin/compose_plantuml compose.yml`
- Then it should fail with:
- """
- docker-compose version exception: version not present
- """
-
- Scenario: Requires Version 2
- Given a file named "compose.yml" with:
- """
- version: 1
- """
- When I run `bin/compose_plantuml compose.yml`
- Then it should fail with exactly:
- """
- docker-compose version exception: need version 2, but got 1
-
- """
+ As a DevOps,
+ I want to get a link graph of my system
+ so that I know where the data flows.
Scenario: Basic Link Graph
Given a file named "compose.yml" with:
@@ -37,9 +13,10 @@ Feature: Link Graph
- second
second: {}
"""
- When I run `bin/compose_plantuml compose.yml`
+ When I run `bin/compose_plantuml --link-graph compose.yml`
Then it should pass with exactly:
"""
+ skinparam componentStyle uml2
[first]
[second]
[first] --> [second]
@@ -56,9 +33,10 @@ Feature: Link Graph
- second:second_alias
second: {}
"""
- When I run `bin/compose_plantuml compose.yml`
+ When I run `bin/compose_plantuml --link-graph compose.yml`
Then it should pass with exactly:
"""
+ skinparam componentStyle uml2
[first]
[second]
[first] --> [second]
diff --git a/features/validation.feature b/features/validation.feature
new file mode 100644
index 0000000..18c9da4
--- /dev/null
+++ b/features/validation.feature
@@ -0,0 +1,28 @@
+Feature: Validation
+ As a DevOps,
+ I want to have error messages for invalid compose input
+ so that I'm sure it works if it does not return an error.
+
+ Scenario: Requires Version
+ Given a file named "compose.yml" with:
+ """
+ foo:
+ image: bar
+ """
+ When I run `bin/compose_plantuml --link-graph compose.yml`
+ Then it should fail with:
+ """
+ docker-compose version exception: version not present
+ """
+
+ Scenario: Requires Version 2
+ Given a file named "compose.yml" with:
+ """
+ version: 1
+ """
+ When I run `bin/compose_plantuml --link-graph compose.yml`
+ Then it should fail with exactly:
+ """
+ docker-compose version exception: need version 2, but got 1
+
+ """
diff --git a/img/boundaries.svg b/img/boundaries.svg
new file mode 100644
index 0000000..ec80b31
--- /dev/null
+++ b/img/boundaries.svg
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/img/link_graph.svg b/img/link_graph.svg
index 7276b5c..337c55f 100644
--- a/img/link_graph.svg
+++ b/img/link_graph.svg
@@ -1,2 +1,2 @@
-
\ No newline at end of file
+
\ No newline at end of file