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
Support for open-port, close-port, and opened-ports #905
Conversation
No tests yet, and some TODOs left
Looking tidy so far! 😎 |
Order is not significant, and this will make it easier for folks to test set difference.
@@ -2998,6 +3042,44 @@ def secret_remove(self, id: str, *, revision: Optional[int] = None): | |||
args.extend(['--revision', str(revision)]) | |||
self._run_for_secret('secret-remove', *args) | |||
|
|||
def open_port(self, protocol: str, port: Optional[int] = None): | |||
arg = f'{port}/{protocol}' if port is not None else protocol |
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.
I'm pretty sure port is only optional if protocol is 'icmp' in which case it can't have a port.
I don't know if there is a clearer way to define this.
This is validated by your logic in "_parse_opened_port" that does have 'icmp' and others hard coded for that behavior (must have a port if tcp or udp, must not have a port for icmp)
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.
This is noted in the docstring of open-port and (updated docstring for) close-port. It is checked by Juju's open-port and close-port hooks tools and will return an error there. In the Harness I test it up-front (in _check_protocol_and_port
), so if folks get this wrong it'll be raised as an error immediately when the unit tests are run.
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.
I think this gives a nice documented way to interact, and conforms to the agreed protocol.
Going to merge without a second approval: spec's been approved by Gustavo, John's taken a close look at the PR and approved, and Jon and others have cast their eyes over it too -- I think we're good. |
Happy to see this land, thanks Ben! |
#15246 When calling `opened-ports` the resulting set did not include the pending open/close requests, this PR adds these pending requests to the result. For this, I moved the "merge" logic functions from `state` to `core/network`, this way we can call them both from state and from the uniter `context`, thus having the pending open/close requests available and mergeable with the already opened ports. ## Checklist *If an item is not applicable, use `~strikethrough~`.* - [X] Code style: imports ordered, good names, simple structure, etc - [X] Comments saying why design decisions were made - [X] Go unit tests, with comments saying what you're testing - [ ] ~[Integration tests](https://github.com/juju/juju/tree/develop/tests), with comments saying what you're testing~ - [ ] ~[doc.go](https://discourse.charmhub.io/t/readme-in-packages/451) added or updated in changed packages~ ## QA steps To correctly QA this, I had to deploy a charm that made use of `open_port()` and then `opened_ports()`, but this was merged canonical/operator#905 recently, so the charm has to be packed, then unzip it, then replace the `/venv/ops` folder with the source `ops/` folder from https://github.com/canonical/operator and then zipped again. After that, we can deploy the charm. Here is a minimal content for `src/charm.py` (taken from https://juju.is/docs/sdk/build-and-deploy-minimal-machine-charm): ```python ... def _on_install(self, event): """ install is the first core hook to fire when deploying. """ logger.info("Step 1/3: INSTALL") self.unit.status = MaintenanceStatus("Step: 1/3") logger.info("Step 1/3: Opening tcp 5432") self.unit.open_port("tcp", 5432) opened = self.unit.opened_ports() logger.info("Step 1/3: opened ports: " + repr(opened)) ... ``` then : ```sh charmcraft pack unzip mini_ubuntu-22.04-amd64.charm -d mini rm -rf mini/venv/ops cp -r ~/workspace/canonical/operator/ops mini/venv zip -r mini_ubuntu-22.04-amd64.charm mini/* juju deploy ./mini_ubuntu-22.04-amd64.charm ``` Before this patch (develop), the logs would show: ``` unit-mini-0: 13:52:16 INFO unit.mini/0.juju-log Step 1/3: INSTALL unit-mini-0: 13:52:16 INFO unit.mini/0.juju-log Step 1/3: Opening tcp 5432 unit-mini-0: 13:52:16 INFO unit.mini/0.juju-log Step 1/3: opened ports: set() ``` With this patch they should be: ``` unit-mini-0: 13:43:35 INFO unit.mini/0.juju-log Step 1/3: INSTALL unit-mini-0: 13:43:35 INFO unit.mini/0.juju-log Step 1/3: Opening tcp 5432 unit-mini-0: 13:43:35 INFO unit.mini/0.juju-log Step 1/3: opened ports: {OpenedPort(protocol='tcp', port=5432)} ``` ## Bug reference https://bugs.launchpad.net/juju/+bug/2008035
Adds support for open-port, close-port and opened-ports as per the OP029 spec.
Also adds testing backend support for the same for use in charm tests.
Fixes #179