Skip to content

Instantly share code, notes, and snippets.

@jason-kane
Created January 9, 2018 21:23
Show Gist options
  • Save jason-kane/08f2b56eff8b87129ab9763b0841d50a to your computer and use it in GitHub Desktop.
Save jason-kane/08f2b56eff8b87129ab9763b0841d50a to your computer and use it in GitHub Desktop.
gross hackage to find an available subnet for docker-compose and smash it into the yaml
#!/usr/bin/env python3
import yaml
import docopt
import sh
import json
BLACKLIST = [24, 25, 26]
SKIP = ["host", "none"]
class UnsupportedComposeFormat(Exception):
"""Only v2 and v3 docker-compose yaml formats allow us to change the subnetwork"""
class NoNetworksAvailable(Exception):
"""We ran out of potential networks"""
def docker_find_pool():
"""Find an available subnet for this docker-compose networking fubar."""
taken = set()
networks = sh.docker.network.list()
for network in networks.split("\n")[1:-1]:
network_id, name, driver, scope = network.split()
if name in SKIP:
continue
network_config = sh.docker.network.inspect("-f", "{{json .IPAM.Config}}", name).stdout
print(name, network_config)
parsed = json.loads(network_config.decode("UTF-8"))
if len(parsed) > 0:
taken.add(int(parsed[0]['Subnet'].split('.')[1]))
# else:
# print("Skipping %s" % parsed)
for net in range(17, 255):
if net in BLACKLIST or net in taken:
continue
else:
return "172.%i.0.0/16" % net
raise NoNetworksAvailable
def docker_compose_fixnet():
"""
Cleanup docker compose networking to avoid internal 172.x networks.
Usage:
docker-compose-fixnet [DOCKER-COMPOSE-FILE]
Options:
DOCKER-COMPOSE-FILE Defaults to docker-compose.yml
"""
args = docopt.docopt(docker_compose_fixnet.__doc__)
compose_fn = args.get("DOCKER-COMPOSE-FILE")
if compose_fn is None:
compose_fn = "docker-compose.yml"
with open(compose_fn, 'r') as h:
compose_file = yaml.load(h)
new_subnet = docker_find_pool()
print("Allocating %s" % new_subnet)
# v1 or v2?
if compose_file.get('version', "1") == "1":
raise UnsupportedComposeFormat(
"Only docker-compose.yml v2 and v3 are supported"
)
elif compose_file.get('version') == "2":
compose_file["networks"] = {
"default": {
"driver": "default",
"ipam": {
"driver": "default",
"config": {
"subnet": new_subnet
}
}
}
}
elif compose_file.get('version') == "3":
compose_file["networks"] = {
"default": {
"driver": "default",
"ipam": {
"driver": "default",
"config": {
"subnet": new_subnet
}
}
}
}
with open(compose_fn, 'w') as h:
yaml.dump(compose_file, h, default_flow_style=False)
docker_compose_fixnet()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment