Revert "Switch to using v1 cloud_credentials"
This reverts commit c2c6d588c78b7701f6ca8e6dfffa9b81a88c5b25. Reason for revert: I misunderstood and v0 Identity credentials actually supersedes v1 cloud credentials Change-Id: Ia985e8c147d92ef593b785d18a1c31132d9b1551
This commit is contained in:
parent
73ce780a1d
commit
c6246a22e6
@ -977,10 +977,10 @@ class IdentityCredentialsRequiresHandler(RelationHandler):
|
|||||||
|
|
||||||
def setup_event_handler(self) -> ops.charm.Object:
|
def setup_event_handler(self) -> ops.charm.Object:
|
||||||
"""Configure event handlers for identity-credentials relation."""
|
"""Configure event handlers for identity-credentials relation."""
|
||||||
import charms.keystone_k8s.v1.cloud_credentials as cloud_credentials
|
import charms.keystone_k8s.v0.identity_credentials as identity_credentials
|
||||||
|
|
||||||
logger.debug("Setting up the cloud-credentials event handler")
|
logger.debug("Setting up the identity-credentials event handler")
|
||||||
credentials_service = cloud_credentials.CloudCredentialsRequires(
|
credentials_service = identity_credentials.IdentityCredentialsRequires(
|
||||||
self.charm,
|
self.charm,
|
||||||
self.relation_name,
|
self.relation_name,
|
||||||
)
|
)
|
||||||
|
@ -1,451 +0,0 @@
|
|||||||
"""CloudCredentialsProvides and Requires module.
|
|
||||||
|
|
||||||
|
|
||||||
This library contains the Requires and Provides classes for handling
|
|
||||||
the cloud_credentials interface.
|
|
||||||
|
|
||||||
Import `CloudCredentialsRequires` in your charm, with the charm object and the
|
|
||||||
relation name:
|
|
||||||
- self
|
|
||||||
- "cloud_credentials"
|
|
||||||
|
|
||||||
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.keystone_k8s.v0.cloud_credentials import CloudCredentialsRequires
|
|
||||||
|
|
||||||
class CloudCredentialsClientCharm(CharmBase):
|
|
||||||
def __init__(self, *args):
|
|
||||||
super().__init__(*args)
|
|
||||||
# CloudCredentials Requires
|
|
||||||
self.cloud_credentials = CloudCredentialsRequires(
|
|
||||||
self, "cloud_credentials",
|
|
||||||
service = "my-service"
|
|
||||||
internal_url = "http://internal-url"
|
|
||||||
public_url = "http://public-url"
|
|
||||||
admin_url = "http://admin-url"
|
|
||||||
region = "region"
|
|
||||||
)
|
|
||||||
self.framework.observe(
|
|
||||||
self.cloud_credentials.on.connected, self._on_cloud_credentials_connected)
|
|
||||||
self.framework.observe(
|
|
||||||
self.cloud_credentials.on.ready, self._on_cloud_credentials_ready)
|
|
||||||
self.framework.observe(
|
|
||||||
self.cloud_credentials.on.goneaway, self._on_cloud_credentials_goneaway)
|
|
||||||
|
|
||||||
def _on_cloud_credentials_connected(self, event):
|
|
||||||
'''React to the CloudCredentials connected event.
|
|
||||||
|
|
||||||
This event happens when n CloudCredentials relation is added to the
|
|
||||||
model before credentials etc have been provided.
|
|
||||||
'''
|
|
||||||
# Do something before the relation is complete
|
|
||||||
pass
|
|
||||||
|
|
||||||
def _on_cloud_credentials_ready(self, event):
|
|
||||||
'''React to the CloudCredentials ready event.
|
|
||||||
|
|
||||||
The CloudCredentials interface will use the provided config for the
|
|
||||||
request to the identity server.
|
|
||||||
'''
|
|
||||||
# CloudCredentials Relation is ready. Do something with the completed relation.
|
|
||||||
pass
|
|
||||||
|
|
||||||
def _on_cloud_credentials_goneaway(self, event):
|
|
||||||
'''React to the CloudCredentials goneaway event.
|
|
||||||
|
|
||||||
This event happens when an CloudCredentials relation is removed.
|
|
||||||
'''
|
|
||||||
# CloudCredentials Relation has goneaway. shutdown services or suchlike
|
|
||||||
pass
|
|
||||||
```
|
|
||||||
"""
|
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
from ops.framework import (
|
|
||||||
StoredState,
|
|
||||||
EventBase,
|
|
||||||
ObjectEvents,
|
|
||||||
EventSource,
|
|
||||||
Object,
|
|
||||||
)
|
|
||||||
from ops.model import (
|
|
||||||
Relation,
|
|
||||||
SecretNotFoundError,
|
|
||||||
)
|
|
||||||
|
|
||||||
# The unique Charmhub library identifier, never change it
|
|
||||||
LIBID = "a5d96cc2686c47eea554ce2210c2d24e"
|
|
||||||
|
|
||||||
# Increment this major API version when introducing breaking changes
|
|
||||||
LIBAPI = 1
|
|
||||||
|
|
||||||
# Increment this PATCH version before using `charmcraft publish-lib` or reset
|
|
||||||
# to 0 if you are raising the major API version
|
|
||||||
LIBPATCH = 1
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
class CloudCredentialsConnectedEvent(EventBase):
|
|
||||||
"""CloudCredentials connected Event."""
|
|
||||||
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class CloudCredentialsReadyEvent(EventBase):
|
|
||||||
"""CloudCredentials ready for use Event."""
|
|
||||||
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class CloudCredentialsGoneAwayEvent(EventBase):
|
|
||||||
"""CloudCredentials relation has gone-away Event"""
|
|
||||||
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class CloudCredentialsServerEvents(ObjectEvents):
|
|
||||||
"""Events class for `on`"""
|
|
||||||
|
|
||||||
connected = EventSource(CloudCredentialsConnectedEvent)
|
|
||||||
ready = EventSource(CloudCredentialsReadyEvent)
|
|
||||||
goneaway = EventSource(CloudCredentialsGoneAwayEvent)
|
|
||||||
|
|
||||||
|
|
||||||
class CloudCredentialsRequires(Object):
|
|
||||||
"""
|
|
||||||
CloudCredentialsRequires class
|
|
||||||
"""
|
|
||||||
|
|
||||||
on = CloudCredentialsServerEvents()
|
|
||||||
_stored = StoredState()
|
|
||||||
|
|
||||||
def __init__(self, charm, relation_name: str):
|
|
||||||
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_cloud_credentials_relation_joined,
|
|
||||||
)
|
|
||||||
self.framework.observe(
|
|
||||||
self.charm.on[relation_name].relation_changed,
|
|
||||||
self._on_cloud_credentials_relation_changed,
|
|
||||||
)
|
|
||||||
self.framework.observe(
|
|
||||||
self.charm.on[relation_name].relation_departed,
|
|
||||||
self._on_cloud_credentials_relation_changed,
|
|
||||||
)
|
|
||||||
self.framework.observe(
|
|
||||||
self.charm.on[relation_name].relation_broken,
|
|
||||||
self._on_cloud_credentials_relation_broken,
|
|
||||||
)
|
|
||||||
|
|
||||||
def _on_cloud_credentials_relation_joined(self, event):
|
|
||||||
"""CloudCredentials relation joined."""
|
|
||||||
logging.debug("CloudCredentials on_joined")
|
|
||||||
self.on.connected.emit()
|
|
||||||
self.request_credentials()
|
|
||||||
|
|
||||||
def _on_cloud_credentials_relation_changed(self, event):
|
|
||||||
"""CloudCredentials relation changed."""
|
|
||||||
logging.debug("CloudCredentials on_changed")
|
|
||||||
try:
|
|
||||||
self.on.ready.emit()
|
|
||||||
except (AttributeError, KeyError):
|
|
||||||
logger.exception('Error when emitting event')
|
|
||||||
|
|
||||||
def _on_cloud_credentials_relation_broken(self, event):
|
|
||||||
"""CloudCredentials relation broken."""
|
|
||||||
logging.debug("CloudCredentials on_broken")
|
|
||||||
self.on.goneaway.emit()
|
|
||||||
|
|
||||||
@property
|
|
||||||
def _cloud_credentials_rel(self) -> Relation:
|
|
||||||
"""The CloudCredentials 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._cloud_credentials_rel.data[self._cloud_credentials_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 credentials(self) -> str:
|
|
||||||
return self.get_remote_app_data('credentials')
|
|
||||||
|
|
||||||
@property
|
|
||||||
def username(self) -> str:
|
|
||||||
credentials_id = self.get_remote_app_data('credentials')
|
|
||||||
if not credentials_id:
|
|
||||||
return None
|
|
||||||
|
|
||||||
try:
|
|
||||||
credentials = self.charm.model.get_secret(id=credentials_id)
|
|
||||||
return credentials.get_content().get("username")
|
|
||||||
except SecretNotFoundError:
|
|
||||||
logger.warning(f"Secret {credentials_id} not found")
|
|
||||||
return None
|
|
||||||
|
|
||||||
@property
|
|
||||||
def password(self) -> str:
|
|
||||||
credentials_id = self.get_remote_app_data('credentials')
|
|
||||||
if not credentials_id:
|
|
||||||
return None
|
|
||||||
|
|
||||||
try:
|
|
||||||
credentials = self.charm.model.get_secret(id=credentials_id)
|
|
||||||
return credentials.get_content().get("password")
|
|
||||||
except SecretNotFoundError:
|
|
||||||
logger.warning(f"Secret {credentials_id} not found")
|
|
||||||
return None
|
|
||||||
|
|
||||||
@property
|
|
||||||
def project_name(self) -> str:
|
|
||||||
"""Return the project name."""
|
|
||||||
return self.get_remote_app_data('project-name')
|
|
||||||
|
|
||||||
@property
|
|
||||||
def project_id(self) -> str:
|
|
||||||
"""Return the project id."""
|
|
||||||
return self.get_remote_app_data('project-id')
|
|
||||||
|
|
||||||
@property
|
|
||||||
def user_domain_name(self) -> str:
|
|
||||||
"""Return the name of the user domain."""
|
|
||||||
return self.get_remote_app_data('user-domain-name')
|
|
||||||
|
|
||||||
@property
|
|
||||||
def user_domain_id(self) -> str:
|
|
||||||
"""Return the id of the user domain."""
|
|
||||||
return self.get_remote_app_data('user-domain-id')
|
|
||||||
|
|
||||||
@property
|
|
||||||
def project_domain_name(self) -> str:
|
|
||||||
"""Return the name of the project domain."""
|
|
||||||
return self.get_remote_app_data('project-domain-name')
|
|
||||||
|
|
||||||
@property
|
|
||||||
def project_domain_id(self) -> str:
|
|
||||||
"""Return the id of the project domain."""
|
|
||||||
return self.get_remote_app_data('project-domain-id')
|
|
||||||
|
|
||||||
@property
|
|
||||||
def region(self) -> str:
|
|
||||||
"""Return the region for the auth urls."""
|
|
||||||
return self.get_remote_app_data('region')
|
|
||||||
|
|
||||||
@property
|
|
||||||
def internal_endpoint(self) -> str:
|
|
||||||
"""Return the region for the internal auth url."""
|
|
||||||
return self.get_remote_app_data('internal-endpoint')
|
|
||||||
|
|
||||||
@property
|
|
||||||
def public_endpoint(self) -> str:
|
|
||||||
"""Return the region for the public auth url."""
|
|
||||||
return self.get_remote_app_data('public-endpoint')
|
|
||||||
|
|
||||||
def request_credentials(self) -> None:
|
|
||||||
"""Request credentials from the CloudCredentials server."""
|
|
||||||
if self.model.unit.is_leader():
|
|
||||||
logging.debug(f'Requesting credentials for {self.charm.app.name}')
|
|
||||||
app_data = self._cloud_credentials_rel.data[self.charm.app]
|
|
||||||
app_data['username'] = self.charm.app.name
|
|
||||||
|
|
||||||
|
|
||||||
class HasCloudCredentialsClientsEvent(EventBase):
|
|
||||||
"""Has CloudCredentialsClients Event."""
|
|
||||||
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class ReadyCloudCredentialsClientsEvent(EventBase):
|
|
||||||
"""CloudCredentialsClients Ready Event."""
|
|
||||||
|
|
||||||
def __init__(self, handle, relation_id, relation_name, username):
|
|
||||||
super().__init__(handle)
|
|
||||||
self.relation_id = relation_id
|
|
||||||
self.relation_name = relation_name
|
|
||||||
self.username = username
|
|
||||||
|
|
||||||
def snapshot(self):
|
|
||||||
return {
|
|
||||||
"relation_id": self.relation_id,
|
|
||||||
"relation_name": self.relation_name,
|
|
||||||
"username": self.username,
|
|
||||||
}
|
|
||||||
|
|
||||||
def restore(self, snapshot):
|
|
||||||
super().restore(snapshot)
|
|
||||||
self.relation_id = snapshot["relation_id"]
|
|
||||||
self.relation_name = snapshot["relation_name"]
|
|
||||||
self.username = snapshot["username"]
|
|
||||||
|
|
||||||
|
|
||||||
class CloudCredentialsClientsGoneAwayEvent(EventBase):
|
|
||||||
"""Has CloudCredentialsClientsGoneAwayEvent Event."""
|
|
||||||
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class CloudCredentialsClientEvents(ObjectEvents):
|
|
||||||
"""Events class for `on`"""
|
|
||||||
|
|
||||||
has_cloud_credentials_clients = EventSource(
|
|
||||||
HasCloudCredentialsClientsEvent
|
|
||||||
)
|
|
||||||
ready_cloud_credentials_clients = EventSource(
|
|
||||||
ReadyCloudCredentialsClientsEvent
|
|
||||||
)
|
|
||||||
cloud_credentials_clients_gone = EventSource(
|
|
||||||
CloudCredentialsClientsGoneAwayEvent
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class CloudCredentialsProvides(Object):
|
|
||||||
"""
|
|
||||||
CloudCredentialsProvides class
|
|
||||||
"""
|
|
||||||
|
|
||||||
on = CloudCredentialsClientEvents()
|
|
||||||
_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_cloud_credentials_relation_joined,
|
|
||||||
)
|
|
||||||
self.framework.observe(
|
|
||||||
self.charm.on[relation_name].relation_changed,
|
|
||||||
self._on_cloud_credentials_relation_changed,
|
|
||||||
)
|
|
||||||
self.framework.observe(
|
|
||||||
self.charm.on[relation_name].relation_broken,
|
|
||||||
self._on_cloud_credentials_relation_broken,
|
|
||||||
)
|
|
||||||
|
|
||||||
def _on_cloud_credentials_relation_joined(self, event):
|
|
||||||
"""Handle CloudCredentials joined."""
|
|
||||||
logging.debug("CloudCredentialsProvides on_joined")
|
|
||||||
self.on.has_cloud_credentials_clients.emit()
|
|
||||||
|
|
||||||
def _on_cloud_credentials_relation_changed(self, event):
|
|
||||||
"""Handle CloudCredentials changed."""
|
|
||||||
logging.debug("CloudCredentials on_changed")
|
|
||||||
REQUIRED_KEYS = ['username']
|
|
||||||
|
|
||||||
values = [
|
|
||||||
event.relation.data[event.relation.app].get(k)
|
|
||||||
for k in REQUIRED_KEYS
|
|
||||||
]
|
|
||||||
# Validate data on the relation
|
|
||||||
if all(values):
|
|
||||||
username = event.relation.data[event.relation.app]['username']
|
|
||||||
self.on.ready_cloud_credentials_clients.emit(
|
|
||||||
event.relation.id,
|
|
||||||
event.relation.name,
|
|
||||||
username,
|
|
||||||
)
|
|
||||||
|
|
||||||
def _on_cloud_credentials_relation_broken(self, event):
|
|
||||||
"""Handle CloudCredentials broken."""
|
|
||||||
logging.debug("CloudCredentialsProvides on_departed")
|
|
||||||
self.on.cloud_credentials_clients_gone.emit()
|
|
||||||
|
|
||||||
def set_cloud_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,
|
|
||||||
credentials: str,
|
|
||||||
project_name: str,
|
|
||||||
project_id: str,
|
|
||||||
user_domain_name: str,
|
|
||||||
user_domain_id: str,
|
|
||||||
project_domain_name: str,
|
|
||||||
project_domain_id: str,
|
|
||||||
region: str):
|
|
||||||
logging.debug("Setting cloud_credentials connection information.")
|
|
||||||
_cloud_credentials_rel = None
|
|
||||||
for relation in self.framework.model.relations[relation_name]:
|
|
||||||
if relation.id == relation_id:
|
|
||||||
_cloud_credentials_rel = relation
|
|
||||||
if not _cloud_credentials_rel:
|
|
||||||
# Relation has disappeared so don't send the data
|
|
||||||
return
|
|
||||||
app_data = _cloud_credentials_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["credentials"] = credentials
|
|
||||||
app_data["project-name"] = project_name
|
|
||||||
app_data["project-id"] = project_id
|
|
||||||
app_data["user-domain-name"] = user_domain_name
|
|
||||||
app_data["user-domain-id"] = user_domain_id
|
|
||||||
app_data["project-domain-name"] = project_domain_name
|
|
||||||
app_data["project-domain-id"] = project_domain_id
|
|
||||||
app_data["region"] = region
|
|
||||||
app_data["internal-endpoint"] = self.charm.internal_endpoint
|
|
||||||
app_data["public-endpoint"] = self.charm.public_endpoint
|
|
Loading…
x
Reference in New Issue
Block a user