-
Notifications
You must be signed in to change notification settings - Fork 5
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 external-load-balancer relation #234
Add external-load-balancer relation #234
Conversation
33093a9
to
d8a90d4
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.
great work @HomayoonAlimohammadi
Did a first pass with a general question.
c733800
to
f278456
Compare
f278456
to
3aa9688
Compare
a809297
to
74860c9
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.
Good work down this road... there's still a bit to clean up here
78fef20
to
4efd89f
Compare
430f2a7
to
461e9e8
Compare
charms/worker/k8s/requirements.txt
Outdated
@@ -17,3 +17,5 @@ websocket-client==1.8.0 | |||
poetry-core==1.9.1 | |||
lightkube==0.16.0 | |||
httpx==0.27.2 | |||
loadbalancer_interface == 1.2.0 | |||
cryptography==44.0.0 |
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.
OH dude, i have bad news. You can't use this library b/c that library requires our charm not be able to support multiple series.
cryptography
compiles C code specific for the ubuntu base's python. Building on focal, yields code that doesn't run on jammy or noble. The same is true if you build on jammy -- it doesn't run on focal/noble.
my best advice. subprocess out to openssl
on the device
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.
Dude, hue this is looking so good. Feel free to be angry with me.
Thanks for your defensive coding practices
charms/worker/k8s/src/charm.py
Outdated
binding = self.model.get_binding(CLUSTER_RELATION) | ||
try: | ||
addresses = binding and binding.network.ingress_addresses | ||
if addresses: | ||
for addr in addresses: | ||
extra_sans.add(str(addr)) | ||
except ops.RelationNotFoundError as e: | ||
log.error(f"Failed to get ingress addresses for extra SANs: {e}") |
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.
so, the CLUSTER_RELATION should ALWAYS be available b/c it's a peer relation. it's required to be there
Would this work?
binding = self.model.get_binding(CLUSTER_RELATION) | |
try: | |
addresses = binding and binding.network.ingress_addresses | |
if addresses: | |
for addr in addresses: | |
extra_sans.add(str(addr)) | |
except ops.RelationNotFoundError as e: | |
log.error(f"Failed to get ingress addresses for extra SANs: {e}") | |
binding = self.model.get_binding(CLUSTER_RELATION) | |
extra_sans |= {str(addr) for addr in binding and binding.network.ingress_addresses or []) |
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 was because of some unit tests that were expecting this relation but it was not there.
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 support Adam's suggestion. You can resolve the unit testing issue by using the Harness
and creating the required relations, right?
charms/worker/k8s/src/charm.py
Outdated
log.error(f"Failed to get ingress addresses for extra SANs: {e}") | ||
|
||
# Add the external load balancer address | ||
if self.is_control_plane and self.external_load_balancer.is_available: |
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.
it doesn't make sense for the worker to need this list -- basically ever. If you wanna protect against it occuring, just do a this near the beginning of the func
if not self.is_control_plane:
raise ReconcilerError("Intended only for the Control Plane Charm")
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.
Tried removing this but we're calling _assemble_bootstrap_config
from a unit test with both a control plane and a worker charm.
4ebc2eb
to
84f7501
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.
We should update the version of this library whenever we introduce new changes. In this case, could you please bump the patch version of the library?
charms/worker/k8s/src/charm.py
Outdated
binding = self.model.get_binding(CLUSTER_RELATION) | ||
try: | ||
addresses = binding and binding.network.ingress_addresses | ||
if addresses: | ||
for addr in addresses: | ||
extra_sans.add(str(addr)) | ||
except ops.RelationNotFoundError as e: | ||
log.error(f"Failed to get ingress addresses for extra SANs: {e}") |
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 support Adam's suggestion. You can resolve the unit testing issue by using the Harness
and creating the required relations, right?
charms/worker/k8s/src/charm.py
Outdated
for san in extra_sans: | ||
if san not in all_cert_sans: | ||
log.info(f"{san} not in cert SANs, refreshing certs with new SANs: {extra_sans}") | ||
status.add(ops.MaintenanceStatus("Refreshing Certificates")) | ||
self.api_manager.refresh_certs(extra_sans) | ||
log.info("Certificates have been refreshed") |
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 calls refresh_certs
in a loop, once for each missing SAN. Therefore, the certificates will be refreshed multiple times unnecessarily:
for san in extra_sans: | |
if san not in all_cert_sans: | |
log.info(f"{san} not in cert SANs, refreshing certs with new SANs: {extra_sans}") | |
status.add(ops.MaintenanceStatus("Refreshing Certificates")) | |
self.api_manager.refresh_certs(extra_sans) | |
log.info("Certificates have been refreshed") | |
missing_sans = [san for san in extra_sans if san not in all_cert_sans] | |
if missing_sans: | |
log.info("Missing SANs found, refreshing certificates.") | |
status.add(ops.MaintenanceStatus("Refreshing Certificates")) | |
self.api_manager.refresh_certs(extra_sans) | |
log.info("Certificates have been refreshed") |
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.
That's a really good catch. Thanks!
pyproject.toml
Outdated
@@ -48,7 +48,8 @@ plugins = "pydantic.mypy" | |||
[tool.pylint] | |||
# Ignore too-few-public-methods due to pydantic models | |||
# Ignore no-self-argument due to pydantic validators | |||
disable = "wrong-import-order,redefined-outer-name,too-many-instance-attributes,too-few-public-methods,no-self-argument,fixme,protected-access" | |||
# Ignore logging-fstring-interpolation which instructs to use %s instead of f-strings in logs which is objectively worse. |
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.
F-strings are evaluated even if the log message is not displayed (e.g., log level): https://docs.python.org/3/howto/logging.html#optimization
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.
Nice, TIL! Changing to %s, but TBH I'm not fully convinced that this optimization is actually worth the readability hit.
84f7501
to
5a360e7
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.
Looking really really good. Thanks for the switch to openssl.
I'm going to build this charm today and try it out
78f2aa2
to
1f6f431
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.
Finally, it all looks so good. We know it's not 100% tested yet but the impl looks right. Nice job @HomayoonAlimohammadi
Thanks @addyess! I need to add multiple unit and integration tests. Didn't test the Openstack LB integration since you mentioned the issue with the openstack integrator charm (incompatible ops versions), but manually tried changing the extra SANs through charm config and seems like the certs refresh alright. |
7117a19
to
8a4ebbe
Compare
Test coverage for 8a4ebbe
Static code analysis report
|
Overview
This PR adds
external-load-balancer
relation. This relation enablesk8s-operator
to utilize external LB sources like Openstack Octavia or Amazon ELB.The
external-load-balancer-port
config is also added. This config should be set according to the external LB provider config. Example for Openstack integrator: https://github.com/charmed-kubernetes/charm-openstack-integrator/blob/main/reactive/openstack.py#L245-L254Please merge me as well #235 (Happy new year!)