Often, charms need to access network information; for example:
self.model.get_binding('juju-info').network.bind_address
However, those of you who have tried unittesting this kind of charms will know that this doesn’t work out of the box. So, fresh out of the press, we present to you a networking harness extension.
charmcraft fetch-lib charms.harness_extensions.v0.networking
(source)
DISCLAIMER: This is a very early release, a preview of a preview, in alpha version. Take a look, give feedback, but keep in mind that things might still dramatically change soon-ish.
For the above use case, it will be sufficient to add to the top of your unittest file (or conftest.py if you’re into that) the following lines:
from charms.harness_extensions.v0 import networking
networking.enable()
For the more complicated use cases, the networking extension offers a few utilities:
# let's pretend 'foo' is a relation:
foo = charm.model.get_relation('foo', 1)
with networking(networks={foo: Network(private_address="42.42.42.42")}):
# the juju-info network is present by default unless you pass None
assert c.model.get_binding("juju-info").network.bind_address == IPv4Address("1.1.1.1")
# the custom foo endpoint is mocked:
assert c.model.get_binding(foo).network.bind_address == IPv4Address("42.42.42.42")
assert c.model.get_binding('foo').network.bind_address == IPv4Address("42.42.42.42")
This is very condensed; what is going on behind the scenes is in fact:
networking.enable()
networking.add_network('foo', 1,
{
"bind-addresses": [
{
"mac-address": "",
"interface-name": "",
"interfacename": "",
"addresses": [
{"hostname": "", "value": "1.1.1.1", "cidr": ""}
],
}
],
"bind-address": "1.1.1.1",
"egress-subnets": ["1.1.1.2/32"],
"ingress-addresses": ["1.1.1.2"],
})
# ... do your tests
networking.disable()
So you can do this whenever you need lower-level control over the network data.
This allows you to simulate juju relate via
situations.
Disclaimer
This is not a full mockup of Juju networking. Therefore, consistency is not guaranteed. In order to accurately mock real-world juju networking behaviour, you will still need to understand real-world juju networking behaviour.
This library will make it easier for you to implement some basic scenarios and some common use cases, but if you start wondering ‘how does my CMR fit into this’? Or ‘where are my spaces’? Then you probably need something more advanced. (In which case, do get in touch! We’re eager to understand and support your use case too!)