libvirt-hook-qemu icon indicating copy to clipboard operation
libvirt-hook-qemu copied to clipboard

Implement multi IP domain handling

Open Doralitze opened this issue 4 years ago • 10 comments
trafficstars

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.

Doralitze avatar Jan 14 '21 12:01 Doralitze

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..

Doralitze avatar Jan 14 '21 14:01 Doralitze

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...

nover avatar Oct 11 '22 11:10 nover

I'd be fine but would be good if @nover could confirm.

saschpe avatar Oct 11 '22 12:10 saschpe

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.

Doralitze avatar Oct 11 '22 12:10 Doralitze

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

nover avatar Oct 12 '22 10:10 nover

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.

Doralitze avatar Oct 12 '22 10:10 Doralitze

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?

nover avatar Oct 12 '22 11:10 nover

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.

Doralitze avatar Oct 12 '22 11:10 Doralitze

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?

Doralitze avatar Oct 12 '22 11:10 Doralitze

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

nover avatar Oct 12 '22 11:10 nover

I can now confirm that it works as intended with multiple "public IPs" - even while reusing the same port numbers 🎉

nover avatar Nov 05 '22 19:11 nover

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?

nover avatar Nov 06 '22 18:11 nover

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.

Doralitze avatar Nov 10 '22 13:11 Doralitze

Sorry for taking a while. @nover @Doralitze I don't see anything blocking the merge. Any last calls?

saschpe avatar Apr 14 '23 11:04 saschpe

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! :)

nover avatar Apr 14 '23 11:04 nover