This repository was archived by the owner on Dec 13, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 177
Expand file tree
/
Copy pathcompose_mode_link_helper.py
More file actions
132 lines (108 loc) · 5.11 KB
/
compose_mode_link_helper.py
File metadata and controls
132 lines (108 loc) · 5.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
import logging
logger = logging.getLogger("haproxy")
def get_compose_mode_links(docker, haproxy_container):
labels = haproxy_container.get("Config", {}).get("Labels", {})
project = labels.get("com.docker.compose.project", "")
if not project:
raise Exception("Cannot read compose labels. Are you using docker compose V2?")
networks = haproxy_container.get("NetworkSettings", {}).get("Networks", {})
compose_labels = haproxy_container.get("Config", {}).get("Labels", {})
has_slug = compose_labels.get("com.docker.compose.slug", "") != ""
linked_compose_services = _get_linked_compose_services(networks, project, has_slug)
links = _calc_links(docker, linked_compose_services, project)
return links, set(["%s_%s" % (project, service) for service in linked_compose_services])
def get_additional_links(docker, additional_services):
links = {}
services = set()
for additional_service in additional_services.split(","):
terms = additional_service.strip().split(":")
if len(terms) == 2:
project = terms[0]
service = terms[1]
link = _calc_links(docker, [service], project)
if link:
links.update(link)
services.add("%s_%s" % (project, service))
else:
logger.info("Cannot find the additional service: %s" % additional_service.strip())
return links, services
def _find_container_networks_ids(container, networks_data):
ids = []
for network in networks_data:
if container['Id'] in network['Containers'].keys():
ids.append(network['Id'])
return ids
def _calc_links(docker, linked_compose_services, project):
links = {}
for _container in docker.containers():
container_id = _container.get("Id", "")
container = docker.inspect_container(container_id)
compose_labels = container.get("Config", {}).get("Labels", {})
compose_project = compose_labels.get("com.docker.compose.project", "")
compose_service = compose_labels.get("com.docker.compose.service", "")
if compose_project == project and compose_service in linked_compose_services:
service_name = "%s_%s" % (compose_project, compose_service)
container_name = container.get("Name").lstrip("/")
container_evvvars = get_container_envvars(container)
endpoints = get_container_endpoints(container, container_name)
links[container_id] = {"service_name": service_name,
"container_envvars": container_evvvars,
"container_name": container_name,
"endpoints": endpoints,
"compose_service": compose_service,
"compose_project": compose_project}
return links
def get_container_endpoints(container, container_name):
endpoints = {}
container_endpoints = container.get("Config", {}).get("ExposedPorts", {})
for k, v in container_endpoints.iteritems():
if k:
terms = k.split("/", 1)
port = terms[0]
if len(terms) == 2:
protocol = terms[1]
else:
protocol = "tcp"
if not v:
v = "%s://%s:%s" % (protocol, container_name, port)
endpoints[k] = v
return endpoints
def get_container_envvars(container):
container_evvvars = []
envvars = container.get("Config", {}).get("Env", [])
for envvar in envvars:
terms = envvar.split("=", 1)
container_evvvar = {"key": terms[0]}
if len(terms) == 2:
container_evvvar["value"] = terms[1]
else:
container_evvvar["value"] = ""
container_evvvars.append(container_evvvar)
return container_evvvars
def _get_linked_compose_services(networks, project, has_slug):
prefix = "%s_" % project
prefix_len = len(prefix)
haproxy_links = []
for network in networks.itervalues():
network_links = network.get("Links", [])
if network_links:
haproxy_links.extend(network_links)
linked_services = []
for link in haproxy_links:
terms = link.strip().split(":")
service = terms[0].strip()
if service and service.startswith(prefix):
last = service.rfind("_")
linked_service = service[prefix_len:last]
# The default naming scheme for containers created by Compose in has changed in 1.23.0
# from <project>_<service>_<index> to <project>_<service>_<index>_<slug>,
# where <slug> is a randomly-generated hexadecimal string.
if has_slug:
linked_service = linked_service[0:linked_service.rfind("_")]
if linked_service not in linked_services:
linked_services.append(linked_service)
return linked_services
def get_service_links_str(links):
return sorted(set([link.get("service_name") for link in links.itervalues()]))
def get_container_links_str(haproxy_links):
return sorted(set([link.get("container_name") for link in haproxy_links.itervalues()]))