mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-02-21 03:25:36 +00:00
nixos/keystone: init at liberty version
This commit introduces a nixos module for the Openstack Keystone service. It also provides a optional bootstrap step that creates some basic initial resources (tenants, endpoints,...). The provided test starts Keystone by enabling bootstrapping and checks if user creation works well. This commit is based on initial works made by domenkozar.
This commit is contained in:
parent
656cc3acaf
commit
415c9ff90b
@ -280,6 +280,7 @@
|
||||
stanchion = 262;
|
||||
riak-cs = 263;
|
||||
infinoted = 264;
|
||||
keystone = 265;
|
||||
|
||||
# When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399!
|
||||
|
||||
@ -530,6 +531,7 @@
|
||||
stanchion = 262;
|
||||
riak-cs = 263;
|
||||
infinoted = 264;
|
||||
keystone = 265;
|
||||
|
||||
# When adding a gid, make sure it doesn't match an existing
|
||||
# uid. Users and groups with the same name should have equal
|
||||
|
@ -631,4 +631,5 @@
|
||||
./virtualisation/vmware-guest.nix
|
||||
./virtualisation/xen-dom0.nix
|
||||
./virtualisation/xe-guest-utilities.nix
|
||||
./virtualisation/openstack/keystone.nix
|
||||
]
|
||||
|
191
nixos/modules/virtualisation/openstack/keystone.nix
Normal file
191
nixos/modules/virtualisation/openstack/keystone.nix
Normal file
@ -0,0 +1,191 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.virtualisation.openstack.keystone;
|
||||
keystoneConf = pkgs.writeText "keystone.conf" ''
|
||||
[DEFAULT]
|
||||
admin_token = ${cfg.adminToken}
|
||||
policy_file=${cfg.package}/etc/policy.json
|
||||
|
||||
[database]
|
||||
connection = ${cfg.databaseConnection}
|
||||
|
||||
[paste_deploy]
|
||||
config_file = ${cfg.package}/etc/keystone-paste.ini
|
||||
|
||||
${cfg.extraConfig}
|
||||
'';
|
||||
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.
|
||||
'';
|
||||
};
|
||||
|
||||
adminToken = mkOption {
|
||||
type = types.str;
|
||||
default = "mySuperToken";
|
||||
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.
|
||||
'';
|
||||
};
|
||||
|
||||
adminPassword = mkOption {
|
||||
type = types.str;
|
||||
default = "admin";
|
||||
description = ''
|
||||
The keystone admin user's password.
|
||||
'';
|
||||
};
|
||||
|
||||
adminTenant = mkOption {
|
||||
type = types.str;
|
||||
default = "admin";
|
||||
description = ''
|
||||
A keystone admin tenant name.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
databaseConnection = mkOption {
|
||||
type = types.str;
|
||||
default = mysql://keystone:keystone@localhost/keystone;
|
||||
description = ''
|
||||
The SQLAlchemy connection string to use to connect to the
|
||||
Keystone database.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
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";
|
||||
packages = [ mysql ];
|
||||
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
|
||||
# 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
|
||||
export OS_SERVICE_TOKEN=${cfg.adminToken}
|
||||
|
||||
# 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}
|
||||
keystone user-create --name ${cfg.bootstrap.adminUsername} --tenant ${cfg.bootstrap.adminTenant} --pass ${cfg.bootstrap.adminPassword}
|
||||
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}";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
53
nixos/tests/keystone.nix
Normal file
53
nixos/tests/keystone.nix
Normal file
@ -0,0 +1,53 @@
|
||||
{ system ? builtins.currentSystem }:
|
||||
|
||||
with import ../lib/testing.nix { inherit system; };
|
||||
with pkgs.lib;
|
||||
|
||||
let
|
||||
createKeystoneDb = pkgs.writeText "create-keystone-db.sql" ''
|
||||
create database keystone;
|
||||
GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'localhost' IDENTIFIED BY 'keystone';
|
||||
GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'%' IDENTIFIED BY 'keystone';
|
||||
'';
|
||||
# The admin keystone account
|
||||
adminOpenstackCmd = "OS_TENANT_NAME=admin OS_USERNAME=admin OS_PASSWORD=admin OS_AUTH_URL=http://localhost:5000/v3 OS_IDENTITY_API_VERSION=3 openstack";
|
||||
# The created demo keystone account
|
||||
demoOpenstackCmd = "OS_TENANT_NAME=demo OS_USERNAME=demo OS_PASSWORD=demo OS_AUTH_URL=http://localhost:5000/v3 OS_IDENTITY_API_VERSION=3 openstack";
|
||||
|
||||
in makeTest {
|
||||
machine =
|
||||
{ config, pkgs, ... }:
|
||||
{
|
||||
services.mysql.enable = true;
|
||||
services.mysql.initialScript = createKeystoneDb;
|
||||
|
||||
virtualisation = {
|
||||
openstack.keystone.enable = true;
|
||||
openstack.keystone.bootstrap.enable = true;
|
||||
|
||||
memorySize = 2096;
|
||||
diskSize = 4 * 1024;
|
||||
};
|
||||
|
||||
environment.systemPackages = with pkgs.pythonPackages; with pkgs; [
|
||||
openstackclient
|
||||
];
|
||||
};
|
||||
|
||||
testScript =
|
||||
''
|
||||
$machine->waitForUnit("keystone-all.service");
|
||||
|
||||
# Verify that admin ccount is working
|
||||
$machine->succeed("${adminOpenstackCmd} token issue");
|
||||
|
||||
# Try to create a new user
|
||||
$machine->succeed("${adminOpenstackCmd} project create --domain default --description 'Demo Project' demo");
|
||||
$machine->succeed("${adminOpenstackCmd} user create --domain default --password demo demo");
|
||||
$machine->succeed("${adminOpenstackCmd} role create user");
|
||||
$machine->succeed("${adminOpenstackCmd} role add --project demo --user demo user");
|
||||
|
||||
# Verify this new account is working
|
||||
$machine->succeed("${demoOpenstackCmd} token issue");
|
||||
'';
|
||||
}
|
Loading…
Reference in New Issue
Block a user