Switch to published identity-service interface
This commit is contained in:
parent
0c6635f708
commit
468343bfae
|
@ -11,3 +11,4 @@ __pycache__/
|
||||||
.stestr/
|
.stestr/
|
||||||
lib/charms/nginx*
|
lib/charms/nginx*
|
||||||
lib/charms/sunbeam_rabbitmq*
|
lib/charms/sunbeam_rabbitmq*
|
||||||
|
lib/charms/sunbeam_keystone*
|
||||||
|
|
|
@ -25,8 +25,7 @@ import ops.charm
|
||||||
import charms.nginx_ingress_integrator.v0.ingress as ingress
|
import charms.nginx_ingress_integrator.v0.ingress as ingress
|
||||||
import charms.mysql.v1.mysql as mysql
|
import charms.mysql.v1.mysql as mysql
|
||||||
import charms.sunbeam_rabbitmq_operator.v0.amqp as sunbeam_amqp
|
import charms.sunbeam_rabbitmq_operator.v0.amqp as sunbeam_amqp
|
||||||
import charms.sunbeam_identity_service_operator.v0.identity_service \
|
import charms.sunbeam_keystone_operator.v0.identity_service as sunbeam_id_svc
|
||||||
as sunbeam_id_svc
|
|
||||||
import advanced_sunbeam_openstack.interfaces as sunbeam_interfaces
|
import advanced_sunbeam_openstack.interfaces as sunbeam_interfaces
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
|
@ -2,6 +2,6 @@
|
||||||
|
|
||||||
charmcraft fetch-lib charms.nginx_ingress_integrator.v0.ingress
|
charmcraft fetch-lib charms.nginx_ingress_integrator.v0.ingress
|
||||||
charmcraft fetch-lib charms.mysql.v1.mysql
|
charmcraft fetch-lib charms.mysql.v1.mysql
|
||||||
charmcraft fetch-lib charms.sunbeam_identity_service_operator.v0.identity_service
|
charmcraft fetch-lib charms.sunbeam_keystone_operator.v0.identity_service
|
||||||
charmcraft fetch-lib charms.sunbeam_rabbitmq_operator.v0.amqp
|
charmcraft fetch-lib charms.sunbeam_rabbitmq_operator.v0.amqp
|
||||||
|
|
||||||
|
|
|
@ -1,470 +0,0 @@
|
||||||
"""IdentityServiceProvides and Requires module.
|
|
||||||
|
|
||||||
|
|
||||||
This library contains the Requires and Provides classes for handling
|
|
||||||
the identity_service interface.
|
|
||||||
|
|
||||||
Import `IdentityServiceRequires` in your charm, with the charm object and the
|
|
||||||
relation name:
|
|
||||||
- self
|
|
||||||
- "identity_service"
|
|
||||||
|
|
||||||
Also provide additional parameters to the charm object:
|
|
||||||
- service
|
|
||||||
- internal_url
|
|
||||||
- public_url
|
|
||||||
- admin_url
|
|
||||||
- region
|
|
||||||
- username
|
|
||||||
- vhost
|
|
||||||
|
|
||||||
Two events are also available to respond to:
|
|
||||||
- connected
|
|
||||||
- ready
|
|
||||||
- goneaway
|
|
||||||
|
|
||||||
A basic example showing the usage of this relation follows:
|
|
||||||
|
|
||||||
```
|
|
||||||
from charms.sunbeam_sunbeam_identity_service_operator.v0.identity_service import IdentityServiceRequires
|
|
||||||
|
|
||||||
class IdentityServiceClientCharm(CharmBase):
|
|
||||||
def __init__(self, *args):
|
|
||||||
super().__init__(*args)
|
|
||||||
# IdentityService Requires
|
|
||||||
self.identity_service = IdentityServiceRequires(
|
|
||||||
self, "identity_service",
|
|
||||||
service = "my-service"
|
|
||||||
internal_url = "http://internal-url"
|
|
||||||
public_url = "http://public-url"
|
|
||||||
admin_url = "http://admin-url"
|
|
||||||
region = "region"
|
|
||||||
)
|
|
||||||
self.framework.observe(
|
|
||||||
self.identity_service.on.connected, self._on_identity_service_connected)
|
|
||||||
self.framework.observe(
|
|
||||||
self.identity_service.on.ready, self._on_identity_service_ready)
|
|
||||||
self.framework.observe(
|
|
||||||
self.identity_service.on.goneaway, self._on_identity_service_goneaway)
|
|
||||||
|
|
||||||
def _on_identity_service_connected(self, event):
|
|
||||||
'''React to the IdentityService connected event.
|
|
||||||
|
|
||||||
This event happens when n IdentityService relation is added to the
|
|
||||||
model before credentials etc have been provided.
|
|
||||||
'''
|
|
||||||
# Do something before the relation is complete
|
|
||||||
pass
|
|
||||||
|
|
||||||
def _on_identity_service_ready(self, event):
|
|
||||||
'''React to the IdentityService ready event.
|
|
||||||
|
|
||||||
The IdentityService interface will use the provided config for the
|
|
||||||
request to the identity server.
|
|
||||||
'''
|
|
||||||
# IdentityService Relation is ready. Do something with the completed relation.
|
|
||||||
pass
|
|
||||||
|
|
||||||
def _on_identity_service_goneaway(self, event):
|
|
||||||
'''React to the IdentityService goneaway event.
|
|
||||||
|
|
||||||
This event happens when an IdentityService relation is removed.
|
|
||||||
'''
|
|
||||||
# IdentityService Relation has goneaway. shutdown services or suchlike
|
|
||||||
pass
|
|
||||||
```
|
|
||||||
"""
|
|
||||||
|
|
||||||
# The unique Charmhub library identifier, never change it
|
|
||||||
# LIBID = ""
|
|
||||||
|
|
||||||
# Increment this major API version when introducing breaking changes
|
|
||||||
LIBAPI = 0
|
|
||||||
|
|
||||||
# Increment this PATCH version before using `charmcraft publish-lib` or reset
|
|
||||||
# to 0 if you are raising the major API version
|
|
||||||
LIBPATCH = 3
|
|
||||||
|
|
||||||
import json
|
|
||||||
import logging
|
|
||||||
import requests
|
|
||||||
|
|
||||||
from ops.framework import (
|
|
||||||
StoredState,
|
|
||||||
EventBase,
|
|
||||||
ObjectEvents,
|
|
||||||
EventSource,
|
|
||||||
Object,
|
|
||||||
)
|
|
||||||
|
|
||||||
from ops.model import Relation
|
|
||||||
|
|
||||||
from typing import List
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
class IdentityServiceConnectedEvent(EventBase):
|
|
||||||
"""IdentityService connected Event."""
|
|
||||||
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class IdentityServiceReadyEvent(EventBase):
|
|
||||||
"""IdentityService ready for use Event."""
|
|
||||||
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class IdentityServiceGoneAwayEvent(EventBase):
|
|
||||||
"""IdentityService relation has gone-away Event"""
|
|
||||||
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class IdentityServiceServerEvents(ObjectEvents):
|
|
||||||
"""Events class for `on`"""
|
|
||||||
|
|
||||||
connected = EventSource(IdentityServiceConnectedEvent)
|
|
||||||
ready = EventSource(IdentityServiceReadyEvent)
|
|
||||||
goneaway = EventSource(IdentityServiceGoneAwayEvent)
|
|
||||||
|
|
||||||
|
|
||||||
class IdentityServiceRequires(Object):
|
|
||||||
"""
|
|
||||||
IdentityServiceRequires class
|
|
||||||
"""
|
|
||||||
|
|
||||||
on = IdentityServiceServerEvents()
|
|
||||||
_stored = StoredState()
|
|
||||||
|
|
||||||
def __init__(self, charm, relation_name: str, service_endpoints: dict,
|
|
||||||
region: str):
|
|
||||||
super().__init__(charm, relation_name)
|
|
||||||
self.charm = charm
|
|
||||||
self.relation_name = relation_name
|
|
||||||
self.service_endpoints = service_endpoints
|
|
||||||
self.region = region
|
|
||||||
self.framework.observe(
|
|
||||||
self.charm.on[relation_name].relation_joined,
|
|
||||||
self._on_identity_service_relation_joined,
|
|
||||||
)
|
|
||||||
self.framework.observe(
|
|
||||||
self.charm.on[relation_name].relation_changed,
|
|
||||||
self._on_identity_service_relation_changed,
|
|
||||||
)
|
|
||||||
self.framework.observe(
|
|
||||||
self.charm.on[relation_name].relation_departed,
|
|
||||||
self._on_identity_service_relation_changed,
|
|
||||||
)
|
|
||||||
self.framework.observe(
|
|
||||||
self.charm.on[relation_name].relation_broken,
|
|
||||||
self._on_identity_service_relation_broken,
|
|
||||||
)
|
|
||||||
|
|
||||||
def _on_identity_service_relation_joined(self, event):
|
|
||||||
"""IdentityService relation joined."""
|
|
||||||
logging.debug("IdentityService on_joined")
|
|
||||||
self.on.connected.emit()
|
|
||||||
self.register_services(
|
|
||||||
self.service_endpoints,
|
|
||||||
self.region)
|
|
||||||
|
|
||||||
def _on_identity_service_relation_changed(self, event):
|
|
||||||
"""IdentityService relation changed."""
|
|
||||||
logging.debug("IdentityService on_changed")
|
|
||||||
try:
|
|
||||||
self.service_password
|
|
||||||
self.on.ready.emit()
|
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def _on_identity_service_relation_broken(self, event):
|
|
||||||
"""IdentityService relation broken."""
|
|
||||||
logging.debug("IdentityService on_broken")
|
|
||||||
self.on.goneaway.emit()
|
|
||||||
|
|
||||||
@property
|
|
||||||
def _identity_service_rel(self) -> Relation:
|
|
||||||
"""The IdentityService relation."""
|
|
||||||
return self.framework.model.get_relation(self.relation_name)
|
|
||||||
|
|
||||||
def get_remote_app_data(self, key: str) -> str:
|
|
||||||
"""Return the value for the given key from remote app data."""
|
|
||||||
data = self._identity_service_rel.data[self._identity_service_rel.app]
|
|
||||||
return data.get(key)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def api_version(self) -> str:
|
|
||||||
"""Return the api_version."""
|
|
||||||
return self.get_remote_app_data('api-version')
|
|
||||||
|
|
||||||
@property
|
|
||||||
def auth_host(self) -> str:
|
|
||||||
"""Return the auth_host."""
|
|
||||||
return self.get_remote_app_data('auth-host')
|
|
||||||
|
|
||||||
@property
|
|
||||||
def auth_port(self) -> str:
|
|
||||||
"""Return the auth_port."""
|
|
||||||
return self.get_remote_app_data('auth-port')
|
|
||||||
|
|
||||||
@property
|
|
||||||
def auth_protocol(self) -> str:
|
|
||||||
"""Return the auth_protocol."""
|
|
||||||
return self.get_remote_app_data('auth-protocol')
|
|
||||||
|
|
||||||
@property
|
|
||||||
def internal_host(self) -> str:
|
|
||||||
"""Return the internal_host."""
|
|
||||||
return self.get_remote_app_data('internal-host')
|
|
||||||
|
|
||||||
@property
|
|
||||||
def internal_port(self) -> str:
|
|
||||||
"""Return the internal_port."""
|
|
||||||
return self.get_remote_app_data('internal-port')
|
|
||||||
|
|
||||||
@property
|
|
||||||
def internal_protocol(self) -> str:
|
|
||||||
"""Return the internal_protocol."""
|
|
||||||
return self.get_remote_app_data('internal-protocol')
|
|
||||||
|
|
||||||
@property
|
|
||||||
def admin_domain_name(self) -> str:
|
|
||||||
"""Return the admin_domain_name."""
|
|
||||||
return self.get_remote_app_data('admin-domain-name')
|
|
||||||
|
|
||||||
@property
|
|
||||||
def admin_domain_id(self) -> str:
|
|
||||||
"""Return the admin_domain_id."""
|
|
||||||
return self.get_remote_app_data('admin-domain-id')
|
|
||||||
|
|
||||||
@property
|
|
||||||
def admin_project_name(self) -> str:
|
|
||||||
"""Return the admin_project_name."""
|
|
||||||
return self.get_remote_app_data('admin-project-name')
|
|
||||||
|
|
||||||
@property
|
|
||||||
def admin_project_id(self) -> str:
|
|
||||||
"""Return the admin_project_id."""
|
|
||||||
return self.get_remote_app_data('admin-project-id')
|
|
||||||
|
|
||||||
@property
|
|
||||||
def admin_user_name(self) -> str:
|
|
||||||
"""Return the admin_user_name."""
|
|
||||||
return self.get_remote_app_data('admin-user-name')
|
|
||||||
|
|
||||||
@property
|
|
||||||
def admin_user_id(self) -> str:
|
|
||||||
"""Return the admin_user_id."""
|
|
||||||
return self.get_remote_app_data('admin-user-id')
|
|
||||||
|
|
||||||
@property
|
|
||||||
def service_domain_name(self) -> str:
|
|
||||||
"""Return the service_domain_name."""
|
|
||||||
return self.get_remote_app_data('service-domain-name')
|
|
||||||
|
|
||||||
@property
|
|
||||||
def service_domain_id(self) -> str:
|
|
||||||
"""Return the service_domain_id."""
|
|
||||||
return self.get_remote_app_data('service-domain-id')
|
|
||||||
|
|
||||||
@property
|
|
||||||
def service_host(self) -> str:
|
|
||||||
"""Return the service_host."""
|
|
||||||
return self.get_remote_app_data('service-host')
|
|
||||||
|
|
||||||
@property
|
|
||||||
def service_password(self) -> str:
|
|
||||||
"""Return the service_password."""
|
|
||||||
return self.get_remote_app_data('service-password')
|
|
||||||
|
|
||||||
@property
|
|
||||||
def service_port(self) -> str:
|
|
||||||
"""Return the service_port."""
|
|
||||||
return self.get_remote_app_data('service-port')
|
|
||||||
|
|
||||||
@property
|
|
||||||
def service_protocol(self) -> str:
|
|
||||||
"""Return the service_protocol."""
|
|
||||||
return self.get_remote_app_data('service-protocol')
|
|
||||||
|
|
||||||
@property
|
|
||||||
def service_project_name(self) -> str:
|
|
||||||
"""Return the service_project_name."""
|
|
||||||
return self.get_remote_app_data('service-project-name')
|
|
||||||
|
|
||||||
@property
|
|
||||||
def service_project_id(self) -> str:
|
|
||||||
"""Return the service_project_id."""
|
|
||||||
return self.get_remote_app_data('service-project-id')
|
|
||||||
|
|
||||||
@property
|
|
||||||
def service_user_name(self) -> str:
|
|
||||||
"""Return the service_user_name."""
|
|
||||||
return self.get_remote_app_data('service-user-name')
|
|
||||||
|
|
||||||
@property
|
|
||||||
def service_user_id(self) -> str:
|
|
||||||
"""Return the service_user_id."""
|
|
||||||
return self.get_remote_app_data('service-user-id')
|
|
||||||
|
|
||||||
|
|
||||||
def register_services(self, service_endpoints: dict,
|
|
||||||
region: str) -> None:
|
|
||||||
"""Request access to the IdentityService server."""
|
|
||||||
if self.model.unit.is_leader():
|
|
||||||
logging.debug("Requesting service registration")
|
|
||||||
app_data = self._identity_service_rel.data[self.charm.app]
|
|
||||||
app_data["service-endpoints"] = json.dumps(service_endpoints)
|
|
||||||
app_data["region"] = region
|
|
||||||
|
|
||||||
|
|
||||||
class HasIdentityServiceClientsEvent(EventBase):
|
|
||||||
"""Has IdentityServiceClients Event."""
|
|
||||||
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class ReadyIdentityServiceClientsEvent(EventBase):
|
|
||||||
"""IdentityServiceClients Ready Event."""
|
|
||||||
|
|
||||||
def __init__(self, handle, relation_id, relation_name, service_endpoints,
|
|
||||||
region, client_app_name):
|
|
||||||
super().__init__(handle)
|
|
||||||
self.relation_id = relation_id
|
|
||||||
self.relation_name = relation_name
|
|
||||||
self.service_endpoints = service_endpoints
|
|
||||||
self.region = region
|
|
||||||
self.client_app_name = client_app_name
|
|
||||||
|
|
||||||
|
|
||||||
def snapshot(self):
|
|
||||||
return {
|
|
||||||
"relation_id": self.relation_id,
|
|
||||||
"relation_name": self.relation_name,
|
|
||||||
"service_endpoints": self.service_endpoints,
|
|
||||||
"client_app_name": self.client_app_name,
|
|
||||||
"region": self.region}
|
|
||||||
|
|
||||||
def restore(self, snapshot):
|
|
||||||
super().restore(snapshot)
|
|
||||||
self.relation_id = snapshot["relation_id"]
|
|
||||||
self.relation_name = snapshot["relation_name"]
|
|
||||||
self.service_endpoints = snapshot["service_endpoints"]
|
|
||||||
self.region = snapshot["region"]
|
|
||||||
self.client_app_name = snapshot["client_app_name"]
|
|
||||||
|
|
||||||
|
|
||||||
class IdentityServiceClientEvents(ObjectEvents):
|
|
||||||
"""Events class for `on`"""
|
|
||||||
|
|
||||||
has_identity_service_clients = EventSource(HasIdentityServiceClientsEvent)
|
|
||||||
ready_identity_service_clients = EventSource(ReadyIdentityServiceClientsEvent)
|
|
||||||
|
|
||||||
|
|
||||||
class IdentityServiceProvides(Object):
|
|
||||||
"""
|
|
||||||
IdentityServiceProvides class
|
|
||||||
"""
|
|
||||||
|
|
||||||
on = IdentityServiceClientEvents()
|
|
||||||
_stored = StoredState()
|
|
||||||
|
|
||||||
def __init__(self, charm, relation_name):
|
|
||||||
super().__init__(charm, relation_name)
|
|
||||||
self.charm = charm
|
|
||||||
self.relation_name = relation_name
|
|
||||||
self.framework.observe(
|
|
||||||
self.charm.on[relation_name].relation_joined,
|
|
||||||
self._on_identity_service_relation_joined,
|
|
||||||
)
|
|
||||||
self.framework.observe(
|
|
||||||
self.charm.on[relation_name].relation_changed,
|
|
||||||
self._on_identity_service_relation_changed,
|
|
||||||
)
|
|
||||||
self.framework.observe(
|
|
||||||
self.charm.on[relation_name].relation_broken,
|
|
||||||
self._on_identity_service_relation_broken,
|
|
||||||
)
|
|
||||||
|
|
||||||
def _on_identity_service_relation_joined(self, event):
|
|
||||||
"""Handle IdentityService joined."""
|
|
||||||
logging.debug("IdentityService on_joined")
|
|
||||||
self.on.has_identity_service_clients.emit()
|
|
||||||
|
|
||||||
def _on_identity_service_relation_changed(self, event):
|
|
||||||
"""Handle IdentityService changed."""
|
|
||||||
logging.debug("IdentityService on_changed")
|
|
||||||
REQUIRED_KEYS = [
|
|
||||||
'service-endpoints',
|
|
||||||
'region']
|
|
||||||
|
|
||||||
values = [
|
|
||||||
event.relation.data[event.relation.app].get(k)
|
|
||||||
for k in REQUIRED_KEYS ]
|
|
||||||
# Validate data on the relation
|
|
||||||
if all(values):
|
|
||||||
print(event.relation.id)
|
|
||||||
print(event.relation.name)
|
|
||||||
service_eps = json.loads(
|
|
||||||
event.relation.data[event.relation.app]['service-endpoints'])
|
|
||||||
self.on.ready_identity_service_clients.emit(
|
|
||||||
event.relation.id,
|
|
||||||
event.relation.name,
|
|
||||||
service_eps,
|
|
||||||
event.relation.data[event.relation.app]['region'],
|
|
||||||
event.relation.app.name)
|
|
||||||
|
|
||||||
def _on_identity_service_relation_broken(self, event):
|
|
||||||
"""Handle IdentityService broken."""
|
|
||||||
logging.debug("IdentityServiceProvides on_departed")
|
|
||||||
# TODO clear data on the relation
|
|
||||||
|
|
||||||
def set_identity_service_credentials(self, relation_name: int,
|
|
||||||
relation_id: str,
|
|
||||||
api_version: str,
|
|
||||||
auth_host: str,
|
|
||||||
auth_port: str,
|
|
||||||
auth_protocol: str,
|
|
||||||
internal_host: str,
|
|
||||||
internal_port: str,
|
|
||||||
internal_protocol: str,
|
|
||||||
service_host: str,
|
|
||||||
service_port: str,
|
|
||||||
service_protocol: str,
|
|
||||||
admin_domain: str,
|
|
||||||
admin_project: str,
|
|
||||||
admin_user: str,
|
|
||||||
service_domain: str,
|
|
||||||
service_password: str,
|
|
||||||
service_project: str,
|
|
||||||
service_user: str):
|
|
||||||
logging.debug("Setting identity_service connection information.")
|
|
||||||
for relation in self.framework.model.relations[relation_name]:
|
|
||||||
if relation.id == relation_id:
|
|
||||||
_identity_service_rel = relation
|
|
||||||
app_data = _identity_service_rel.data[self.charm.app]
|
|
||||||
app_data["api-version"] = api_version
|
|
||||||
app_data["auth-host"] = auth_host
|
|
||||||
app_data["auth-port"] = str(auth_port)
|
|
||||||
app_data["auth-protocol"] = auth_protocol
|
|
||||||
app_data["internal-host"] = internal_host
|
|
||||||
app_data["internal-port"] = str(internal_port)
|
|
||||||
app_data["internal-protocol"] = internal_protocol
|
|
||||||
app_data["service-host"] = service_host
|
|
||||||
app_data["service-port"] = str(service_port)
|
|
||||||
app_data["service-protocol"] = service_protocol
|
|
||||||
app_data["admin-domain-name"] = admin_domain.name
|
|
||||||
app_data["admin-domain-id"] = admin_domain.id
|
|
||||||
app_data["admin-project-name"] = admin_project.name
|
|
||||||
app_data["admin-project-id"] = admin_project.id
|
|
||||||
app_data["admin-user-name"] = admin_user.name
|
|
||||||
app_data["admin-user-id"] = admin_user.id
|
|
||||||
app_data["service-domain-name"] = service_domain.name
|
|
||||||
app_data["service-domain-id"] = service_domain.id
|
|
||||||
app_data["service-project-name"] = service_project.name
|
|
||||||
app_data["service-project-id"] = service_project.id
|
|
||||||
app_data["service-user-name"] = service_user.name
|
|
||||||
app_data["service-user-id"] = service_user.id
|
|
||||||
app_data["service-password"] = service_password
|
|
Loading…
Reference in New Issue