2016-12-04 21:02:49 +00:00
|
|
|
|
{ config, lib, pkgs, ... }:
|
|
|
|
|
|
2016-12-10 22:14:50 +00:00
|
|
|
|
with lib; with import ./common.nix {inherit lib;};
|
2016-12-04 21:02:49 +00:00
|
|
|
|
|
|
|
|
|
let
|
|
|
|
|
cfg = config.virtualisation.openstack.keystone;
|
2016-12-10 22:14:50 +00:00
|
|
|
|
keystoneConfTpl = pkgs.writeText "keystone.conf" ''
|
2016-12-04 21:02:49 +00:00
|
|
|
|
[DEFAULT]
|
2016-12-10 22:14:50 +00:00
|
|
|
|
admin_token = ${cfg.adminToken.pattern}
|
2016-12-04 21:02:49 +00:00
|
|
|
|
policy_file=${cfg.package}/etc/policy.json
|
|
|
|
|
|
|
|
|
|
[database]
|
2016-12-10 22:14:50 +00:00
|
|
|
|
|
|
|
|
|
connection = "mysql://${cfg.database.user}:${cfg.database.password.pattern}@${cfg.database.host}/${cfg.database.name}"
|
2016-12-04 21:02:49 +00:00
|
|
|
|
|
|
|
|
|
[paste_deploy]
|
|
|
|
|
config_file = ${cfg.package}/etc/keystone-paste.ini
|
|
|
|
|
|
|
|
|
|
${cfg.extraConfig}
|
|
|
|
|
'';
|
2016-12-10 22:14:50 +00:00
|
|
|
|
keystoneConf = "/var/lib/keystone/keystone.conf";
|
|
|
|
|
|
2016-12-04 21:02:49 +00:00
|
|
|
|
in {
|
|
|
|
|
options.virtualisation.openstack.keystone = {
|
|
|
|
|
package = mkOption {
|
|
|
|
|
type = types.package;
|
|
|
|
|
example = literalExample "pkgs.keystone";
|
|
|
|
|
description = ''
|
|
|
|
|
Keystone package to use.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
enable = mkOption {
|
|
|
|
|
default = false;
|
|
|
|
|
type = types.bool;
|
|
|
|
|
description = ''
|
|
|
|
|
Enable Keystone, the OpenStack Identity Service
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
extraConfig = mkOption {
|
|
|
|
|
default = "";
|
|
|
|
|
type = types.lines;
|
|
|
|
|
description = ''
|
|
|
|
|
Additional text appended to <filename>keystone.conf</filename>,
|
|
|
|
|
the main Keystone configuration file.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
2016-12-10 22:14:50 +00:00
|
|
|
|
adminToken = mkSecretOption {
|
|
|
|
|
name = "adminToken";
|
2016-12-04 21:02:49 +00:00
|
|
|
|
description = ''
|
|
|
|
|
This is the admin token used to boostrap keystone,
|
|
|
|
|
ie. to provision first resources.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
bootstrap = {
|
|
|
|
|
enable = mkOption {
|
|
|
|
|
default = false;
|
|
|
|
|
type = types.bool;
|
|
|
|
|
description = ''
|
|
|
|
|
Bootstrap the Keystone service by creating the service
|
|
|
|
|
tenant, an admin account and a public endpoint. This options
|
|
|
|
|
provides a ready-to-use admin account. This is only done at
|
|
|
|
|
the first Keystone execution by the systemd post start.
|
|
|
|
|
|
|
|
|
|
Note this option is a helper for setting up development or
|
|
|
|
|
testing environments.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
endpointPublic = mkOption {
|
|
|
|
|
type = types.str;
|
|
|
|
|
default = "http://localhost:5000/v2.0";
|
|
|
|
|
description = ''
|
|
|
|
|
The public identity endpoint. The link <link
|
|
|
|
|
xlink:href="http://docs.openstack.org/liberty/install-guide-rdo/keystone-services.html">
|
|
|
|
|
create keystone endpoint</link> provides more informations
|
|
|
|
|
about that.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
adminUsername = mkOption {
|
|
|
|
|
type = types.str;
|
|
|
|
|
default = "admin";
|
|
|
|
|
description = ''
|
|
|
|
|
A keystone admin username.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
2016-12-10 22:14:50 +00:00
|
|
|
|
adminPassword = mkSecretOption {
|
|
|
|
|
name = "keystoneAdminPassword";
|
2016-12-04 21:02:49 +00:00
|
|
|
|
description = ''
|
|
|
|
|
The keystone admin user's password.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
adminTenant = mkOption {
|
|
|
|
|
type = types.str;
|
|
|
|
|
default = "admin";
|
|
|
|
|
description = ''
|
|
|
|
|
A keystone admin tenant name.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
2016-12-10 22:14:50 +00:00
|
|
|
|
database = {
|
|
|
|
|
host = mkOption {
|
|
|
|
|
type = types.str;
|
|
|
|
|
default = "localhost";
|
|
|
|
|
description = ''
|
|
|
|
|
Host of the database.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
name = mkOption {
|
2016-12-04 21:02:49 +00:00
|
|
|
|
type = types.str;
|
2016-12-10 22:14:50 +00:00
|
|
|
|
default = "keystone";
|
2016-12-04 21:02:49 +00:00
|
|
|
|
description = ''
|
2016-12-10 22:14:50 +00:00
|
|
|
|
Name of the existing database.
|
2016-12-04 21:02:49 +00:00
|
|
|
|
'';
|
2016-12-10 22:14:50 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
user = mkOption {
|
|
|
|
|
type = types.str;
|
|
|
|
|
default = "keystone";
|
|
|
|
|
description = ''
|
|
|
|
|
The database user. The user must exist and has access to
|
|
|
|
|
the specified database.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
password = mkSecretOption {
|
|
|
|
|
name = "mysqlPassword";
|
|
|
|
|
description = "The database user's password";};
|
2016-12-04 21:02:49 +00:00
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
config = mkIf cfg.enable {
|
|
|
|
|
# Note: when changing the default, make it conditional on
|
|
|
|
|
# ‘system.stateVersion’ to maintain compatibility with existing
|
|
|
|
|
# systems!
|
|
|
|
|
virtualisation.openstack.keystone.package = mkDefault pkgs.keystone;
|
|
|
|
|
|
|
|
|
|
users.extraUsers = [{
|
|
|
|
|
name = "keystone";
|
|
|
|
|
group = "keystone";
|
|
|
|
|
uid = config.ids.uids.keystone;
|
|
|
|
|
}];
|
|
|
|
|
users.extraGroups = [{
|
|
|
|
|
name = "keystone";
|
|
|
|
|
gid = config.ids.gids.keystone;
|
|
|
|
|
}];
|
|
|
|
|
|
|
|
|
|
systemd.services.keystone-all = {
|
|
|
|
|
description = "OpenStack Keystone Daemon";
|
|
|
|
|
after = [ "network.target"];
|
|
|
|
|
path = [ cfg.package pkgs.mysql pkgs.curl pkgs.pythonPackages.keystoneclient pkgs.gawk ];
|
|
|
|
|
wantedBy = [ "multi-user.target" ];
|
|
|
|
|
preStart = ''
|
|
|
|
|
mkdir -m 755 -p /var/lib/keystone
|
2016-12-10 22:14:50 +00:00
|
|
|
|
|
|
|
|
|
cp ${keystoneConfTpl} ${keystoneConf};
|
|
|
|
|
chown keystone:keystone ${keystoneConf};
|
|
|
|
|
chmod 640 ${keystoneConf}
|
|
|
|
|
|
|
|
|
|
${replaceSecret cfg.database.password keystoneConf}
|
|
|
|
|
${replaceSecret cfg.adminToken keystoneConf}
|
|
|
|
|
|
2016-12-04 21:02:49 +00:00
|
|
|
|
# Initialise the database
|
|
|
|
|
${cfg.package}/bin/keystone-manage --config-file=${keystoneConf} db_sync
|
|
|
|
|
# Set up the keystone's PKI infrastructure
|
|
|
|
|
${cfg.package}/bin/keystone-manage --config-file=${keystoneConf} pki_setup --keystone-user keystone --keystone-group keystone
|
|
|
|
|
'';
|
|
|
|
|
postStart = optionalString cfg.bootstrap.enable ''
|
|
|
|
|
set -eu
|
|
|
|
|
# Wait until the keystone is available for use
|
|
|
|
|
count=0
|
|
|
|
|
while ! curl --fail -s http://localhost:35357/v2.0 > /dev/null
|
|
|
|
|
do
|
|
|
|
|
if [ $count -eq 30 ]
|
|
|
|
|
then
|
|
|
|
|
echo "Tried 30 times, giving up..."
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
echo "Keystone not yet started. Waiting for 1 second..."
|
|
|
|
|
count=$((count++))
|
|
|
|
|
sleep 1
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
# We use the service token to create a first admin user
|
|
|
|
|
export OS_SERVICE_ENDPOINT=http://localhost:35357/v2.0
|
2016-12-10 22:14:50 +00:00
|
|
|
|
export OS_SERVICE_TOKEN=${getSecret cfg.adminToken}
|
2016-12-04 21:02:49 +00:00
|
|
|
|
|
|
|
|
|
# If the tenant service doesn't exist, we consider
|
|
|
|
|
# keystone is not initialized
|
|
|
|
|
if ! keystone tenant-get service
|
|
|
|
|
then
|
|
|
|
|
keystone tenant-create --name service
|
|
|
|
|
keystone tenant-create --name ${cfg.bootstrap.adminTenant}
|
2016-12-10 22:14:50 +00:00
|
|
|
|
keystone user-create --name ${cfg.bootstrap.adminUsername} --tenant ${cfg.bootstrap.adminTenant} --pass ${getSecret cfg.bootstrap.adminPassword}
|
2016-12-04 21:02:49 +00:00
|
|
|
|
keystone role-create --name admin
|
|
|
|
|
keystone role-create --name Member
|
|
|
|
|
keystone user-role-add --tenant ${cfg.bootstrap.adminTenant} --user ${cfg.bootstrap.adminUsername} --role admin
|
|
|
|
|
keystone service-create --type identity --name keystone
|
|
|
|
|
ID=$(keystone service-get keystone | awk '/ id / { print $4 }')
|
|
|
|
|
keystone endpoint-create --region RegionOne --service $ID --publicurl ${cfg.bootstrap.endpointPublic} --adminurl http://localhost:35357/v2.0 --internalurl http://localhost:5000/v2.0
|
|
|
|
|
fi
|
|
|
|
|
'';
|
|
|
|
|
serviceConfig = {
|
|
|
|
|
PermissionsStartOnly = true; # preStart must be run as root
|
|
|
|
|
TimeoutStartSec = "600"; # 10min for initial db migrations
|
|
|
|
|
User = "keystone";
|
|
|
|
|
Group = "keystone";
|
|
|
|
|
ExecStart = "${cfg.package}/bin/keystone-all --config-file=${keystoneConf}";
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
}
|