-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add port forwarding support to python-esiclient #79
Conversation
I kinda hate the number of colons in something like Will there be optional arguments for things like If there are multiple internal networks that could match the given internal IP, would you error out? I think you initially mentioned the idea of having a floating IP address automatically created for you; is that something you'd still want to do? Perhaps you could specify a network name instead of an IP, and have Neutron create the port for you? |
That's similar to the syntax we use for docker/podman port forwarding (
I think it's very common to want to create multiple port forwards for baremetal hosts (e.g., the example from the description, in which we're forwarding ssh, http, and https).
Protocol can already be specified in a fashion similar to docker/podman:
I haven't been able to figure out a good way of setting a description per port-forward; I guess you specify a single description that would be used for all of them.
It does not currently error out. That would be a relatively easy change. You can specify an explicit internal network (and subnet) using
There is code for this, but it doesn't work because it's not possible to create specific addresses. We would need to change the cli syntax to allow creating a random floating ip and using it. I had some concerns about that because we have pretty strict quotas on floating ips and I wasn't sure if that would interact badly with a command that automatically allocates floating ips. I'm not dead set against it, though. See below for some thoughts. If we assume that the most common case will be creating a set of port forwardings targeting the same external ip/internal ip pair, we could maybe do something like this instead:
Where the earlier example would become:
Or, to create a new floating ip:
The
There would obviously be no |
I'm vaguely - but honestly, only vaguely - bothered by how different this is from typical OpenStack CLI syntax, in that the OpenStack CLI loves to use argument flags to make it clear what's being passed in. I'm not a huge fan of moving entirely towards docker port forwarding syntax, because there is still (currently) the expectation that the user uses other non-ESI OpenStack CLIs, and I do think it should feel "similar". I do understand that multiple port forwardings will often be desired; what I meant to push back on is the idea that those port forwardings have to be accomplished with a single command, rather than running the command multiple times with different parameters. All that being said, I see you are compromising in your updated example; maybe we could close the gap with one more small modification?
The protocol port designation is pretty much exactly as you describe - The internal network designation could either be an IP address or a Neutron port name, or a Neutron network name; in the latter case, a Neutron port is created for you (and if it happens that a port and network - or IP address? - have the same name, then we throw an error). The external network designation would either be an existing floating IP address you've created, or simply the name of the external floating IP network; in the latter case, the floating IP is created for you (and we throw an error if you're past your quota). We allow users to pass in What do you think? |
I think it only makes sense for the internal network designation to be either an ip address or an existing port uuid/name; I don't think it makes sense to create a forward to a random internal address. My only other complaint is that by allowing either an ip address or a (port/network) name, we make option validation much more difficult (we can't reject an invalid ip address, for example, until after we contact the api to see if maybe it was a port name or id).
The thing that bothers me here is that both
...but that loses the contextual clues provided by the option names. Do you have a preference?
I think that overall it sounds like a reasonable plan. |
Yeah, that's fair. Part of me just wants it to be parallel to allowing someone to specify the external network (and have a floating IP created for you). Do you think someone would ever run this first to create a port with the appropriate port forwardings, and then attach it to a node? In the back of my mind, I was also thinking that the "network designation" logic would be generalized into a function that something like
Yep - that logic definitely becomes more difficult, but I think the alternative is a spaghetti selection of optional arguments which I think looks pretty convoluted to the end user. I think it may be better to err on the side of avoiding that.
Not a strong one - I know plenty of OpenStack CLI commands that actually require optional arguments, but I've always kind of hated that. I'm fine with either choice if the ports are part of the optional argument; that's what really made the command difficult to parse.
|
5ab7817
to
e9b8dd1
Compare
I've refactored the code in line with our conversation; the following are now all valid commands: Create
DeleteThe
PurgeThe |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
some initial comments!
84a46ae
to
ab2fbb4
Compare
There is now support for |
ab2fbb4
to
e439acd
Compare
Man, Python 3.8 is just the worst. Actually, |
de055d1
to
c4803e3
Compare
The tests are complete. I've squashed everything together. I think I've addressed all the review comments thus far. I was going to add some documentation to this pr, but |
c4803e3
to
11d8806
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Works pretty well! A few issues:
- when creating port forwardings,
--description
is actually required right now - if you don't pass in a
--port
argument, you get an unintuitive'NoneType' object is not iterable
message - the help text for
port
should maybe state that it can be specified multiple times, and give examples of allowed port formats - are you sure that an arbitrary protocol name (beyond tcp/udp) shouldn't be allowed? regardless, the error message if you specify something like "foo" isn't the clearest (
error: argument --port/-p: invalid from_spec value: '29:30/foo'
, as opposed to a message that mentions the protocol) - if you run
openstack esi port forwarding purge
with no arguments, the command "works" with no message - I feel like it may be worth checking this case and asking the user to supply at least one floating IP
Ugh, I'm calling that an API foul. Treating
Yeah, that was ugly. I will fix that.
I'll update the help text and included a few examples.
Sigh. This is
But
I'll add an error message in this case. |
I think the recent changes resolve all the issues from your last comment. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Works great! Can you squash the commits?
Add three new commands to esiclient: - openstack esi port forwarding create - openstack esi port forwarding delete - openstack esi port forwarding purge These are convenience commands that make it easier to create and delete floating ip port forwardings. Using the native openstack commands, to create a port forward from a new floating ip address to a new internal address looks something like this: ip=$(openstack floating ip create external -f value -c name) openstack port create --network mynetwork \ --fixed-ip subnet=10.10.10.0/24,ip-address=10.10.10.10 \ my-internal-port openstack floating ip port forwarding create "$ip" \ --internal-ip-address 10.10.10.10 --port my-internal-port \ --internal-protocol-port 80 --external-protocol-port 80 \ --protocol tcp Using the new esiclient commands, this becomes: openstack esi port forwarding create \ --internal-ip-network mynetwork -p 80 10.10.10.10 external
ab92354
to
b315d7e
Compare
The commits have been squashed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
This is a draft pull request, but I am looking for feedback
Add the following commands:
openstack esi port forward create
-- create one or more port forwardingsopenstack esi port forward delete
-- delete one or more port forwardingsopenstack esi port forward purge
-- remove all port forwardings associated with a floating ipCreate
The
create
anddelete
commands operate with forwarding specifications of the form<internal ip>:<internal port>:<external ip>[:<external port>][/<protocol>
. For example, to create a port forward from floating ip address 100.100.100.100 port 22 to internal address 10.10.10.10 port 22:This will:
If the external port does not match the internal port, you can add an additional component to the specification, like this:
This will create a port forwarding from 100.100.100.100 port 2222 to internal address 10.10.10.10 port 22.
You can create multiple forwardings in a single invocation:
Delete
The syntax for the
delete
command is similar:Purge
The
purge
command removes all the port forwardings associated with a given floating ip address: