libvirt-hook-qemu
libvirt-hook-qemu copied to clipboard
Implement multi IP domain handling
This PR implements a feature designed to allow domains to have several private ip addresses each with a different set of forward rules on the same hook.
Ok. These changes address two things:
- Allow one to define multiple domins for one vir_domain in order to handle a single VM with multiple assigned ip addresses each with their own set of port forwards
- Fix a bug where the chain names got too long for iptables to accept them (by shortening them)
These changes are tested on our hypervisors running a recent debian version and libvirt 6.9.0. They're already running on out production machines and didn't produce any issues..
Ok. These changes address two things:
- Allow one to define multiple domins for one vir_domain in order to handle a single VM with multiple assigned ip addresses each with their own set of port forwards
- Fix a bug where the chain names got too long for iptables to accept them (by shortening them)
These changes are tested on our hypervisors running a recent debian version and libvirt 6.9.0. They're already running on out production machines and didn't produce any issues..
Do you have an example of how the new JSON structure looks with your PR? I'm looking to achieve exactly what you have added support for here...
I'd be fine but would be good if @nover could confirm.
Do you have an example of how the new JSON structure looks with your PR? I'm looking to achieve exactly what you have added support for here...
Sure.
{
// This is copied and censored from a live system in order to demonstrate the ussage
// Due to me deleting a bunch of entries there might be a missing } but it should demonstrate the schema
"a-single-ip-vm": {
"private_ip": "192.168.122.13",
"port_map": {
"tcp": [[2222, 22]]
}
},
"a-vm-with-multiple-ip-addresses": [{
"private_ip": "192.168.122.12",
"port_map": {
"tcp": [[80, 80],
[443, 443]]
}
}, {
"private_ip": "192.168.122.14",
"port_map": {
"tcp": [[2223, 22]]
}
}],
"another-single-ip-vm": {
"private_ip": "192.168.122.38",
"port_map": {
"tcp": [[2224, 22]]
}
}
}
EDIT / Note: For clarification: The only difference is that one might specify a list of mapping objects instead of a single one for a VM.
I'm currently testing out this branch, however I'm having trouble with my cloud provider and private vlans at the moment - so I can only test the new array syntax with a single object config block for the publicly available ports.
Libvirt / kvm craps out immediately when trying to boot a domain that is configured:
error: Hook script execution failed: internal error: Child process (LC_ALL=C PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin /etc/libvirt/hooks/qemu ovh-kuji-testnet-01 prepare begin -) unexpected exit status 1: Traceback (most recent call last):
File "/etc/libvirt/hooks/qemu", line 269, in <module>
domain = config().get(vir_domain)
File "/etc/libvirt/hooks/qemu", line 138, in config
jsonschema.validate(config._conf,
File "/usr/lib/python3/dist-packages/jsonschema/validators.py", line 934, in validate
raise error
jsonschema.exceptions.ValidationError: [{'private_ip': '192.168.122.21', 'public_ip': '<redacted>, 'port_map': {'tcp': [[30222, 22]]}}] is not of type 'object'
Failed validating 'type' in schema['patternProperties']['^[A-Za-z_\\-]']:
{'additionalProperties': False,
So it would seem like the JSON schema needs some patching?
My configuration looks like this;
{
"my-server": [{
"private_ip": "192.168.122.21",
"public_ip": "<redacted>",
"port_map": {
"tcp": [
[30222, 22] // direct SSH to the node
]
}
}]
}
Latest commit on my checkout is:
commit 6d539791830473b8e7ddaed97125cd91b3a7c946 (HEAD -> master, origin/master, origin/HEAD)
Author: Doralitze <[email protected]>
Date: Thu Jan 14 15:12:02 2021 +0100
chg: clean up debug statements
So it would seem like the JSON schema needs some patching?
Definitely. I didn't change it back then because it wasn't reliable back then and I don't need that feature anyway. I run the script with the corresponding option disabled. If your're a bit patient I'll write a patch in the next couple of hours and will come back to you. But I need to figure JSON schemes out first.
Edit: I think i simply forgot to change the scheme as I never had that feature enabled.
That totally makes sense! I managed to patch it locally so that it's always expecting the [] format, but that's a pretty breaking changes for all existing configs.
My new schema looks like this: https://gist.github.com/nover/59c8078d19ee8d1da47bc0c2074492cd
How would I go about disabling the schema validation?
How would I go about disabling the schema validation?
def config(validate=True): needs to be called with validate=False at the end of the script.
As an alternative one might make sure that the python module jsonschema is not installed or not in the python path.
OK, The commit c5986a9 should have done the trick.
@nover Would you be so kind to test that change, since you seam to have schema support enabled?
OK, The commit c5986a9 should have done the trick.
@nover Would you be so kind to test that change, since you seam to have schema support enabled?
Awesome stuff - pulled your changes, and:
- [x] Schema validation works
- [x] Ports are mapped
- [x] Need to test that mapping works with multiple public IPs
I can now confirm that it works as intended with multiple "public IPs" - even while reusing the same port numbers 🎉
By the way - it would probably be a good idea to update the installed template with an example of multi public ip, as well as the Readme?
By the way - it would probably be a good idea to update the installed template with an example of multi public ip, as well as the Readme?
That wouldn't be the worst thing to do. I'll see what I can do.
Sorry for taking a while. @nover @Doralitze I don't see anything blocking the merge. Any last calls?
Sorry for taking a while. @nover @Doralitze I don't see anything blocking the merge. Any last calls?
All working smoothly on my machines so far! :)