* 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 |