Skip to content

Commit 02c3755

Browse files
committed
added --port_boundaries and --volume_boundaries
1 parent a7c8cc9 commit 02c3755

File tree

4 files changed

+128
-55
lines changed

4 files changed

+128
-55
lines changed

bin/compose_plantuml

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,30 @@ if __name__ == '__main__':
1717
default=False,
1818
)
1919
parser.add_argument(
20-
'--group', action='store_const', const=True,
21-
help='group similar properties together',
20+
'--port_boundaries', action='store_const', const=True,
21+
help='prints the port system boundaries',
22+
default=False,
23+
)
24+
parser.add_argument(
25+
'--volume_boundaries', action='store_const', const=True,
26+
help='prints the port system boundaries',
2227
default=False,
2328
)
2429
parser.add_argument(
2530
'--notes', action='store_const', const=True,
2631
help='utilize notes for displaying additional information',
2732
default=False,
2833
)
34+
parser.add_argument(
35+
'--group', action='store_const', const=True,
36+
help='group similar properties together',
37+
default=False,
38+
)
2939
parser.add_argument('files', nargs=argparse.REMAINDER)
3040
args = parser.parse_args()
3141
plantuml = ComposePlantuml()
3242

33-
if not args.link_graph and not args.boundaries:
43+
if not args.link_graph and not args.boundaries and not args.port_boundaries and not args.volume_boundaries:
3444
print('specify an output option. link_graph or boundaries')
3545
sys.exit(1)
3646

@@ -40,7 +50,11 @@ if __name__ == '__main__':
4050
if args.link_graph:
4151
print(plantuml.link_graph(parsed, notes=args.notes))
4252
if args.boundaries:
43-
print(plantuml.boundaries(parsed, group=args.group, notes=args.notes))
53+
print(plantuml.boundaries(parsed, args.group, notes=args.notes))
54+
if args.port_boundaries:
55+
print(plantuml.boundaries(parsed, args.group, notes=args.notes, ports=True, volumes=False))
56+
if args.volume_boundaries:
57+
print(plantuml.boundaries(parsed, args.group, notes=args.notes, ports=False, volumes=True))
4458

4559
if len(args.files) == 0:
4660
execute(sys.stdin.read())

compose_plantuml/__init__.py

Lines changed: 53 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -29,58 +29,66 @@ def link_graph(self, compose, notes=False):
2929
result += 'note top of [{0}]\n {1}\nend note\n'.format(component_name, '\n '.join(labels))
3030
return result.strip()
3131

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

3535
result += 'cloud system {\n'
3636
for component in sorted(self.components(compose)):
37-
if self.has_service_external_ports(compose, component) or self.has_service_volumes(compose, component):
38-
result += ' [{0}]\n'.format(component)
39-
result += '}\n'
40-
volume_registry = {}
41-
42-
volume_uml = ''
43-
for volume in sorted(self.volumes(compose)):
44-
if not self.is_volume_used(compose, volume):
37+
relevant = False
38+
if ports and self.has_service_external_ports(compose, component):
39+
relevant = True
40+
if volumes and self.has_service_volumes(compose, component):
41+
relevant = True
42+
if not relevant:
4543
continue
46-
volume_uml += 'database {0}'.format(volume) + ' {\n'
47-
for path in sorted(self.volume_usage(compose, volume)):
48-
id = self.volume_identifier(volume, path)
49-
50-
if id in volume_registry:
51-
continue
52-
volume_registry[id] = 'volume_{0}'.format(len(volume_registry.keys()) + 1)
53-
volume_uml += ' [{0}] as {1}\n'.format(path, volume_registry[id])
54-
55-
volume_uml += '}\n'
56-
result += self.group('volumes', volume_uml) if group else volume_uml
57-
58-
port_uml = ''
59-
port_links = ''
60-
for service, host, container in sorted(self.ports(compose)):
61-
port = host if container is None else '{0} : {1}'.format(host, container)
62-
port_links += '[{0}] --> {1}\n'.format(service, port)
63-
port_uml += 'interface {0}\n'.format(host)
64-
result += self.group('ports', port_uml) if group else ''
65-
result += port_links
66-
67-
for volume in sorted(self.volumes(compose)):
68-
for service, volume_path in sorted(self.service_using_path(compose, volume)):
69-
name = volume_path
70-
if '{0}.{1}'.format(volume, volume_path) in volume_registry:
71-
name = volume_registry['{0}.{1}'.format(volume, volume_path)]
72-
result += '[{0}] --> {1}\n'.format(service, name)
44+
result += ' [{0}]\n'.format(component)
45+
if not notes:
46+
continue
47+
if not self.labels(compose, component):
48+
continue
49+
labels = []
50+
for key, value in self.labels(compose, component).items():
51+
labels.append('{0}={1}'.format(key, value))
52+
result += ' note top of [{0}]\n {1}\n end note\n'.format(component, '\n '.join(labels))
53+
result += '}\n'
54+
if volumes:
55+
volume_registry = {}
7356

74-
if notes:
75-
for component_name in sorted(self.components(compose)):
76-
if not (self.has_service_external_ports(compose, component_name) or self.has_service_volumes(compose, component_name)):
77-
continue
78-
if not self.labels(compose, component_name):
57+
volume_uml = ''
58+
for volume in sorted(self.volumes(compose)):
59+
if not self.is_volume_used(compose, volume):
7960
continue
80-
labels = []
81-
for key, value in self.labels(compose, component_name).items():
82-
labels.append('{0}={1}'.format(key, value))
83-
result += 'note top of [{0}]\n {1}\nend note\n'.format(component_name, '\n '.join(labels))
61+
volume_uml += 'database {0}'.format(volume) + ' {\n'
62+
for path in sorted(self.volume_usage(compose, volume)):
63+
id = self.volume_identifier(volume, path)
64+
65+
if id in volume_registry:
66+
continue
67+
volume_registry[id] = 'volume_{0}'.format(len(volume_registry.keys()) + 1)
68+
volume_uml += ' [{0}] as {1}\n'.format(path, volume_registry[id])
69+
70+
volume_uml += '}\n'
71+
result += self.group('volumes', volume_uml) if group else volume_uml
72+
73+
if ports:
74+
port_uml = ''
75+
port_links = ''
76+
for service, host, container in sorted(self.ports(compose)):
77+
port = host
78+
if container is not None:
79+
port = '{0} : {1}'.format(host, container)
80+
port_links += '[{0}] --> {1}\n'.format(service, port)
81+
port_uml += 'interface {0}\n'.format(port)
82+
result += self.group('ports', port_uml) if group else ''
83+
result += port_links
84+
85+
if volumes:
86+
for volume in sorted(self.volumes(compose)):
87+
for service, volume_path in sorted(self.service_using_path(compose, volume)):
88+
name = volume_path
89+
if '{0}.{1}'.format(volume, volume_path) in volume_registry:
90+
name = volume_registry['{0}.{1}'.format(volume, volume_path)]
91+
result += '[{0}] --> {1}\n'.format(service, name)
8492

8593
return result.strip()
8694

features/boundaries.feature

Lines changed: 56 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ Feature: Boundaries
104104
volumes:
105105
- service_log:/log
106106
ports:
107-
- 8080:80
107+
- 8080
108108
unused_service: {}
109109
volumes:
110110
service_log: {}
@@ -125,7 +125,7 @@ Feature: Boundaries
125125
package ports {
126126
interface 8080
127127
}
128-
[service] --> 8080 : 80
128+
[service] --> 8080
129129
[service] --> volume_1
130130
131131
"""
@@ -149,14 +149,65 @@ Feature: Boundaries
149149
skinparam componentStyle uml2
150150
cloud system {
151151
[service]
152+
note top of [service]
153+
key=value
154+
end note
152155
}
153156
database service_log {
154157
[/log] as volume_1
155158
}
156159
[service] --> volume_1
157-
note top of [service]
158-
key=value
159-
end note
160+
"""
161+
162+
Scenario: Ports only
163+
Given a file named "compose.yml" with:
164+
"""
165+
version: "2"
166+
services:
167+
service:
168+
volumes:
169+
- service_log:/log
170+
ports:
171+
- 8080
172+
volumes:
173+
service_log: {}
174+
"""
175+
When I run `bin/compose_plantuml --port_boundaries compose.yml`
176+
Then it should pass with exactly:
177+
"""
178+
skinparam componentStyle uml2
179+
cloud system {
180+
[service]
181+
}
182+
[service] --> 8080
183+
184+
"""
185+
186+
Scenario: Volumes only
187+
Given a file named "compose.yml" with:
188+
"""
189+
version: "2"
190+
services:
191+
service:
192+
volumes:
193+
- service_log:/log
194+
ports:
195+
- 8080
196+
volumes:
197+
service_log: {}
198+
"""
199+
When I run `bin/compose_plantuml --volume_boundaries compose.yml`
200+
Then it should pass with exactly:
201+
"""
202+
skinparam componentStyle uml2
203+
cloud system {
204+
[service]
205+
}
206+
database service_log {
207+
[/log] as volume_1
208+
}
209+
[service] --> volume_1
210+
160211
"""
161212

162213
Scenario: Suppport for legacy docker-compose format

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ def readme():
77

88
setup(
99
name='compose_plantuml',
10-
version='0.0.11',
10+
version='0.0.12',
1111
description='converts docker-compose into plantuml',
1212
long_description=readme(),
1313
url='http://github.com/funkwerk/compose_plantuml',

0 commit comments

Comments
 (0)