[openstack-dev] Shared containers in Swift with Keystone

Pete Zaitcev zaitcev at redhat.com
Wed Mar 13 04:08:53 UTC 2013


I have a change outstanding in Gerrit right now that adds Keystone
support to functional tests. It seems very straightforward, but
for some reason tests of shared containers fail when ran against
Keystone (obviously they work with tempauth). Chmouel told me that
this should work, but I just cannot seem to figure it out.

I wrote a shell script that reproduces the issue, so it's decoupled
from my patch to .functests. Here:

#!/bin/sh
#
# this needs keystone(1), from python-keystoneclient

use_keystone=0

# tempauth
turl=http://kvm-ni.zaitcev.lan:8080/auth/v1.0

# Keystone
kurl=http://kvm-ichi.zaitcev.lan:5000/v2.0
keyst="keystone --os-auth-url $kurl"

surl=http://kvm-rei.zaitcev.lan:8080/v1/AUTH_

split_ten_tok_k () {
  while read a1 k a2 v a3; do
    if [ "$k" = tenant_id ]; then
      ten=$v
    fi
    if [ "$k" = id ]; then
      tok=$v
    fi
  done
  echo $ten $tok
}

split_ten_surl_s () {
  # Using IFS=: ends returning extra whitespace, but caller deals with it.
  while IFS=: read k v; do
    if [ "$k" = X-Storage-Url ]; then
      surl=$v
    fi
    if [ "$k" = X-Auth-Token ]; then
      tok=$v
    fi
  done
  echo "$surl" "$tok"
}

if [ $use_keystone \!= 0 ]; then

  t=$($keyst --os-tenant-name test --os-username tester --os-password testing token-get | split_ten_tok_k)
  ten1=$(echo $t | awk '{print $1}')
  tok1=$(echo $t | awk '{print $2}')
  surl1=$surl$ten1

  t=$($keyst --os-tenant-name test2 --os-username tester2 --os-password testing2 token-get | split_ten_tok_k)
  ten2=$(echo $t | awk '{print $1}')
  tok2=$(echo $t | awk '{print $2}')
  surl2=$surl$ten2

else

  t=$(curl -s -i -H 'X-Storage-User: test:tester' -H 'X-Storage-Pass: testing' $turl | tr -d '\015' | split_ten_surl_s)
  surl1=$(echo $t | awk '{print $1}')
  tok1=$(echo $t | awk '{print $2}')

  t=$(curl -s -i -H 'X-Storage-User: test2:tester2' -H 'X-Storage-Pass: testing2' $turl | tr -d '\015' | split_ten_surl_s)
  surl2=$(echo $t | awk '{print $1}')
  tok2=$(echo $t | awk '{print $2}')

fi

echo surl $surl1 token $tok1
echo surl $surl2 token $tok2

#curl -v -X DELETE -H "X-Auth-Token: $tok1" $surl1/testcont
curl -v -X PUT -H "X-Auth-Token: $tok1" $surl1/testcont
# tempauth 201 Created or 202 Accepted
# Keystone 202 Accepted <--- existing container

## Verify that PUT dropped the ACL
#curl -v -X HEAD -H "X-Auth-Token: $tok1" $surl1/testcont

curl -v  -H "X-Auth-Token: $tok2" $surl1/testcont
# tempauth 403 Forbidden
# HTTP/1.1 403 Forbidden

curl -v -X POST -H "X-Auth-Token: $tok1" -H "X-Container-Read: test2:tester2" $surl1/testcont
#> X-Auth-Token: AUTH_tk3e8a5479460e4d398dba78a3783c8e8c
#> X-Container-Write: test2:tester2
# tempauth 204 No Content
# Keystone 204 No Content

curl -v  -H "X-Auth-Token: $tok2" $surl1/testcont
# Keystone 403 Forbidden <====== problem


What am I doing wrong? Or, if anyone actually succeeded creating
shared containers, what did you do to add users and roles?

Thanks
-- Pete

P.S. Here's a script to populate Keystone:

#!/bin/sh

set -e
set -x

dbfile=/var/lib/keystone/keystone.sqlite
# External Swift URL base
swurl=http://kvm-rei.zaitcev.lan:8080
#swurl=https://simbelmyne.zaitcev.lan
# Proxy host - not used for anything, points to Swift proxy or admin node
pxhost=kvm-rei.zaitcev.lan
# Authentication URL points to $auhost
auhost=kvm-rei.zaitcev.lan

ATOK=a8dmintoken
#MURL=
keystone="keystone --endpoint http://localhost:35357/v2.0 --token=$ATOK"

# XXX This grep is not very discriminating against commented lines.
grep $dbfile /etc/keystone/keystone.conf > /dev/null
if [ \! $? ]; then
  echo "$dbfile not in /etc/keystone/keystone.conf, aborting" >&2
  exit 1
fi
if [ -f $dbfile ]; then
  echo "$dbfile exists, aborting" >&2
  exit 1
fi
keystone-manage db_sync
if [ \! -f $dbfile ]; then
  echo "$dbfile not created, aborting" >&2
  exit 1
fi
chown keystone $dbfile

# XXX requires
#  systemctl stop openstack-keystone.service
#  /bin/rm /var/lib/keystone/keystone.sqlite
systemctl start openstack-keystone.service
sleep 5

function get_id () {
    # echo $("$@" | grep ' id ' | awk '{print $4}')
    "$@" | grep ' id ' | awk '{print $4}'
}

# We need a known TID if we ever want to keep AUTH_xxx stable.
#TID=$(get_id $keystone tenant-create --name=admten)
TID=ea15004eb664450dae0a3302d98fd28b
echo "{\"tenant\": {\"name\":\"admten\", \"description\":null, \"enabled\":true, \"id\":\"$TID\"}}" | curl -H "Content-Type: application/json" -H "x-auth-token: $ATOK" -X POST -T - http://$auhost:35357/v2.0/tenants

# tenants necessary for functional tests
TID1=t1
echo "{\"tenant\": {\"name\":\"test\", \"description\":null, \"enabled\":true, \"id\":\"$TID1\"}}" | curl -H "Content-Type: application/json" -H "x-auth-token: $ATOK" -X POST -T - http://$auhost:35357/v2.0/tenants
TID2=t2
echo "{\"tenant\": {\"name\":\"test2\", \"description\":null, \"enabled\":true, \"id\":\"$TID2\"}}" | curl -H "Content-Type: application/json" -H "x-auth-token: $ATOK" -X POST -T - http://$auhost:35357/v2.0/tenants

AUID=$(get_id $keystone user-create --name=admin --pass=admpass --tenant_id=$TID)
ZUID=$(get_id $keystone user-create --name=zaitcev --pass=keypass --tenant_id=$TID)
# $keystone tenant-create --name=admten
# $keystone user-create --name=admin --pass=admpass --default_tenant=admten
# $keystone user-create --name=zaitcev --pass=keypass --default_tenant=admten

T1UID=$(get_id $keystone user-create --name=tester --pass=testing --tenant_id=$TID1)
T2UID=$(get_id $keystone user-create --name=tester2 --pass=testing2 --tenant_id=$TID2)
T3UID=$(get_id $keystone user-create --name=tester3 --pass=testing3 --tenant_id=$TID1)

## The Admin is used for testing.
ARID=$(get_id $keystone role-create --name=Admin)
$keystone user-role-add --user_id $AUID --role_id $ARID --tenant_id $TID
$keystone user-role-add --user_id $ZUID --role_id $ARID --tenant_id $TID

## The Admin and KeystoneAdmin are set in keystone.conf.
KRID=$(get_id $keystone role-create --name=KeystoneAdmin)
$keystone user-role-add --user_id $AUID --role_id $KRID --tenant_id $TID
$keystone user-role-add --user_id $ZUID --role_id $KRID --tenant_id $TID

TRID=$(get_id $keystone role-create --name=TestUser)
# XXX TestUser has to be in ACL or else it's 403
#        referrers, roles = swift_acl.parse_acl(getattr(req, 'acl', None))

## Wait a moment, role names are global across whole Keystone?
$keystone user-role-add --user_id $T1UID --role_id $ARID --tenant_id $TID1
$keystone user-role-add --user_id $T2UID --role_id $ARID --tenant_id $TID2
$keystone user-role-add --user_id $T3UID --role_id $TRID --tenant_id $TID1

# The Keystone service must be created, or else some Swift clients
# blow up, even though they do not use it for anything. Those that do
# not blow up report a bogus authentication failure.

KSID=$(get_id $keystone service-create --name=keystone --type="identity" --description="Keystone Identity Service")

$keystone endpoint-create --region RegionOne  --service_id "$KSID" \
  --publicurl http://$auhost:5000/v2.0 \
  --internalurl http://$auhost:5000/v2.0 \
  --adminurl http://$auhost:35357/v2.0

# Now create Swift service.

#keystone-manage service add swift storage "Swift Object Storage Service"
SSID=$(get_id $keystone service-create --name=swift --type="object-store" --description="Swift Service")

$keystone endpoint-create --region RegionOne --service_id "$SSID" \
  --publicurl $swurl/v1/'AUTH_$(tenant_id)s' \
  --adminurl http://$pxhost:8080/v1.0/ \
  --internalurl http://$pxhost:8080/v1/'AUTH_$(tenant_id)s'


Sorry if I'm asking to look into the broken code, but this is a better
kind of documentation of what is happening precisely.



More information about the OpenStack-dev mailing list