Skip to content

Instantly share code, notes, and snippets.

@nh2
Created October 29, 2018 21:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nh2/7707e0069df1d4bebc6572c40c85b673 to your computer and use it in GitHub Desktop.
Save nh2/7707e0069df1d4bebc6572c40c85b673 to your computer and use it in GitHub Desktop.
NixOps migration script for https://github.com/NixOS/nixops/pull/1032
#!/usr/bin/env python3
import argparse
import copy
import json
import sys
def migrate(input_dict):
j = copy.deepcopy(input_dict)
net = j['networking']
defgw_ip_str = net['defaultGateway']
iface = list(net['interfaces'])[0]
ipv4 = net['interfaces'][iface]['ipAddress']
prefixLength_v4 = net['interfaces'][iface]['prefixLength']
# Expected syntax:
# ip -6 addr add '2a01:4f8:192:5292::/64' dev 'eth0' || true
# ^ field index 4
ipv6_lines = [l for l in net['localCommands'].strip().split('\n') if l.startswith('ip -6')]
ipv6_with_slash = ipv6_lines[0].split(' ')[4].strip("'")
ipv6, prefixLength_v6_str = ipv6_with_slash.split('/')
prefixLength_v6 = int(prefixLength_v6_str)
# Delete localCommands
del net['localCommands']
# Add v4 gateway with interface device
net['defaultGateway'] = {
'interface': iface,
'address': defgw_ip_str,
}
# Add v6 gateway with interface device
net['defaultGateway6'] = {
'interface': iface,
'address': 'fe80::1',
}
# Move addresses to new interfaces.<iface>.ipv*.addresses = [{address, prefixLength}] style
net['interfaces'][iface] = {
"ipv4": {
"addresses": [
{
"address": ipv4,
"prefixLength": prefixLength_v4,
}
]
},
"ipv6": {
"addresses": [
{
"address": ipv6,
"prefixLength": prefixLength_v6,
}
]
},
}
return j
# Example network spec in JSON format
example_json = '''
{
"services": {
"udev": {
"extraRules": "ACTION==\\"add\\", SUBSYSTEM==\\"net\\", ATTR{address}==\\"00:1a:2b:3c:4d:5e\\", NAME=\\"eth0\\"\\n"
}
},
"networking": {
"nameservers": [
"213.133.98.98",
"213.133.99.99",
"213.133.100.100",
"2a01:4f8:0:a0a1::add:1010",
"2a01:4f8:0:a102::add:9999",
"2a01:4f8:0:a111::add:9898"
],
"interfaces": {
"eth0": {
"prefixLength": 27,
"ipAddress": "1.2.3.190"
}
},
"defaultGateway": "1.2.3.161",
"localCommands": "ip -6 addr add '2a01:4f8:123:4567::/64' dev 'eth0' || true\\nip -4 route change '1.2.3.160/27' via '1.2.3.161' dev 'eth0' || true\\nip -6 route add default via 'fe80::1' dev eth0 || true\\n"
}
}
'''
def main():
parser = argparse.ArgumentParser(description='Transform NixOps Hetzner network spec JSON from NixOS 17.09 ipAddress format to new NixOS 18.03 format')
parser.add_argument('--file', metavar='FILE', help='JSON file to process')
args = parser.parse_args()
if args.file is None:
j = json.loads(example_json)
print('Example file output:')
else:
with open(args.file) as f:
j = json.load(f)
migrated_json = migrate(j)
print(json.dumps(migrated_json, indent=2))
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment