Derive mandatory relations from charmcraft.yaml
Currently each charm defines in the code all the mandatory relations. Instead populate the mandatory relations from chamrcraft.yaml requires relations with optional as False. Charm can define mandatory relations that are not derived from requires relations and they will be appended to the list of mandatory_relations. Barbican and ovn-central charms follows this pattern. Change-Id: Iff45fca33dc954593ded52b97e905431b6a7bb53
This commit is contained in:
parent
56c35f5988
commit
e07819a9d9
@ -252,13 +252,6 @@ class AodhOperatorCharm(sunbeam_charm.OSBaseOperatorAPICharm):
|
||||
|
||||
db_sync_cmds = [["aodh-dbsync"]]
|
||||
|
||||
mandatory_relations = {
|
||||
"database",
|
||||
"identity-service",
|
||||
"ingress-internal",
|
||||
"amqp",
|
||||
}
|
||||
|
||||
@property
|
||||
def service_conf(self) -> str:
|
||||
"""Service default configuration file."""
|
||||
|
@ -66,6 +66,7 @@ requires:
|
||||
interface: rabbitmq
|
||||
vault-kv:
|
||||
interface: vault-kv
|
||||
optional: true
|
||||
limit: 1
|
||||
receive-ca-cert:
|
||||
interface: certificate_transfer
|
||||
|
@ -250,12 +250,6 @@ class BarbicanOperatorCharm(sunbeam_charm.OSBaseOperatorAPICharm):
|
||||
service_name = "barbican-api"
|
||||
wsgi_admin_script = "/usr/bin/barbican-wsgi-api"
|
||||
wsgi_public_script = "/usr/bin/barbican-wsgi-api"
|
||||
mandatory_relations = {
|
||||
"database",
|
||||
"amqp",
|
||||
"identity-service",
|
||||
"ingress-internal",
|
||||
}
|
||||
|
||||
db_sync_cmds = [
|
||||
["sudo", "-u", "barbican", "barbican-manage", "db", "upgrade"]
|
||||
@ -435,9 +429,7 @@ class BarbicanOperatorCharm(sunbeam_charm.OSBaseOperatorAPICharm):
|
||||
class BarbicanVaultOperatorCharm(BarbicanOperatorCharm):
|
||||
"""Vault specialized Barbican Operator Charm."""
|
||||
|
||||
mandatory_relations = BarbicanOperatorCharm.mandatory_relations.union(
|
||||
{VAULT_KV_RELATION}
|
||||
)
|
||||
mandatory_relations = {VAULT_KV_RELATION}
|
||||
|
||||
def __init__(self, *args):
|
||||
super().__init__(*args)
|
||||
|
@ -181,7 +181,6 @@ class CeilometerOperatorCharm(sunbeam_charm.OSBaseOperatorCharmK8S):
|
||||
shared_metering_secret_key = "shared-metering-secret"
|
||||
|
||||
db_sync_cmds = [["ceilometer-upgrade"]]
|
||||
mandatory_relations = {"amqp", "identity-credentials", "gnocchi-db"}
|
||||
|
||||
def __init__(self, framework: ops.framework):
|
||||
super().__init__(framework)
|
||||
|
@ -224,13 +224,6 @@ class CinderCephOperatorCharm(charm.OSBaseOperatorCharmK8S):
|
||||
|
||||
ceph_access_relation_name = "ceph-access"
|
||||
|
||||
mandatory_relations = {
|
||||
"database",
|
||||
"amqp",
|
||||
"ceph",
|
||||
"storage-backend",
|
||||
}
|
||||
|
||||
def __init__(self, framework):
|
||||
super().__init__(framework)
|
||||
self._state.set_default(api_ready=False)
|
||||
|
@ -201,14 +201,6 @@ class CinderOperatorCharm(sunbeam_charm.OSBaseOperatorAPICharm):
|
||||
wsgi_admin_script = "/usr/bin/cinder-wsgi"
|
||||
wsgi_public_script = "/usr/bin/cinder-wsgi"
|
||||
|
||||
mandatory_relations = {
|
||||
"database",
|
||||
"amqp",
|
||||
"storage-backend",
|
||||
"identity-service",
|
||||
"ingress-internal",
|
||||
}
|
||||
|
||||
db_sync_cmds = [
|
||||
[
|
||||
"sudo",
|
||||
|
@ -198,8 +198,6 @@ class BindOperatorCharm(sunbeam_charm.OSBaseOperatorCharmK8S):
|
||||
_state = StoredState()
|
||||
service_name = "designate-bind"
|
||||
|
||||
# mandatory_relations = {}
|
||||
|
||||
def __init__(self, *args):
|
||||
super().__init__(*args)
|
||||
self.framework.observe(self.on.secret_rotate, self._on_secret_rotate)
|
||||
|
@ -361,14 +361,6 @@ class DesignateOperatorCharm(sunbeam_charm.OSBaseOperatorAPICharm):
|
||||
["sudo", "-u", "designate", "designate-manage", "pool", "update"],
|
||||
]
|
||||
|
||||
mandatory_relations = {
|
||||
"database",
|
||||
"identity-service",
|
||||
"ingress-internal",
|
||||
"amqp",
|
||||
BIND_RNDC_RELATION,
|
||||
}
|
||||
|
||||
def __init__(self, *args):
|
||||
super().__init__(*args)
|
||||
self.framework.observe(self.on.install, self._on_install)
|
||||
|
@ -327,9 +327,10 @@ requires:
|
||||
amqp:
|
||||
interface: rabbitmq
|
||||
optional: true
|
||||
# ceph is not marked as optional as the GlanceStorage relation handler
|
||||
# falls back to juju storage if ceph relation is not connected.
|
||||
ceph:
|
||||
interface: ceph-client
|
||||
optional: true
|
||||
receive-ca-cert:
|
||||
interface: certificate_transfer
|
||||
optional: true
|
||||
|
@ -290,16 +290,6 @@ class GlanceOperatorCharm(sunbeam_charm.OSBaseOperatorAPICharm):
|
||||
]
|
||||
]
|
||||
|
||||
# ceph is included in the mandatory list as the GlanceStorage
|
||||
# relation handler falls back to juju storage if ceph relation
|
||||
# is not connected.
|
||||
mandatory_relations = {
|
||||
"database",
|
||||
"identity-service",
|
||||
"ingress-internal",
|
||||
"ceph",
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs) -> None:
|
||||
super().__init__(*args, **kwargs)
|
||||
self.framework.observe(
|
||||
|
@ -184,13 +184,6 @@ class GnocchiOperatorCharm(sunbeam_charm.OSBaseOperatorAPICharm):
|
||||
|
||||
db_sync_cmds = [["gnocchi-upgrade"]]
|
||||
|
||||
mandatory_relations = {
|
||||
"database",
|
||||
"identity-service",
|
||||
"ingress-internal",
|
||||
"ceph",
|
||||
}
|
||||
|
||||
@property
|
||||
def service_conf(self) -> str:
|
||||
"""Service default configuration file."""
|
||||
|
@ -203,14 +203,6 @@ class HeatOperatorCharm(sunbeam_charm.OSBaseOperatorAPICharm):
|
||||
|
||||
db_sync_cmds = [["heat-manage", "db_sync"]]
|
||||
|
||||
mandatory_relations = {
|
||||
"database",
|
||||
"amqp",
|
||||
"identity-service",
|
||||
"traefik-route-internal",
|
||||
"identity-ops",
|
||||
}
|
||||
|
||||
def __init__(self, framework):
|
||||
self.traefik_route_public = None
|
||||
self.traefik_route_internal = None
|
||||
|
@ -139,12 +139,6 @@ class HorizonOperatorCharm(sunbeam_charm.OSBaseOperatorAPICharm):
|
||||
]
|
||||
]
|
||||
|
||||
mandatory_relations = {
|
||||
"database",
|
||||
"ingress-internal",
|
||||
"identity-credentials",
|
||||
}
|
||||
|
||||
def __init__(self, framework):
|
||||
super().__init__(framework)
|
||||
self._state.set_default(plugins=[])
|
||||
|
@ -151,6 +151,7 @@ requires:
|
||||
optional: true
|
||||
domain-config:
|
||||
interface: keystone-domain-config
|
||||
optional: true
|
||||
logging:
|
||||
interface: loki_push_api
|
||||
optional: true
|
||||
|
@ -334,7 +334,6 @@ class KeystoneOperatorCharm(sunbeam_charm.OSBaseOperatorAPICharm):
|
||||
domain_config_dir = Path("/etc/keystone/domains")
|
||||
domain_ca_dir = Path("/usr/local/share/ca-certificates")
|
||||
service_port = 5000
|
||||
mandatory_relations = {"database", "ingress-internal"}
|
||||
db_sync_cmds = [
|
||||
[
|
||||
"sudo",
|
||||
|
@ -142,13 +142,6 @@ class MagnumOperatorCharm(sunbeam_charm.OSBaseOperatorAPICharm):
|
||||
service_name = "magnum-api"
|
||||
wsgi_admin_script = "/usr/bin/magnum-api-wsgi"
|
||||
wsgi_public_script = "/usr/bin/magnum-api-wsgi"
|
||||
mandatory_relations = {
|
||||
"database",
|
||||
"amqp",
|
||||
"identity-service",
|
||||
"ingress-internal",
|
||||
"identity-ops",
|
||||
}
|
||||
|
||||
db_sync_cmds = [["sudo", "-u", "magnum", "magnum-db-manage", "upgrade"]]
|
||||
|
||||
|
@ -290,13 +290,6 @@ class MasakariHostMonitorPebbleHandler(sunbeam_chandlers.ServicePebbleHandler):
|
||||
class MasakariOperatorCharm(sunbeam_charm.OSBaseOperatorAPICharm):
|
||||
"""Charm the service."""
|
||||
|
||||
mandatory_relations = {
|
||||
"database",
|
||||
"amqp",
|
||||
"identity-service",
|
||||
"ingress-internal",
|
||||
}
|
||||
|
||||
wsgi_admin_script = "/usr/bin/masakari-wsgi"
|
||||
wsgi_public_script = "/usr/bin/masakari-wsgi"
|
||||
|
||||
|
@ -427,14 +427,6 @@ class NeutronServerOVNPebbleHandler(NeutronServerPebbleHandler):
|
||||
class NeutronOVNOperatorCharm(NeutronOperatorCharm):
|
||||
"""Neutron charm class for OVN."""
|
||||
|
||||
mandatory_relations = {
|
||||
"amqp",
|
||||
"database",
|
||||
"ovsdb-cms",
|
||||
"identity-service",
|
||||
"ingress-internal",
|
||||
}
|
||||
|
||||
@property
|
||||
def config_contexts(self) -> list[sunbeam_ctxts.ConfigContext]:
|
||||
"""Configuration contexts for the operator."""
|
||||
|
@ -91,20 +91,11 @@ requires:
|
||||
limit: 1
|
||||
amqp:
|
||||
interface: rabbitmq
|
||||
image-service:
|
||||
interface: glance
|
||||
identity-service:
|
||||
interface: keystone
|
||||
cloud-compute:
|
||||
interface: nova-compute
|
||||
cinder-volume-service:
|
||||
interface: cinder
|
||||
neutron-network-service:
|
||||
interface: neutron
|
||||
neutron-api:
|
||||
interface: neutron-api
|
||||
placement:
|
||||
interface: placement
|
||||
optional: true
|
||||
receive-ca-cert:
|
||||
interface: certificate_transfer
|
||||
optional: true
|
||||
|
@ -343,15 +343,6 @@ class NovaOperatorCharm(sunbeam_charm.OSBaseOperatorAPICharm):
|
||||
wsgi_admin_script = "/usr/bin/nova-api-wsgi"
|
||||
wsgi_public_script = "/usr/bin/nova-api-wsgi"
|
||||
shared_metadata_secret_key = "shared-metadata-secret"
|
||||
mandatory_relations = {
|
||||
"database",
|
||||
"api-database",
|
||||
"cell-database",
|
||||
"amqp",
|
||||
"identity-service",
|
||||
"ingress-internal",
|
||||
"traefik-route-internal",
|
||||
}
|
||||
|
||||
def __init__(self, framework):
|
||||
self.traefik_route_public = None
|
||||
|
@ -300,13 +300,6 @@ class OctaviaOperatorCharm(sunbeam_charm.OSBaseOperatorAPICharm):
|
||||
class OctaviaOVNOperatorCharm(OctaviaOperatorCharm):
|
||||
"""Charm the Octavia service with OVN provider."""
|
||||
|
||||
mandatory_relations = {
|
||||
"database",
|
||||
"ovsdb-cms",
|
||||
"identity-service",
|
||||
"ingress-internal",
|
||||
}
|
||||
|
||||
@property
|
||||
def config_contexts(self) -> List[sunbeam_config_contexts.ConfigContext]:
|
||||
"""Configuration contexts for the operator."""
|
||||
|
@ -158,9 +158,6 @@ class GrafanaDashboardsRelationHandler(sunbeam_rhandlers.RelationHandler):
|
||||
class OSExporterOperatorCharm(sunbeam_charm.OSBaseOperatorCharmK8S):
|
||||
"""Charm the service."""
|
||||
|
||||
mandatory_relations = {
|
||||
"identity-ops",
|
||||
}
|
||||
service_name = "openstack-exporter"
|
||||
|
||||
@property
|
||||
|
@ -105,6 +105,7 @@ requires:
|
||||
interface: nova
|
||||
masakari-service:
|
||||
interface: service-ready
|
||||
optional: true
|
||||
tracing:
|
||||
interface: tracing
|
||||
optional: true
|
||||
|
@ -162,13 +162,6 @@ class HypervisorOperatorCharm(sunbeam_charm.OSBaseOperatorCharm):
|
||||
METADATA_SECRET_KEY = "ovn-metadata-proxy-shared-secret"
|
||||
DEFAULT_SECRET_LENGTH = 32
|
||||
|
||||
mandatory_relations = {
|
||||
"amqp",
|
||||
"identity-credentials",
|
||||
"ovsdb-cms",
|
||||
"nova-service",
|
||||
}
|
||||
|
||||
def __init__(self, framework: ops.framework.Framework) -> None:
|
||||
"""Run constructor."""
|
||||
super().__init__(framework)
|
||||
|
@ -59,7 +59,6 @@ requires:
|
||||
ingress-internal:
|
||||
interface: ingress
|
||||
limit: 1
|
||||
optional: true
|
||||
ingress-public:
|
||||
interface: ingress
|
||||
optional: true
|
||||
|
@ -155,10 +155,6 @@ class OpenstackImagesSyncK8SCharm(sunbeam_charm.OSBaseOperatorAPICharm):
|
||||
"""Charm the application."""
|
||||
|
||||
service_name = "openstack-images-sync"
|
||||
mandatory_relations = {
|
||||
"identity-service",
|
||||
"ingress-internal",
|
||||
}
|
||||
|
||||
@property
|
||||
def service_conf(self) -> str:
|
||||
|
@ -183,7 +183,7 @@ class OVNCentralOperatorCharm(sunbeam_charm.OSBaseOperatorCharmK8S):
|
||||
"""Charm the service."""
|
||||
|
||||
_state = StoredState()
|
||||
mandatory_relations = {"certificates", "peers"}
|
||||
mandatory_relations = {"peers"}
|
||||
|
||||
def __init__(self, framework):
|
||||
"""Setup OVN central charm class."""
|
||||
|
@ -93,11 +93,6 @@ class OVNRelayPebbleHandler(ovn_chandlers.OVNPebbleHandler):
|
||||
class OVNRelayOperatorCharm(ovn_charm.OSBaseOVNOperatorCharm):
|
||||
"""Charm the service."""
|
||||
|
||||
mandatory_relations = {
|
||||
"ovsdb-cms",
|
||||
"certificates",
|
||||
}
|
||||
|
||||
def __init__(self, framework):
|
||||
super().__init__(framework)
|
||||
self.service_patcher = KubernetesServicePatch(
|
||||
|
@ -117,6 +117,7 @@ requires:
|
||||
interface: keystone-resources
|
||||
logging:
|
||||
interface: loki_push_api
|
||||
optional: true
|
||||
receive-ca-cert:
|
||||
interface: certificate_transfer
|
||||
optional: true
|
||||
|
@ -107,8 +107,6 @@ class TempestOperatorCharm(sunbeam_charm.OSBaseOperatorCharmK8S):
|
||||
_state = ops.framework.StoredState()
|
||||
service_name = "tempest"
|
||||
|
||||
mandatory_relations = {"identity-ops"}
|
||||
|
||||
def __init__(self, framework: ops.framework.Framework) -> None:
|
||||
"""Run the constructor."""
|
||||
# config for openstack, used by tempest
|
||||
|
@ -118,12 +118,6 @@ class WatcherOperatorCharm(sunbeam_charm.OSBaseOperatorAPICharm):
|
||||
service_name = "watcher-api"
|
||||
wsgi_admin_script = "/usr/bin/watcher-api-wsgi"
|
||||
wsgi_public_script = "/usr/bin/watcher-api-wsgi"
|
||||
mandatory_relations = {
|
||||
"database",
|
||||
"amqp",
|
||||
"identity-service",
|
||||
"ingress-internal",
|
||||
}
|
||||
|
||||
db_sync_cmds = [
|
||||
[
|
||||
|
@ -79,6 +79,7 @@ class OSBaseOperatorCharm(ops.charm.CharmBase):
|
||||
_state = ops.framework.StoredState()
|
||||
|
||||
# Holds set of mandatory relations
|
||||
# Auto-updates the mandatory requires relations from charmcraft.yaml
|
||||
mandatory_relations: set[str] = set()
|
||||
service_name: str
|
||||
|
||||
@ -92,6 +93,17 @@ class OSBaseOperatorCharm(ops.charm.CharmBase):
|
||||
"by ops_sunbeam"
|
||||
)
|
||||
)
|
||||
|
||||
# Update mandatory relations from charmcraft.yaml definitions
|
||||
requires_relations: set[str] = {
|
||||
name
|
||||
for name, metadata in self.meta.requires.items()
|
||||
if metadata.optional is False
|
||||
}
|
||||
self.mandatory_relations = requires_relations.union(
|
||||
self.mandatory_relations
|
||||
)
|
||||
|
||||
# unit_bootstrapped is stored in the local unit storage which is lost
|
||||
# when the pod is replaced, so this will revert to False on charm
|
||||
# upgrade or upgrade of the payload container.
|
||||
@ -789,7 +801,6 @@ class OSBaseOperatorCharmK8S(OSBaseOperatorCharm):
|
||||
class OSBaseOperatorAPICharm(OSBaseOperatorCharmK8S):
|
||||
"""Base class for OpenStack API operators."""
|
||||
|
||||
mandatory_relations = {"database", "identity-service", "ingress-internal"}
|
||||
wsgi_admin_script: str
|
||||
wsgi_public_script: str
|
||||
|
||||
|
@ -108,6 +108,7 @@ requires:
|
||||
limit: 1
|
||||
ingress-public:
|
||||
interface: ingress
|
||||
optional: true
|
||||
limit: 1
|
||||
amqp:
|
||||
interface: rabbitmq
|
||||
@ -115,9 +116,11 @@ requires:
|
||||
interface: keystone
|
||||
identity-credentials:
|
||||
interface: keystone-credentials
|
||||
optional: true
|
||||
limit: 1
|
||||
ceph-access:
|
||||
interface: cinder-ceph-key
|
||||
optional: true
|
||||
|
||||
peers:
|
||||
peers:
|
||||
@ -253,12 +256,6 @@ class MyAPICharm(sunbeam_charm.OSBaseOperatorAPICharm):
|
||||
service_name = "my-service"
|
||||
wsgi_admin_script = "/bin/wsgi_admin"
|
||||
wsgi_public_script = "/bin/wsgi_public"
|
||||
mandatory_relations = {
|
||||
"database",
|
||||
"amqp",
|
||||
"identity-service",
|
||||
"ingress-public",
|
||||
}
|
||||
|
||||
def __init__(self, framework: "ops.framework.Framework") -> None:
|
||||
"""Run constructor."""
|
||||
|
@ -365,7 +365,7 @@ class TestOSBaseOperatorAPICharm(_TestOSBaseOperatorAPICharm):
|
||||
self.harness.charm.get_mandatory_relations_not_ready(
|
||||
self.mock_event
|
||||
),
|
||||
{"identity-service", "ingress-public", "amqp"},
|
||||
{"identity-service", "ingress-internal", "amqp"},
|
||||
)
|
||||
|
||||
amqp_rel_id = test_utils.add_base_amqp_relation(self.harness)
|
||||
@ -374,7 +374,7 @@ class TestOSBaseOperatorAPICharm(_TestOSBaseOperatorAPICharm):
|
||||
self.harness.charm.get_mandatory_relations_not_ready(
|
||||
self.mock_event
|
||||
),
|
||||
{"ingress-public", "identity-service"},
|
||||
{"ingress-internal", "identity-service"},
|
||||
)
|
||||
|
||||
identity_rel_id = test_utils.add_base_identity_service_relation(
|
||||
@ -387,14 +387,14 @@ class TestOSBaseOperatorAPICharm(_TestOSBaseOperatorAPICharm):
|
||||
self.harness.charm.get_mandatory_relations_not_ready(
|
||||
self.mock_event
|
||||
),
|
||||
{"ingress-public"},
|
||||
{"ingress-internal"},
|
||||
)
|
||||
|
||||
ingress_rel_id = test_utils.add_ingress_relation(
|
||||
self.harness, "public"
|
||||
self.harness, "internal"
|
||||
)
|
||||
test_utils.add_ingress_relation_data(
|
||||
self.harness, ingress_rel_id, "public"
|
||||
self.harness, ingress_rel_id, "internal"
|
||||
)
|
||||
|
||||
ceph_access_rel_id = test_utils.add_base_ceph_access_relation(
|
||||
@ -413,10 +413,10 @@ class TestOSBaseOperatorAPICharm(_TestOSBaseOperatorAPICharm):
|
||||
# Add an optional relation and test if relation_handlers_ready
|
||||
# returns True
|
||||
optional_rel_id = test_utils.add_ingress_relation(
|
||||
self.harness, "internal"
|
||||
self.harness, "public"
|
||||
)
|
||||
test_utils.add_ingress_relation_data(
|
||||
self.harness, optional_rel_id, "internal"
|
||||
self.harness, optional_rel_id, "public"
|
||||
)
|
||||
self.assertSetEqual(
|
||||
self.harness.charm.get_mandatory_relations_not_ready(
|
||||
@ -432,15 +432,15 @@ class TestOSBaseOperatorAPICharm(_TestOSBaseOperatorAPICharm):
|
||||
self.harness.charm.get_mandatory_relations_not_ready(
|
||||
self.mock_event
|
||||
),
|
||||
{"ingress-public"},
|
||||
{"ingress-internal"},
|
||||
)
|
||||
|
||||
# Add the mandatory relation back and retest relation_handlers_ready
|
||||
ingress_rel_id = test_utils.add_ingress_relation(
|
||||
self.harness, "public"
|
||||
self.harness, "internal"
|
||||
)
|
||||
test_utils.add_ingress_relation_data(
|
||||
self.harness, ingress_rel_id, "public"
|
||||
self.harness, ingress_rel_id, "internal"
|
||||
)
|
||||
self.assertSetEqual(
|
||||
self.harness.charm.get_mandatory_relations_not_ready(
|
||||
|
Loading…
x
Reference in New Issue
Block a user