* Creates account rc files for all tenant user
* Able to create new accounts
* The rc files contains certificates for image bundle
* euca related steps can be simpler in the future
Change-Id: I917bffb64e09a5d85c84cde45777c49eaca65e64
| ... | ... |
@@ -1672,6 +1672,17 @@ if is_service_enabled heat; then |
| 1672 | 1672 |
start_heat |
| 1673 | 1673 |
fi |
| 1674 | 1674 |
|
| 1675 |
+# Create account rc files |
|
| 1676 |
+# ======================= |
|
| 1677 |
+ |
|
| 1678 |
+# Creates source able script files for easier user switching. |
|
| 1679 |
+# This step also creates certificates for tenants and users, |
|
| 1680 |
+# which is helpful in image bundle steps. |
|
| 1681 |
+ |
|
| 1682 |
+if is_service_enabled nova && is_service_enabled key; then |
|
| 1683 |
+ $TOP_DIR/tools/create_userrc.sh -PA --target-dir $TOP_DIR/accrc |
|
| 1684 |
+fi |
|
| 1685 |
+ |
|
| 1675 | 1686 |
|
| 1676 | 1687 |
# Install Images |
| 1677 | 1688 |
# ============== |
| 1678 | 1689 |
new file mode 100755 |
| ... | ... |
@@ -0,0 +1,254 @@ |
| 0 |
+#!/usr/bin/env bash |
|
| 1 |
+ |
|
| 2 |
+#Warning: This script just for development purposes |
|
| 3 |
+ |
|
| 4 |
+ACCOUNT_DIR=./accrc |
|
| 5 |
+ |
|
| 6 |
+display_help() |
|
| 7 |
+{
|
|
| 8 |
+cat <<EOF |
|
| 9 |
+ |
|
| 10 |
+usage: $0 <options..> |
|
| 11 |
+ |
|
| 12 |
+This script creates certificates and sourcable rc files per tenant/user. |
|
| 13 |
+ |
|
| 14 |
+Target account directory hierarchy: |
|
| 15 |
+target_dir-| |
|
| 16 |
+ |-cacert.pem |
|
| 17 |
+ |-tenant1-name| |
|
| 18 |
+ | |- user1 |
|
| 19 |
+ | |- user1-cert.pem |
|
| 20 |
+ | |- user1-pk.pem |
|
| 21 |
+ | |- user2 |
|
| 22 |
+ | .. |
|
| 23 |
+ |-tenant2-name.. |
|
| 24 |
+ .. |
|
| 25 |
+ |
|
| 26 |
+Optional Arguments |
|
| 27 |
+-P include password to the rc files; with -A it assume all users password is the same |
|
| 28 |
+-A try with all user |
|
| 29 |
+-u <username> create files just for the specified user |
|
| 30 |
+-C <tanent_name> create user and tenant, the specifid tenant will be the user's tenant |
|
| 31 |
+-r <name> when combined with -C and the (-u) user exists it will be the user's tenant role in the (-C)tenant (default: Member) |
|
| 32 |
+-p <userpass> password for the user |
|
| 33 |
+--os-username <username> |
|
| 34 |
+--os-password <admin password> |
|
| 35 |
+--os-tenant-name <tenant_name> |
|
| 36 |
+--os-tenant-id <tenant_id> |
|
| 37 |
+--os-auth-url <auth_url> |
|
| 38 |
+--target-dir <target_directory> |
|
| 39 |
+--skip-tenant <tenant-name> |
|
| 40 |
+--debug |
|
| 41 |
+ |
|
| 42 |
+Example: |
|
| 43 |
+$0 -AP |
|
| 44 |
+$0 -P -C mytenant -u myuser -p mypass |
|
| 45 |
+EOF |
|
| 46 |
+} |
|
| 47 |
+ |
|
| 48 |
+if ! options=$(getopt -o hPAp:u:r:C: -l os-username:,os-password:,os-tenant-name:,os-tenant-id:,os-auth-url:,target-dir:,skip-tenant:,help,debug -- "$@") |
|
| 49 |
+then |
|
| 50 |
+ #parse error |
|
| 51 |
+ display_help |
|
| 52 |
+ exit 1 |
|
| 53 |
+fi |
|
| 54 |
+eval set -- $options |
|
| 55 |
+ADDPASS="" |
|
| 56 |
+ |
|
| 57 |
+# The services users usually in the service tenant. |
|
| 58 |
+# rc files for service users, is out of scope. |
|
| 59 |
+# Supporting different tanent for services is out of scope. |
|
| 60 |
+SKIP_TENANT=",service," # tenant names are between commas(,) |
|
| 61 |
+MODE="" |
|
| 62 |
+ROLE=Member |
|
| 63 |
+USER_NAME="" |
|
| 64 |
+USER_PASS="" |
|
| 65 |
+while [ $# -gt 0 ] |
|
| 66 |
+do |
|
| 67 |
+ case "$1" in |
|
| 68 |
+ -h|--help) display_help; exit 0 ;; |
|
| 69 |
+ --os-username) export OS_USERNAME=$2; shift ;; |
|
| 70 |
+ --os-password) export OS_PASSWORD=$2; shift ;; |
|
| 71 |
+ --os-tenant-name) export OS_TENANT_NAME=$2; shift ;; |
|
| 72 |
+ --os-tenant-id) export OS_TENANT_ID=$2; shift ;; |
|
| 73 |
+ --skip-tenant) SKIP_TENANT="$SKIP_TENANT$2,"; shift ;; |
|
| 74 |
+ --os-auth-url) export OS_AUTH_URL=$2; shift ;; |
|
| 75 |
+ --target-dir) ACCOUNT_DIR=$2; shift ;; |
|
| 76 |
+ --debug) set -o xtrace ;; |
|
| 77 |
+ -u) MODE=${MODE:-one}; USER_NAME=$2; shift ;;
|
|
| 78 |
+ -p) USER_PASS=$2; shift ;; |
|
| 79 |
+ -A) MODE=all; ;; |
|
| 80 |
+ -P) ADDPASS="yes" ;; |
|
| 81 |
+ -C) MODE=create; TENANT=$2; shift ;; |
|
| 82 |
+ -r) ROLE=$2; shift ;; |
|
| 83 |
+ (--) shift; break ;; |
|
| 84 |
+ (-*) echo "$0: error - unrecognized option $1" >&2; display_help; exit 1 ;; |
|
| 85 |
+ (*) echo "$0: error - unexpected argument $1" >&2; display_help; exit 1 ;; |
|
| 86 |
+ esac |
|
| 87 |
+ shift |
|
| 88 |
+done |
|
| 89 |
+ |
|
| 90 |
+if [ -z "$OS_PASSWORD" ]; then |
|
| 91 |
+ if [ -z "$ADMIN_PASSWORD" ];then |
|
| 92 |
+ echo "The admin password is required option!" >&2 |
|
| 93 |
+ exit 2 |
|
| 94 |
+ else |
|
| 95 |
+ OS_PASSWORD=$ADMIN_PASSWORD |
|
| 96 |
+ fi |
|
| 97 |
+fi |
|
| 98 |
+ |
|
| 99 |
+if [ -z "$OS_TENANT_NAME" -a -z "$OS_TENANT_ID" ]; then |
|
| 100 |
+ export OS_TENANT_NAME=admin |
|
| 101 |
+fi |
|
| 102 |
+ |
|
| 103 |
+if [ -z "$OS_USERNAME" ]; then |
|
| 104 |
+ export OS_USERNAME=admin |
|
| 105 |
+fi |
|
| 106 |
+ |
|
| 107 |
+if [ -z "$OS_AUTH_URL" ]; then |
|
| 108 |
+ export OS_AUTH_URL=http://localhost:5000/v2.0/ |
|
| 109 |
+fi |
|
| 110 |
+ |
|
| 111 |
+USER_PASS=${USER_PASS:-$OS_PASSWORD}
|
|
| 112 |
+USER_NAME=${USER_NAME:-$OS_USERNAME}
|
|
| 113 |
+ |
|
| 114 |
+if [ -z "$MODE" ]; then |
|
| 115 |
+ echo "You must specify at least -A or -u parameter!" >&2 |
|
| 116 |
+ echo |
|
| 117 |
+ display_help |
|
| 118 |
+ exit 3 |
|
| 119 |
+fi |
|
| 120 |
+ |
|
| 121 |
+export -n SERVICE_TOKEN SERVICE_ENDPOINT OS_SERVICE_TOKEN OS_SERVICE_ENDPOINT |
|
| 122 |
+ |
|
| 123 |
+EC2_URL=http://localhost:8773/service/Cloud |
|
| 124 |
+S3_URL=http://localhost:3333 |
|
| 125 |
+ |
|
| 126 |
+ec2=`keystone endpoint-get --service ec2 | awk '/\|[[:space:]]*ec2.publicURL/ {print $4}'`
|
|
| 127 |
+[ -n "$ec2" ] && EC2_URL=$ec2 |
|
| 128 |
+ |
|
| 129 |
+s3=`keystone endpoint-get --service s3 | awk '/\|[[:space:]]*s3.publicURL/ {print $4}'`
|
|
| 130 |
+[ -n "$s3" ] && S3_URL=$s3 |
|
| 131 |
+ |
|
| 132 |
+ |
|
| 133 |
+mkdir -p "$ACCOUNT_DIR" |
|
| 134 |
+ACCOUNT_DIR=`readlink -f "$ACCOUNT_DIR"` |
|
| 135 |
+EUCALYPTUS_CERT=$ACCOUNT_DIR/cacert.pem |
|
| 136 |
+mv "$EUCALYPTUS_CERT" "$EUCALYPTUS_CERT.old" &>/dev/null |
|
| 137 |
+if ! nova x509-get-root-cert "$EUCALYPTUS_CERT"; then |
|
| 138 |
+ echo "Failed to update the root certificate: $EUCALYPTUS_CERT" >&2 |
|
| 139 |
+ mv "$EUCALYPTUS_CERT.old" "$EUCALYPTUS_CERT" &>/dev/null |
|
| 140 |
+fi |
|
| 141 |
+ |
|
| 142 |
+ |
|
| 143 |
+function add_entry(){
|
|
| 144 |
+ local user_id=$1 |
|
| 145 |
+ local user_name=$2 |
|
| 146 |
+ local tenant_id=$3 |
|
| 147 |
+ local tenant_name=$4 |
|
| 148 |
+ local user_passwd=$5 |
|
| 149 |
+ |
|
| 150 |
+ # The admin user can see all user's secret AWS keys, it does not looks good |
|
| 151 |
+ local line=`keystone ec2-credentials-list --user_id $user_id | grep -E "^\\|[[:space:]]*($tenant_name|$tenant_id)[[:space:]]*\\|" | head -n 1` |
|
| 152 |
+ if [ -z "$line" ]; then |
|
| 153 |
+ keystone ec2-credentials-create --user-id $user_id --tenant-id $tenant_id 1>&2 |
|
| 154 |
+ line=`keystone ec2-credentials-list --user_id $user_id | grep -E "^\\|[[:space:]]*($tenant_name|$tenant_id)[[:space:]]*\\|" | head -n 1` |
|
| 155 |
+ fi |
|
| 156 |
+ local ec2_access_key ec2_secret_key |
|
| 157 |
+ read ec2_access_key ec2_secret_key <<< `echo $line | awk '{print $4 " " $6 }'`
|
|
| 158 |
+ mkdir -p "$ACCOUNT_DIR/$tenant_name" |
|
| 159 |
+ local rcfile="$ACCOUNT_DIR/$tenant_name/$user_name" |
|
| 160 |
+ # The certs subject part are the tenant ID "dash" user ID, but the CN should be the first part of the DN |
|
| 161 |
+ # Generally the subject DN parts should be in reverse order like the Issuer |
|
| 162 |
+ # The Serial does not seams correctly marked either |
|
| 163 |
+ local ec2_cert="$rcfile-cert.pem" |
|
| 164 |
+ local ec2_private_key="$rcfile-pk.pem" |
|
| 165 |
+ # Try to preserve the original file on fail (best effort) |
|
| 166 |
+ mv "$ec2_private_key" "$ec2_private_key.old" &>/dev/null |
|
| 167 |
+ mv "$ec2_cert" "$ec2_cert.old" &>/dev/null |
|
| 168 |
+ # It will not create certs when the password is incorrect |
|
| 169 |
+ if ! nova --os-password "$user_passwd" --os-username "$user_name" --os-tenant-name "$tenant_name" x509-create-cert "$ec2_private_key" "$ec2_cert"; then |
|
| 170 |
+ mv "$ec2_private_key.old" "$ec2_private_key" &>/dev/null |
|
| 171 |
+ mv "$ec2_cert.old" "$ec2_cert" &>/dev/null |
|
| 172 |
+ fi |
|
| 173 |
+ cat >"$rcfile" <<EOF |
|
| 174 |
+# you can source this file |
|
| 175 |
+export EC2_ACCESS_KEY=$ec2_access_key |
|
| 176 |
+export EC2_SECRET_KEY=$ec2_secret_key |
|
| 177 |
+export EC2_URL=$EC2_URL |
|
| 178 |
+export S3_URL=$S3_URL |
|
| 179 |
+# OpenStack USER ID = $user_id |
|
| 180 |
+export OS_USERNAME="$user_name" |
|
| 181 |
+# Openstack Tenant ID = $tenant_id |
|
| 182 |
+export OS_TENANT_NAME="$tenant_name" |
|
| 183 |
+export OS_AUTH_URL="$OS_AUTH_URL" |
|
| 184 |
+export EC2_CERT="$ec2_cert" |
|
| 185 |
+export EC2_PRIVATE_KEY="$ec2_private_key" |
|
| 186 |
+export EC2_USER_ID=42 #not checked by nova (can be a 12-digit id) |
|
| 187 |
+export EUCALYPTUS_CERT="$ACCOUNT_DIR/cacert.pem" |
|
| 188 |
+export NOVA_CERT="$ACCOUNT_DIR/cacert.pem" |
|
| 189 |
+EOF |
|
| 190 |
+ if [ -n "$ADDPASS" ]; then |
|
| 191 |
+ echo "export OS_PASSWORD=\"$user_passwd\"" >>"$rcfile" |
|
| 192 |
+ fi |
|
| 193 |
+} |
|
| 194 |
+ |
|
| 195 |
+#admin users expected |
|
| 196 |
+function create_or_get_tenant(){
|
|
| 197 |
+ local tenant_name=$1 |
|
| 198 |
+ local tenant_id=`keystone tenant-list | awk '/\|[[:space:]]*'"$tenant_name"'[[:space:]]*\|.*\|/ {print $2}'`
|
|
| 199 |
+ if [ -n "$tenant_id" ]; then |
|
| 200 |
+ echo $tenant_id |
|
| 201 |
+ else |
|
| 202 |
+ keystone tenant-create --name "$tenant_name" | awk '/\|[[:space:]]*id[[:space:]]*\|.*\|/ {print $4}'
|
|
| 203 |
+ fi |
|
| 204 |
+} |
|
| 205 |
+ |
|
| 206 |
+function create_or_get_role(){
|
|
| 207 |
+ local role_name=$1 |
|
| 208 |
+ local role_id=`keystone role-list| awk '/\|[[:space:]]*'"$role_name"'[[:space:]]*\|/ {print $2}'`
|
|
| 209 |
+ if [ -n "$role_id" ]; then |
|
| 210 |
+ echo $role_id |
|
| 211 |
+ else |
|
| 212 |
+ keystone tenant-create --name "$role_name" |awk '/\|[[:space:]]*id[[:space:]]*\|.*\|/ {print $4}'
|
|
| 213 |
+ fi |
|
| 214 |
+} |
|
| 215 |
+ |
|
| 216 |
+# Provides empty string when the user does not exists |
|
| 217 |
+function get_user_id(){
|
|
| 218 |
+ local user_name=$1 |
|
| 219 |
+ keystone user-list | awk '/^\|[^|]*\|[[:space:]]*'"$user_name"'[[:space:]]*\|.*\|/ {print $2}'
|
|
| 220 |
+} |
|
| 221 |
+ |
|
| 222 |
+if [ $MODE != "create" ]; then |
|
| 223 |
+# looks like I can't ask for all tenant related to a specified user |
|
| 224 |
+ for tenant_id_at_name in `keystone tenant-list | awk 'BEGIN {IGNORECASE = 1} /true[[:space:]]*\|$/ {print $2 "@" $4}'`; do
|
|
| 225 |
+ read tenant_id tenant_name <<< `echo "$tenant_id_at_name" | sed 's/@/ /'` |
|
| 226 |
+ if echo $SKIP_TENANT| grep -q ",$tenant_name,"; then |
|
| 227 |
+ continue; |
|
| 228 |
+ fi |
|
| 229 |
+ for user_id_at_name in `keystone user-list --tenant-id $tenant_id | awk 'BEGIN {IGNORECASE = 1} /true[[:space:]]*\|[^|]*\|$/ {print $2 "@" $4}'`; do
|
|
| 230 |
+ read user_id user_name <<< `echo "$user_id_at_name" | sed 's/@/ /'` |
|
| 231 |
+ if [ $MODE = one -a "$user_name" != "$USER_NAME" ]; then |
|
| 232 |
+ continue; |
|
| 233 |
+ fi |
|
| 234 |
+ add_entry "$user_id" "$user_name" "$tenant_id" "$tenant_name" "$USER_PASS" |
|
| 235 |
+ done |
|
| 236 |
+ done |
|
| 237 |
+else |
|
| 238 |
+ tenant_name=$TENANT |
|
| 239 |
+ tenant_id=`create_or_get_tenant "$TENANT"` |
|
| 240 |
+ user_name=$USER_NAME |
|
| 241 |
+ user_id=`get_user_id $user_name` |
|
| 242 |
+ if [ -z "$user_id" ]; then |
|
| 243 |
+ #new user |
|
| 244 |
+ user_id=`keystone user-create --name "$user_name" --tenant-id "$tenant_id" --pass "$USER_PASS" --email "$user_name@example.com" | awk '/\|[[:space:]]*id[[:space:]]*\|.*\|/ {print $4}'`
|
|
| 245 |
+ #The password is in the cmd line. It is not a good thing |
|
| 246 |
+ add_entry "$user_id" "$user_name" "$tenant_id" "$tenant_name" "$USER_PASS" |
|
| 247 |
+ else |
|
| 248 |
+ #new role |
|
| 249 |
+ role_id=`create_or_get_role "$ROLE"` |
|
| 250 |
+ keystone user-role-add --user-id "$user_id" --tenant-id "$tenant_id" --role-id "$role_id" |
|
| 251 |
+ add_entry "$user_id" "$user_name" "$tenant_id" "$tenant_name" "$USER_PASS" |
|
| 252 |
+ fi |
|
| 253 |
+fi |