Skip to content
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

feat: add Unit.set_ports() for declarative port opening #1005

Merged

Conversation

tonyandrewmeyer
Copy link
Contributor

@tonyandrewmeyer tonyandrewmeyer commented Sep 20, 2023

Adjustments to port management to provide a more declarative style and some additional brevity in charm code.

  • Rename OpenPort to Port to better reflect that it's a protocol+port and the state of the port is changed by calling one of the three relevant methods. Keep OpenPort as an alias for backwards compatibility.
  • New Unit.set_ports() method that takes an arbitrary number of ports, either ints (implying 'tcp' as the protocol) or Ports, that will open any ports in the provided list that are not already open, and close any ports that are already open but are not in the provided list.
  • Unit.open_port() and Unit.close_port() default to tcp for the protocol, allowing, for example, unit.open_port(port=8000)

Fixes #989

In the majority of cases, the protocol is tcp, so make it a little easier and more concise for those cases.
This avoids the impression that the port is already/always opened, rather than just being a port and the instruction is then given via the open/close methods.
Tests still to be added.

This does do a transform to Port() objects that are then disassembled again almost immediately, for the case where ints are provided. We could normalise to a pair of (str, int) instead to avoid that. Not normalising at all ended up with a fairly messy couple of loops instead of simple set operations.
This can be flakey, because we're working with sets but then asserting that things happen in a specific order. That should get resolved.
The opened-ports call should always be first, but after that it depends on the order of items returned from set operations, and we don't care which order they happen in, so compare the sorted items.
@tonyandrewmeyer tonyandrewmeyer added the feature New feature or request label Sep 20, 2023
Copy link
Member

@jameinel jameinel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall this looks good to me. There are a couple bits about test coverage and error messaging.

I do also wonder if we are promoting Port more heavily, whether 'open_port' and 'close_port' should have a way to take them. Probably a step too far, and awkward given compatibility and parameterization.

ops/model.py Show resolved Hide resolved
ops/model.py Show resolved Hide resolved
ops/model.py Outdated Show resolved Hide resolved
test/test_model.py Outdated Show resolved Hide resolved
test/test_model.py Show resolved Hide resolved
@jameinel
Copy link
Member

BTW, great to see your first PR show up.

Add typing overloads to ensure that type checking will raise issues.

Good:
 * open_port('icmp')
 * open_port('tcp', 1)
 * open_port('udp', 2)
 * open_port(port=3)

Bad:
 * open_port()
 * open_port('icmp', 1)
 * open_port('tcp')
 * open_port('udp')
 * open_port(4, 'tcp')

Also check that nothing bad has been done at runtime, raising an error (ModelError to be consistent with ops.testing) if one of the invalid specifications is used.
@tonyandrewmeyer
Copy link
Contributor Author

tonyandrewmeyer commented Sep 20, 2023

BTW, great to see your first PR show up.

Technically, 4th 😉 but first one in operator with code, yes 🎉, thanks! Feels great to be moving on from onboarding towards providing value 😄

ops/model.py Outdated Show resolved Hide resolved
ops/model.py Outdated Show resolved Hide resolved
ops/model.py Outdated Show resolved Hide resolved
ops/model.py Outdated Show resolved Hide resolved
ops/__init__.py Show resolved Hide resolved
Also some minor adjustments per code review comments.
In other repos, there's code like this:

Unfortunately, pyright cannot tell that the protocol argument is always 'tcp' in this case, only that the protocol is one of tcp/udp/icmp, and that's too broad to fit the righter overloaded specs, so it complains. This could be handled with changes in the upstream places, but I don't see any simple way to handle it within ops itself.

This was a minor improvement and not really needed, plus it's in the two methods that we're wanting to move people away from, so drop this change.
@tonyandrewmeyer
Copy link
Contributor Author

Note: will wait for #918 to be merged before moving this out of draft, so that I can get in the open/close port doc changes and align them with set_port.

@benhoyt
Copy link
Collaborator

benhoyt commented Sep 21, 2023

I've just merged the #1006 open/close_port docs tweak.

@tonyandrewmeyer tonyandrewmeyer marked this pull request as ready for review September 21, 2023 22:45
Copy link
Collaborator

@benhoyt benhoyt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good. Just one more change requested: let's drop the redundant checks in open_port -- or discuss if my reasoning doesn't make sense.

ops/model.py Outdated Show resolved Hide resolved
1 Outdated Show resolved Hide resolved
test/test_model.py Outdated Show resolved Hide resolved
test/test_model.py Show resolved Hide resolved
Copy link
Collaborator

@benhoyt benhoyt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, approved!

@benhoyt benhoyt changed the title feat: wholesale port management feat: add Unit.set_ports() for declarative port opening Sep 22, 2023
test/test_model.py Show resolved Hide resolved
test/test_model.py Show resolved Hide resolved
ops/model.py Outdated Show resolved Hide resolved
@tonyandrewmeyer tonyandrewmeyer merged commit 76a5f15 into canonical:main Sep 25, 2023
17 checks passed
@tonyandrewmeyer tonyandrewmeyer deleted the wholesale-port-management-989 branch September 25, 2023 23:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add method for "wholesale" port management
4 participants