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
151 lines (124 loc) · 5.72 KB
/
compose_mode_link_helper.py
File metadata and controls
151 lines (124 loc) · 5.72 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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
import logging
from haproxy.config import LINKED_SERVICES
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", {})
linked_compose_services = _get_linked_compose_services(networks, project)
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", "")
linked_service_names = {}
for x in str(LINKED_SERVICES).strip().split(";"):
if not x.strip():
break
service_values = x.strip().split(":")
service_name = "%s" % service_values[0]
if len(service_values) == 2:
linked_service_names[service_name] = {y: {} for y in service_values[1].strip().split(",") if y}
else:
linked_service_names[service_name] = {}
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)
explicit_endpoints = linked_service_names.get(compose_service, {})
endpoints = get_container_endpoints(container, container_name, explicit_endpoints)
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, explicit_endpoints):
endpoints = {}
if not explicit_endpoints:
explicit_endpoints = container.get("Config", {}).get("ExposedPorts", {})
for k, v in explicit_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):
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_service_names = []
if LINKED_SERVICES:
for x in str(LINKED_SERVICES).strip().split(";"):
if not x.strip():
break
service_values = x.strip().split(":")
if service_values:
linked_service_names.append("%s" % (service_values[0]))
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]
if linked_service_names and linked_service not in linked_service_names:
continue
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()]))