Skip to content

Commit

Permalink
added --port_boundaries and --volume_boundaries
Browse files Browse the repository at this point in the history
  • Loading branch information
lindt committed Mar 30, 2016
1 parent a7c8cc9 commit 02c3755
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 55 deletions.
22 changes: 18 additions & 4 deletions bin/compose_plantuml
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,30 @@ if __name__ == '__main__':
default=False,
)
parser.add_argument(
'--group', action='store_const', const=True,
help='group similar properties together',
'--port_boundaries', action='store_const', const=True,
help='prints the port system boundaries',
default=False,
)
parser.add_argument(
'--volume_boundaries', action='store_const', const=True,
help='prints the port system boundaries',
default=False,
)
parser.add_argument(
'--notes', action='store_const', const=True,
help='utilize notes for displaying additional information',
default=False,
)
parser.add_argument(
'--group', action='store_const', const=True,
help='group similar properties together',
default=False,
)
parser.add_argument('files', nargs=argparse.REMAINDER)
args = parser.parse_args()
plantuml = ComposePlantuml()

if not args.link_graph and not args.boundaries:
if not args.link_graph and not args.boundaries and not args.port_boundaries and not args.volume_boundaries:
print('specify an output option. link_graph or boundaries')
sys.exit(1)

Expand All @@ -40,7 +50,11 @@ if __name__ == '__main__':
if args.link_graph:
print(plantuml.link_graph(parsed, notes=args.notes))
if args.boundaries:
print(plantuml.boundaries(parsed, group=args.group, notes=args.notes))
print(plantuml.boundaries(parsed, args.group, notes=args.notes))
if args.port_boundaries:
print(plantuml.boundaries(parsed, args.group, notes=args.notes, ports=True, volumes=False))
if args.volume_boundaries:
print(plantuml.boundaries(parsed, args.group, notes=args.notes, ports=False, volumes=True))

if len(args.files) == 0:
execute(sys.stdin.read())
Expand Down
98 changes: 53 additions & 45 deletions compose_plantuml/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,58 +29,66 @@ def link_graph(self, compose, notes=False):
result += 'note top of [{0}]\n {1}\nend note\n'.format(component_name, '\n '.join(labels))
return result.strip()

def boundaries(self, compose, group=False, notes=False):
def boundaries(self, compose, group=False, ports=True, volumes=True, notes=False):
result = 'skinparam componentStyle uml2\n'

result += 'cloud system {\n'
for component in sorted(self.components(compose)):
if self.has_service_external_ports(compose, component) or self.has_service_volumes(compose, component):
result += ' [{0}]\n'.format(component)
result += '}\n'
volume_registry = {}

volume_uml = ''
for volume in sorted(self.volumes(compose)):
if not self.is_volume_used(compose, volume):
relevant = False
if ports and self.has_service_external_ports(compose, component):
relevant = True
if volumes and self.has_service_volumes(compose, component):
relevant = True
if not relevant:
continue
volume_uml += 'database {0}'.format(volume) + ' {\n'
for path in sorted(self.volume_usage(compose, volume)):
id = self.volume_identifier(volume, path)

if id in volume_registry:
continue
volume_registry[id] = 'volume_{0}'.format(len(volume_registry.keys()) + 1)
volume_uml += ' [{0}] as {1}\n'.format(path, volume_registry[id])

volume_uml += '}\n'
result += self.group('volumes', volume_uml) if group else volume_uml

port_uml = ''
port_links = ''
for service, host, container in sorted(self.ports(compose)):
port = host if container is None else '{0} : {1}'.format(host, container)
port_links += '[{0}] --> {1}\n'.format(service, port)
port_uml += 'interface {0}\n'.format(host)
result += self.group('ports', port_uml) if group else ''
result += port_links

for volume in sorted(self.volumes(compose)):
for service, volume_path in sorted(self.service_using_path(compose, volume)):
name = volume_path
if '{0}.{1}'.format(volume, volume_path) in volume_registry:
name = volume_registry['{0}.{1}'.format(volume, volume_path)]
result += '[{0}] --> {1}\n'.format(service, name)
result += ' [{0}]\n'.format(component)
if not notes:
continue
if not self.labels(compose, component):
continue
labels = []
for key, value in self.labels(compose, component).items():
labels.append('{0}={1}'.format(key, value))
result += ' note top of [{0}]\n {1}\n end note\n'.format(component, '\n '.join(labels))
result += '}\n'
if volumes:
volume_registry = {}

if notes:
for component_name in sorted(self.components(compose)):
if not (self.has_service_external_ports(compose, component_name) or self.has_service_volumes(compose, component_name)):
continue
if not self.labels(compose, component_name):
volume_uml = ''
for volume in sorted(self.volumes(compose)):
if not self.is_volume_used(compose, volume):
continue
labels = []
for key, value in self.labels(compose, component_name).items():
labels.append('{0}={1}'.format(key, value))
result += 'note top of [{0}]\n {1}\nend note\n'.format(component_name, '\n '.join(labels))
volume_uml += 'database {0}'.format(volume) + ' {\n'
for path in sorted(self.volume_usage(compose, volume)):
id = self.volume_identifier(volume, path)

if id in volume_registry:
continue
volume_registry[id] = 'volume_{0}'.format(len(volume_registry.keys()) + 1)
volume_uml += ' [{0}] as {1}\n'.format(path, volume_registry[id])

volume_uml += '}\n'
result += self.group('volumes', volume_uml) if group else volume_uml

if ports:
port_uml = ''
port_links = ''
for service, host, container in sorted(self.ports(compose)):
port = host
if container is not None:
port = '{0} : {1}'.format(host, container)
port_links += '[{0}] --> {1}\n'.format(service, port)
port_uml += 'interface {0}\n'.format(port)
result += self.group('ports', port_uml) if group else ''
result += port_links

if volumes:
for volume in sorted(self.volumes(compose)):
for service, volume_path in sorted(self.service_using_path(compose, volume)):
name = volume_path
if '{0}.{1}'.format(volume, volume_path) in volume_registry:
name = volume_registry['{0}.{1}'.format(volume, volume_path)]
result += '[{0}] --> {1}\n'.format(service, name)

return result.strip()

Expand Down
61 changes: 56 additions & 5 deletions features/boundaries.feature
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ Feature: Boundaries
volumes:
- service_log:/log
ports:
- 8080:80
- 8080
unused_service: {}
volumes:
service_log: {}
Expand All @@ -125,7 +125,7 @@ Feature: Boundaries
package ports {
interface 8080
}
[service] --> 8080 : 80
[service] --> 8080
[service] --> volume_1
"""
Expand All @@ -149,14 +149,65 @@ Feature: Boundaries
skinparam componentStyle uml2
cloud system {
[service]
note top of [service]
key=value
end note
}
database service_log {
[/log] as volume_1
}
[service] --> volume_1
note top of [service]
key=value
end note
"""

Scenario: Ports only
Given a file named "compose.yml" with:
"""
version: "2"
services:
service:
volumes:
- service_log:/log
ports:
- 8080
volumes:
service_log: {}
"""
When I run `bin/compose_plantuml --port_boundaries compose.yml`
Then it should pass with exactly:
"""
skinparam componentStyle uml2
cloud system {
[service]
}
[service] --> 8080
"""

Scenario: Volumes only
Given a file named "compose.yml" with:
"""
version: "2"
services:
service:
volumes:
- service_log:/log
ports:
- 8080
volumes:
service_log: {}
"""
When I run `bin/compose_plantuml --volume_boundaries compose.yml`
Then it should pass with exactly:
"""
skinparam componentStyle uml2
cloud system {
[service]
}
database service_log {
[/log] as volume_1
}
[service] --> volume_1
"""

Scenario: Suppport for legacy docker-compose format
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ def readme():

setup(
name='compose_plantuml',
version='0.0.11',
version='0.0.12',
description='converts docker-compose into plantuml',
long_description=readme(),
url='http://github.com/funkwerk/compose_plantuml',
Expand Down

0 comments on commit 02c3755

Please sign in to comment.