151 lines
5.5 KiB
Python
Executable File
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]()
|