charm-keystone/hooks/keystone-hooks

151 lines
5.5 KiB
Python
Executable File

#!/usr/bin/python
import sys
from utils import *
config = config_get()
packages = "keystone python-mysqldb pwgen"
service = "keystone"
# used to verify joined services are valid openstack components.
# this should reflect the current "core" components of openstack
# and be expanded as we add support for them as a distro
valid_services = {
"nova": {
"type": "compute",
"desc": "Nova Compute Service"
},
"glance": {
"type": "image",
"desc": "Glance Image Service"
},
"swift": {
"type": "storage",
"desc": "Swift Object Storage Service"
}
}
def install_hook():
if config["keystone-release"] != "distro":
setup_ppa(config["keystone-release"])
execute("apt-get update", die=True)
execute("apt-get -y install %s" % packages, die=True, echo=True)
keystone_conf_update("keystone-admin-role",
config["keystone-admin-role"])
keystone_conf_update("keystone-service-admin-role",
config["keystone-service-admin-role"])
keystone_conf_update("service_port", config["service-port"])
keystone_conf_update("admin_port", config["admin-port"])
execute("service keystone restart", echo=True)
ensure_initial_admin(config)
def db_joined():
relation_data = { "database": config["database"],
"username": config["database-user"],
"hostname": config["hostname"] }
relation_set(relation_data)
def db_changed():
relation_data = relation_get(["private-address", "password"])
if len(relation_data) != 2:
juju_log("private-address or password not set. Peer not ready, exit 0")
exit(0)
keystone_conf_update("sql_connection",
"mysql://%s:%s@%s/%s" %
(config["database-user"],
relation_data["password"],
relation_data["private-address"],
config["database"]))
execute("service keystone restart", echo=True)
# both keystone restart and manager do database migrations on new databases
# sleep to avoid a race + migration errors
execute("sleep 2")
ensure_initial_admin(config)
def identity_joined():
""" Do nothing until we get information about requested service """
pass
def identity_changed():
""" A service has advertised its API endpoints, create an entry in the
service catalog. """
options = ["service", "region", "public_url", "admin_url", "internal_url"]
relation_data = relation_get(options)
if len(relation_data) != len(options):
juju_log("Missing relation data. Peer not ready, exit 0")
exit(0)
# If we do not support the service advertised on the other end of relation
# return a token of -1
if relation_data["service"] not in valid_services.keys():
juju_log("WARN: Invalid service requested: '%s'" % relation_data["service"])
realtion_set({ "admin_token": -1 })
return
import manager
service = relation_data["service"]
service_type = valid_services[service]["type"]
desc = valid_services[service]["desc"]
create_service_entry(manager, service, service_type, desc)
create_endpoint_template(manager, relation_data["region"], service,
relation_data["public_url"],
relation_data["admin_url"],
relation_data["internal_url"])
token = generate_admin_token(manager, config)
# we return a token and information about our API endpoints
relation_data = {
"admin_token": token,
"service_host": config["hostname"],
"service_port": config["service-port"],
"auth_host": config["hostname"],
"auth_port": config["admin-port"]
}
relation_set(relation_data)
def keystone_joined():
"""
The keystone-service relations exist specifically for horizon. Instead of
a token and entry in the service catalog (like other services), it requires
a token and a role. It doesn't expose any endpoint that keystone needs to
care about, thus it relates to this unit via its own service relation.
"""
pass
def keystone_changed():
""" Horizon will request a default role, we create it and return a
token
"""
import manager
options = ["role"]
relation_data = relation_get(options)
if len(relation_data) != len(options):
juju_log("Missing relation data. Peer not ready, exit 0")
exit(0)
# create the requested admin role
create_role(manager, relation_data["role"], config["admin-user"])
token = generate_admin_token(manager, config)
# Return token and API ports. Let horizon find our hostname via
# 'relation-get private-address'
relation_data = {
"service_port": config["service-port"],
"auth_port": config["admin-port"],
"admin_token": token
}
relation_set(relation_data)
hooks = {
"install": install_hook,
"shared-db-relation-joined": db_joined,
"shared-db-relation-changed": db_changed,
"identity-service-relation-joined": identity_joined,
"identity-service-relation-changed": identity_changed,
"keystone-service-relation-joined": keystone_joined,
"keystone-service-relation-changed": keystone_changed
}
# keystone-hooks gets called by symlink corresponding to the requested relation
# hook.
arg0 = sys.argv[0].split("/").pop()
if arg0 not in hooks.keys():
error_out("Unsupported hook: %s" % arg0)
hooks[arg0]()