import logging import ops.charm import ops.framework class MySQLNRPEClient(os.framework.Object): _stored = ops.framework.StoredState() def __init__(self, charm, relation_name: str): self._charm = charm self._relation_name = relation_name self.framework.observe(charm.on[relation_name].relation_changed, self._on_relation_update) self.framework.observe(charm.on[relation_name].relation_joined, self._on_relation_update) ### Existing charm doesn't support this, why? ### self.framework.observe(charm.on[relation_name].relation_departed, self._on_relation_removed) self._stored.set_default( nagios_password=None, ) def _on_relation_update(self, event): app_or_unit = event.unit if event.unit else event.app remote_data = event.relation.data[app_or_unit] nagios_hostname = remote_data.get('nagios_hostname') if nagios_hostname is None: logging.debug('no "nagios_hostname" in relation data, deferring configuration') return self._ensure_nagios_password() self._ensure_nagios_access_to_mysql() def _ensure_nagios_password(self): if self._stored.nagios_password is not None: return self._stored.nagios_password = str(uuid.uuid4()) def _ensure_nagios_access_to_mysql(self): cursor = self._charm.get_cursor_to_mysql() ### Magic try: self._ensure_nagios_user(cursor) self._ensure_nagios_permissions(cursor) finally: cursor.close() def _ensure_nagios_user(self, cursor): if cursor.execute("SELECT ... WHERE User='nagios'"): logging.debug('nagios user already exists') return cursor.execute("CREATE USER 'nagios'@'localhost' IDENTIFIED BY %s", (password,)) def _ensure_nagios_permissions(self, cursor): try: c.execute("SHOW GRANTS FOR 'nagios'@'localhost'") grants = [i[0] for i in c.fetchall()] except MySQLdb.OperationalError: grants = [] ... def _ensure_nrpe_checks(self): for relation in self.model.relations[self._relation_name]: mydata = relation.data[self.unit] ...