Created
January 9, 2018 21:23
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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