at 17.09-beta 7.1 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; with import ./common.nix {inherit lib;}; 4 5let 6 cfg = config.virtualisation.openstack.keystone; 7 keystoneConfTpl = pkgs.writeText "keystone.conf" '' 8 [DEFAULT] 9 admin_token = ${cfg.adminToken.pattern} 10 policy_file=${cfg.package}/etc/policy.json 11 12 [database] 13 14 connection = "mysql://${cfg.database.user}:${cfg.database.password.pattern}@${cfg.database.host}/${cfg.database.name}" 15 16 [paste_deploy] 17 config_file = ${cfg.package}/etc/keystone-paste.ini 18 19 ${cfg.extraConfig} 20 ''; 21 keystoneConf = "/var/lib/keystone/keystone.conf"; 22 23in { 24 options.virtualisation.openstack.keystone = { 25 package = mkOption { 26 type = types.package; 27 example = literalExample "pkgs.keystone"; 28 description = '' 29 Keystone package to use. 30 ''; 31 }; 32 33 enable = mkOption { 34 default = false; 35 type = types.bool; 36 description = '' 37 Enable Keystone, the OpenStack Identity Service 38 ''; 39 }; 40 41 extraConfig = mkOption { 42 default = ""; 43 type = types.lines; 44 description = '' 45 Additional text appended to <filename>keystone.conf</filename>, 46 the main Keystone configuration file. 47 ''; 48 }; 49 50 adminToken = mkSecretOption { 51 name = "adminToken"; 52 description = '' 53 This is the admin token used to boostrap keystone, 54 ie. to provision first resources. 55 ''; 56 }; 57 58 bootstrap = { 59 enable = mkOption { 60 default = false; 61 type = types.bool; 62 description = '' 63 Bootstrap the Keystone service by creating the service 64 tenant, an admin account and a public endpoint. This options 65 provides a ready-to-use admin account. This is only done at 66 the first Keystone execution by the systemd post start. 67 68 Note this option is a helper for setting up development or 69 testing environments. 70 ''; 71 }; 72 73 endpointPublic = mkOption { 74 type = types.str; 75 default = "http://localhost:5000/v2.0"; 76 description = '' 77 The public identity endpoint. The link <link 78 xlink:href="http://docs.openstack.org/liberty/install-guide-rdo/keystone-services.html"> 79 create keystone endpoint</link> provides more informations 80 about that. 81 ''; 82 }; 83 84 adminUsername = mkOption { 85 type = types.str; 86 default = "admin"; 87 description = '' 88 A keystone admin username. 89 ''; 90 }; 91 92 adminPassword = mkSecretOption { 93 name = "keystoneAdminPassword"; 94 description = '' 95 The keystone admin user's password. 96 ''; 97 }; 98 99 adminTenant = mkOption { 100 type = types.str; 101 default = "admin"; 102 description = '' 103 A keystone admin tenant name. 104 ''; 105 }; 106 }; 107 108 database = { 109 host = mkOption { 110 type = types.str; 111 default = "localhost"; 112 description = '' 113 Host of the database. 114 ''; 115 }; 116 117 name = mkOption { 118 type = types.str; 119 default = "keystone"; 120 description = '' 121 Name of the existing database. 122 ''; 123 }; 124 125 user = mkOption { 126 type = types.str; 127 default = "keystone"; 128 description = '' 129 The database user. The user must exist and has access to 130 the specified database. 131 ''; 132 }; 133 password = mkSecretOption { 134 name = "mysqlPassword"; 135 description = "The database user's password";}; 136 }; 137 }; 138 139 config = mkIf cfg.enable { 140 # Note: when changing the default, make it conditional on 141 # ‘system.stateVersion’ to maintain compatibility with existing 142 # systems! 143 virtualisation.openstack.keystone.package = mkDefault pkgs.keystone; 144 145 users.extraUsers = [{ 146 name = "keystone"; 147 group = "keystone"; 148 uid = config.ids.uids.keystone; 149 }]; 150 users.extraGroups = [{ 151 name = "keystone"; 152 gid = config.ids.gids.keystone; 153 }]; 154 155 systemd.services.keystone-all = { 156 description = "OpenStack Keystone Daemon"; 157 after = [ "network.target"]; 158 path = [ cfg.package pkgs.mysql pkgs.curl pkgs.pythonPackages.keystoneclient pkgs.gawk ]; 159 wantedBy = [ "multi-user.target" ]; 160 preStart = '' 161 mkdir -m 755 -p /var/lib/keystone 162 163 cp ${keystoneConfTpl} ${keystoneConf}; 164 chown keystone:keystone ${keystoneConf}; 165 chmod 640 ${keystoneConf} 166 167 ${replaceSecret cfg.database.password keystoneConf} 168 ${replaceSecret cfg.adminToken keystoneConf} 169 170 # Initialise the database 171 ${cfg.package}/bin/keystone-manage --config-file=${keystoneConf} db_sync 172 # Set up the keystone's PKI infrastructure 173 ${cfg.package}/bin/keystone-manage --config-file=${keystoneConf} pki_setup --keystone-user keystone --keystone-group keystone 174 ''; 175 postStart = optionalString cfg.bootstrap.enable '' 176 set -eu 177 # Wait until the keystone is available for use 178 count=0 179 while ! curl --fail -s http://localhost:35357/v2.0 > /dev/null 180 do 181 if [ $count -eq 30 ] 182 then 183 echo "Tried 30 times, giving up..." 184 exit 1 185 fi 186 187 echo "Keystone not yet started. Waiting for 1 second..." 188 count=$((count++)) 189 sleep 1 190 done 191 192 # We use the service token to create a first admin user 193 export OS_SERVICE_ENDPOINT=http://localhost:35357/v2.0 194 export OS_SERVICE_TOKEN=${getSecret cfg.adminToken} 195 196 # If the tenant service doesn't exist, we consider 197 # keystone is not initialized 198 if ! keystone tenant-get service 199 then 200 keystone tenant-create --name service 201 keystone tenant-create --name ${cfg.bootstrap.adminTenant} 202 keystone user-create --name ${cfg.bootstrap.adminUsername} --tenant ${cfg.bootstrap.adminTenant} --pass ${getSecret cfg.bootstrap.adminPassword} 203 keystone role-create --name admin 204 keystone role-create --name Member 205 keystone user-role-add --tenant ${cfg.bootstrap.adminTenant} --user ${cfg.bootstrap.adminUsername} --role admin 206 keystone service-create --type identity --name keystone 207 ID=$(keystone service-get keystone | awk '/ id / { print $4 }') 208 keystone endpoint-create --region RegionOne --service $ID --publicurl ${cfg.bootstrap.endpointPublic} --adminurl http://localhost:35357/v2.0 --internalurl http://localhost:5000/v2.0 209 fi 210 ''; 211 serviceConfig = { 212 PermissionsStartOnly = true; # preStart must be run as root 213 TimeoutStartSec = "600"; # 10min for initial db migrations 214 User = "keystone"; 215 Group = "keystone"; 216 ExecStart = "${cfg.package}/bin/keystone-all --config-file=${keystoneConf}"; 217 }; 218 }; 219 }; 220}