#!/bin/bash #CDMI Tools (v0.3) by Salvatore Pinto - 05.08.2013 function usage { echo "Usage: $0 -e [options] is the endpoint of the CDMI service. is the action to be performed on the storage. Possible actions are: auth Display auth information (for integration with other services) list List contents of the container [default action] stat Get info for the file (as CDMI metadata) publicurl Retreive object public url (for public data access) get Download file put Upload a file (needs -T switch in the arguments) post Update metadata (see post command options for the metadata list) delete Delete a file (or container) mkdir Create folder Generic options: -o | --output Redirect output to file --auth-file Local authorization file. Default authorization file is $_LOCAL_AUTH . This file cointains the service authorization data. See sample authorization file for more info -a | --auth Override authorization data (format shall be understandable by cURL command line). --cdmi-version Version of the CDMI standard to use (default $_CDMI_VERSION) --crl-update Update CRL before creating a new proxy. Recommended if fetch-crl is not enabled in the cron (ex. on Windows machines) --ca-path Use the following CA path for HTTPs certificates verification (default to /etc/grid-security/certificates if present) -k | --insecure Do not verify HTTPs certificate in the API calls (not recommended) put command: -T | --upload-file File to upload [mandatory] delete command: -r Enable recursive directory deletion post command: -m Add metadata features. Metadata format is pipe separated = . Allowed metadata is readacl Read permission for containers. Allowed values are '.r:*' or '.' writeacl Write permission for containers. Allowed values are '.r:*' or '.' weblist Listing of container contents in web format. Allowed values are 'true' or 'false' " exit 1 } function error { ec="$1" dsc="$2" if [[ -z "$dsc" ]]; then dsc="$ec" ec=255 fi [[ -z "$dsc" ]] && dsc="Unknow Error!!!" echo "ERROR: $dsc" 1>&2 exit $ec } #Default arguments _DEBUG=false _ENDPOINT= _PATH= _AUTH= _LOCAL_AUTH=$0.auth _ACTION= _POST_META= _CDMI_VERSION=1.0.1 _FILE_TO_UPLOAD= _FILE_OUTPUT= _RECURSIVE=false _CRL_UPDATE=false _CURL_OPTS= #Parse arguments [[ -z "$1" ]] && usage while [[ "$#" -gt 0 ]]; do case "$1" in -d | --debug) _DEBUG=true; shift 1 ;; -a | --auth) _AUTH="$2"; shift 2 ;; -A | --auth-file) _LOCAL_AUTH="$2"; shift 2 ;; -e | --endpoint) _ENDPOINT="${2%/}"; shift 2 ;; --cdmi-version) _CDMI_VERSION="$2"; shift 2 ;; -T | --upload-file) _FILE_TO_UPLOAD="$2"; shift 2 ;; -o | --output) _FILE_OUTPUT="$2"; shift 2 ;; -a | --action) _ACTION="$2"; shift 2 ;; -k | --insecure) _CURL_OPTS="$_CURL_OPTS -k"; shift 1;; --ca-path) _CURL_OPTS="$_CURL_OPTS --capath $_CURL_OPTS"; shift 1;; -r) _RECURSIVE=true; shift 1 ;; -m) _POST_META="$2"; shift 2 ;; --crl-update) _CRL_UPDATE=true; shift 1 ;; -h | --help) usage ;; *) if [[ -z "$_ACTION" ]]; then _ACTION="$1"; shift 1; else _PATH="${_PATH%/}/$1"; shift 1; fi ;; esac done #Redirect output to a file if required if [[ -n "$_FILE_OUTPUT" ]]; then exec 1>$_FILE_OUTPUT fi #If prensent, load authorization file if [[ -n "$_LOCAL_AUTH" && -e "$_LOCAL_AUTH" ]]; then $_DEBUG && echo "[DEBUG] Loading authorization file" >&2 source "$_LOCAL_AUTH" #If present, not expired and related to the same endpoint, load token cache file infomration _LOCAL_AUTH_CACHE="${_LOCAL_AUTH}.cache" if [[ -e "$_LOCAL_AUTH_CACHE" ]]; then CACHE_EXPIRE_TIME="`sed -n 's/^CACHE_EXPIRE_TIME="\\(.*\\)"/\1/p' $_LOCAL_AUTH_CACHE`" CACHE_RELATED_ENDPOINT="`sed -n 's/^CACHE_RELATED_ENDPOINT="\\(.*\\)"/\1/p' $_LOCAL_AUTH_CACHE`" if [[ -n "$CACHE_EXPIRE_TIME" && `date +%s` -lt `date -d "$CACHE_EXPIRE_TIME" +%s` && "$CACHE_RELATED_ENDPOINT" == "$_ENDPOINT" ]]; then $_DEBUG && echo "[DEBUG] Loading cached authorization file data" >&2 source $_LOCAL_AUTH_CACHE fi fi fi #Authorization $_DEBUG && echo "[DEBUG] Initializing authorization" >&2 if [[ "$AUTH_TYPE" == "basic" ]]; then #HTTP basic authentication $_DEBUG && echo "[DEBUG] using HTTP basic authentication: $AUTH_USERNAME / ***********" >&2 AUTH="Authorization: Basic `echo -n "$AUTH_USERNAME:$AUTH_PASSWORD" | base64`" elif [[ "$AUTH_TYPE" == "token" ]]; then #HTTP token authentication $_DEBUG && echo "[DEBUG] using HTTP token authentication: $AUTH_TOKEN" >&2 AUTH="X-Auth-Token: $AUTH_TOKEN" elif [[ "$AUTH_TYPE" == "keystone-basic" ]]; then #Keystone authentication (with username/password) $_DEBUG && echo "[DEBUG] using keystone (username/password) authentication" >&2 if [[ -n "$AUTH_TOKEN" ]]; then #Token is still valid, just use it $_DEBUG && echo "[DEBUG] valid token found ( $AUTH_TOKEN ). using it." >&2 AUTH="X-Auth-Token: $AUTH_TOKEN" else #Token is not valid anymore, re-generate it $_DEBUG && echo "[DEBUG] no valid token found, creating a new one." >&2 error 127 "Not jet implemented" fi elif [[ "$AUTH_TYPE" == "keystone-voms" || "$AUTH_TYPE" == "keystone-myproxy" ]]; then #Keystone authentication (with VOMS proxy certificate) $_DEBUG && echo "[DEBUG] using keystone (VOMS) authentication" >&2 #Set CA PATH if [[ "${_CURL_OPTS//--capath/}" == "$_CURL_OPTS" ]]; then [[ -z "$AUTH_KEYSTONE_CAPATH" ]] && AUTH_KEYSTONE_CAPATH=/etc/grid-security/certificates _CURL_OPTS="$_CURL_OPTS --capath $AUTH_KEYSTONE_CAPATH" fi if [[ "$_ACTION" == "auth" ]]; then #If action is auth, to recreate a new token AUTH_TOKEN= fi #Get token (if not defined already from the cache) if [[ -n "$AUTH_TOKEN" ]]; then #Token is still valid, just use it $_DEBUG && echo "[DEBUG] valid token found in the cache ( $AUTH_TOKEN ). using it." >&2 AUTH="X-Auth-Token: $AUTH_TOKEN" else #Token is not valid anymore, re-generate it $_DEBUG && echo "[DEBUG] no valid token found, creating a new one." >&2 if $_CRL_UPDATE; then #Run fetch-crl if specified, this is required for VOMS tools $_DEBUG && echo "[DEBUG] Updating CRLs..." >&2 fetch-crl &>/dev/null fi #Get proxy credential, if any if [[ -n "$AUTH_KEYSTONE_PROXY" ]]; then $_DEBUG && echo "[DEBUG] checking proxy validity." >&2 #Check proxy certificate validity and VO name voms-proxy-info -file "$AUTH_KEYSTONE_PROXY" -exists [[ $? -ne 0 ]] && error 192 "Specified proxy certificate is not valid anymore. Please generate a new proxy or specify the user certificate." VONAME="`voms-proxy-info -file "$AUTH_KEYSTONE_PROXY" -all | gawk '{if($1=="VO")print $3}'`" [[ $? -ne 0 ]] && error 192 "Specified proxy certificate is not valid anymore. Please generate a new proxy or specify the user certificate." #Check the proxy VO extensions validity (if specified) if [[ -n "$AUTH_KEYSTONE_VOMSEXT" && "$VONAME" != "$AUTH_KEYSTONE_VOMSEXT" ]]; then #No valid VOMS extensions provided with the proxy, re-create a new proxy $_DEBUG && echo "[DEBUG] No valid VOMS extensions provided in the proxy. Create a new temporary proxy for autentication." >&2 TMP_OPTS="-rfc -n" [[ -n "$X509_VOMSES" ]] && TMP_OPTS="$TMP_OPTS -vomses $X509_VOMSES" export X509_USER_PROXY="$AUTH_KEYSTONE_PROXY" voms-proxy-init -voms "$AUTH_KEYSTONE_VOMSEXT" -out "$AUTH_KEYSTONE_PROXY.vomsext" $TMP_OPTS &>/dev/null if [[ $? -ne 0 ]]; then rm -f "$AUTH_KEYSTONE_PROXY.vomsext" voms-proxy-init -voms "$AUTH_KEYSTONE_VOMSEXT" -out "$AUTH_KEYSTONE_PROXY.vomsext" $TMP_OPTS -debug error 192 "Failed to generate temporary user proxy." fi AUTH_KEYSTONE_PROXY=$AUTH_KEYSTONE_PROXY.vomsext export X509_USER_PROXY= fi elif [[ -n "$AUTH_KEYSTONE_CERT" && -n "$AUTH_KEYSTONE_KEY" && -n "$AUTH_KEYSTONE_VOMSEXT" ]]; then $_DEBUG && echo "[DEBUG] generating temporary proxy." >&2 AUTH_KEYSTONE_PROXY="$0.tempproxy" #Generate a proxy from the certificate (with VOMS extensions) TMP_OPTS="-rfc" [[ -n "$X509_VOMSES" ]] && TMP_OPTS="$TMP_OPTS -vomses $X509_VOMSES" voms-proxy-init -cert "$AUTH_KEYSTONE_CERT" -key "$AUTH_KEYSTONE_KEY" -voms "$AUTH_KEYSTONE_VOMSEXT" -out "$AUTH_KEYSTONE_PROXY" $TMP_OPTS &>/dev/null if [[ $? -ne 0 ]]; then voms-proxy-info -file "$AUTH_KEYSTONE_PROXY" -exists if [[ $? -ne 0 ]]; then rm -f "$AUTH_KEYSTONE_PROXY" voms-proxy-init -cert "$AUTH_KEYSTONE_CERT" -key "$AUTH_KEYSTONE_KEY" -voms "$AUTH_KEYSTONE_VOMSEXT" -out "$AUTH_KEYSTONE_PROXY" $TMP_OPTS -debug error 192 "Failed to generate temporary user proxy." fi fi elif [[ -n "$AUTH_MYPROXY_SERVER" && -n "$AUTH_USERNAME" && -n "$AUTH_KEYSTONE_VOMSEXT" ]]; then $_DEBUG && echo "[DEBUG] generating temporary proxy from myproxy." >&2 AUTH_KEYSTONE_PROXY="$0.tempproxy" #Generate a proxy from the myproxy (with VOMS extensions) AUTH_MYPROXY_SERVER="-s ${AUTH_MYPROXY_SERVER/:/ -p }" if [[ -n "$AUTH_PASSWORD" ]]; then echo "$AUTH_PASSWORD" | myproxy-logon -S $AUTH_MYPROXY_SERVER -l $AUTH_USERNAME -o "${AUTH_KEYSTONE_PROXY}m" > /dev/null res="${PIPESTATUS[1]}" else myproxy-logon $AUTH_MYPROXY_SERVER -l $AUTH_USERNAME -o "${AUTH_KEYSTONE_PROXY}m" res=$? fi if [[ $res -ne 0 ]]; then error 193 "Failed to get proxy from myproxy. Are credentials wrong?" fi #Sign the proxy with VOMS extensions TMP_OPTS="-rfc -n" [[ -n "$X509_VOMSES" ]] && TMP_OPTS="$TMP_OPTS -vomses $X509_VOMSES" export X509_USER_PROXY="${AUTH_KEYSTONE_PROXY}m" voms-proxy-init -voms "$AUTH_KEYSTONE_VOMSEXT" -out "$AUTH_KEYSTONE_PROXY" $TMP_OPTS &>/dev/null if [[ $? -ne 0 ]]; then voms-proxy-info -file "$AUTH_KEYSTONE_PROXY" -exists if [[ $? -ne 0 ]]; then rm -f "$AUTH_KEYSTONE_PROXY" voms-proxy-init -voms "$AUTH_KEYSTONE_VOMSEXT" -out "$AUTH_KEYSTONE_PROXY" $TMP_OPTS -debug error 192 "Failed to sign temporary user proxy." fi fi rm -f "${AUTH_KEYSTONE_PROXY}m" export X509_USER_PROXY= else error 194 "Please setup a proxy or certificate for Keystone authentication and VOMS extension in the bcdmi.auth file" fi #Get Keystone URI if [[ -z "$AUTH_KEYSTONE_URI" ]]; then #Try to get the keystone url from the endpoint AUTH_KEYSTONE_URI=`curl $_CURL_OPTS -v -H "X-CDMI-Specification-Version: $_CDMI_VERSION" "${_ENDPOINT}" 2>&1 | sed -n "s|< www-authenticate *: *Keystone uri *= *[\"\\\']*\([^\"\\\']*\).*$|\1|Ip"` #Try to get the keystone URI for OpenStack CDMI implementation [[ -z "$AUTH_KEYSTONE_URI" ]] && AUTH_KEYSTONE_URI=`curl $_CURL_OPTS -v -H "X-CDMI-Specification-Version: $_CDMI_VERSION" "${_ENDPOINT%/AUTH_*}/AUTH_testauth" 2>&1 | sed -n "s|< www-authenticate *: *Keystone uri *= *[\"\\\']*\([^\"\\\']*\).*$|\1|Ip"` [[ -z "$AUTH_KEYSTONE_URI" ]] && AUTH_KEYSTONE_URI=`curl $_CURL_OPTS -v -H "X-CDMI-Specification-Version: $_CDMI_VERSION" "${_ENDPOINT%/cdmi/AUTH_*}/cdmi/AUTH_testauth" 2>&1 | sed -n "s|< www-authenticate *: *Keystone uri *= *[\"\\\']*\([^\"\\\']*\).*$|\1|Ip"` [[ -z "$AUTH_KEYSTONE_URI" ]] && error 197 "Impossible to get Keystone URI. Please specify a custom one in the autorization file." fi AUTH_KEYSTONE_URI="${AUTH_KEYSTONE_URI%/}"; AUTH_KEYSTONE_URI="${AUTH_KEYSTONE_URI%/v2.0}/v2.0" #Get tenant if [[ -z "$AUTH_KEYSTONE_TENANT" ]]; then #Tenant name if not specified, get tenants list $_DEBUG && echo "[DEBUG] tenant name not specified. getting unscoped token" >&2 TMPSTR="`curl $_CURL_OPTS -s -S -X POST "$AUTH_KEYSTONE_URI/tokens" -H 'Accept: application/json' -H 'Content-Type: application/json' -d '{"auth":{"voms":true}}' --cert "$AUTH_KEYSTONE_PROXY" --key "$AUTH_KEYSTONE_PROXY" --cacert "$AUTH_KEYSTONE_PROXY" | gawk 'BEGIN{RS="\\""}{if ($0=="expires") {getline;getline;gsub("T"," ",$0);gsub("Z","",$0);printf $0","}if($0=="id"){getline;getline;printf $0;exit}}'`" AUTH_TOKEN="${TMPSTR#*,}" [[ -z "$AUTH_TOKEN" ]] && error 201 "failed to get unscoped token. Are you sure your certificate VOMS extension can access the service?" AUTH="X-Auth-Token: $AUTH_TOKEN" #get default tenant name $_DEBUG && echo "[DEBUG] getting the tenants lists for the user via unskopen token" >&2 AUTH_KEYSTONE_TENANT=`curl $_CURL_OPTS -s -S "$AUTH_KEYSTONE_URI/tenants" -H "$AUTH" -H 'Accept: application/json' -H 'Content-Type: application/json' | gawk 'BEGIN{RS="\""}{if($0=="name"){getline;getline;printf $0","}}'` AUTH_KEYSTONE_TENANT=${AUTH_KEYSTONE_TENANT%,} if [[ "${AUTH_KEYSTONE_TENANT//,/}" != "$AUTH_KEYSTONE_TENANT" ]]; then #user belongs to more than one tenant, check to which tenants he can autenticate to with this proxy $_DEBUG && echo "[DEBUG] user belongs to more than one tenant, tryying to get the tenant associated to the VOMS signature" >&2 allowed_tenants= for tenant in ${AUTH_KEYSTONE_TENANT//,/ }; do TMPSTR="`curl $_CURL_OPTS -s -S -X POST "$AUTH_KEYSTONE_URI/tokens" -H 'Accept: application/json' -H 'Content-Type: application/json' -d '{"auth":{"voms":true,"tenantName":"'"$tenant"'"}}' --cert "$AUTH_KEYSTONE_PROXY" --key $AUTH_KEYSTONE_PROXY --cacert "$AUTH_KEYSTONE_PROXY" | gawk 'BEGIN{RS="\\""}{if ($0=="expires") {getline;getline;gsub("T"," ",$0);gsub("Z","",$0);printf $0","}if($0=="id"){getline;getline;printf $0;exit}}'`" AUTH_TOKEN="${TMPSTR#*,}" [[ -n "$AUTH_TOKEN" ]] && allowed_tenants="$allowed_tenants,$tenant" done AUTH_KEYSTONE_TENANT="${allowed_tenants#,}" if [[ "${AUTH_KEYSTONE_TENANT//,/}" != "$AUTH_KEYSTONE_TENANT" ]]; then if [[ "$_ACTION" == "auth" ]]; then AUTH_KEYSTONE_TENANT= else error 203 "User belong to more than one tenant. You need to specify one in the authorization file. Possible tenants are: $AUTH_KEYSTONE_TENANT . Use auth to get the details of the allowed tenants." fi fi $_DEBUG && echo "[DEBUG] Got default tenant (from VOMS signature): $AUTH_KEYSTONE_TENANT" >&2 else #user belong to only one tenant, using it as default $_DEBUG && echo "[DEBUG] Got default tenant: $AUTH_KEYSTONE_TENANT" >&2 fi fi if [[ -z "$AUTH_KEYSTONE_TENANT" ]]; then echo "WARNING: Failed to get a default tenant. You need to specify one in the authorization file. The list of allowed tenants is provided via the auth command." else #Request scoped token (and get as return the endpoint path also, if any) TMPSTR="`curl $_CURL_OPTS -s -S -X POST "$AUTH_KEYSTONE_URI/tokens" -H 'Accept: application/json' -H 'Content-Type: application/json' -d '{"auth":{"voms":true,"tenantName":"'"$AUTH_KEYSTONE_TENANT"'"}}' --cert "$AUTH_KEYSTONE_PROXY" --key $AUTH_KEYSTONE_PROXY --cacert "$AUTH_KEYSTONE_PROXY" | gawk -v e="$_ENDPOINT" 'BEGIN{RS="\\\""}{if ($0=="expires"){getline;getline;gsub("T"," ",$0);gsub("Z","",$0);expd=$0}if($0=="id"&&idd==""){getline;getline;idd=$0}if($0=="publicURL"){getline;getline;if($0~"^"e){gsub("^"e,"",$0);ptd=$0};}}END{if(idd!=""&&expd!="")print expd","idd","ptd}'`" AUTH_TOKEN_EXPIRE_TIME="${TMPSTR%%,*}" AUTH_TOKEN="${TMPSTR#*,}"; AUTH_TOKEN="${AUTH_TOKEN%,*}" AUTH_TOKEN_PATH="${TMPSTR##*,}" [[ -z "$AUTH_TOKEN" ]] && error 202 "failed to get scoped token for tenant $AUTH_KEYSTONE_TENANT" $_DEBUG && echo "[DEBUG] got scoped token $AUTH_TOKEN (expire on $AUTH_TOKEN_EXPIRE_TIME)." >&2 $_DEBUG && [[ -n "$AUTH_TOKEN_PATH" ]] && echo "[DEBUG] got additional endpoint scoped path: $AUTH_TOKEN_PATH" >&2 AUTH="X-Auth-Token: $AUTH_TOKEN" #Convert endpoint from SWIFT to CDMI interface (only for openstack, does nothing for other CDMI implementations) [[ "$AUTH_TOKEN_PATH" == "${AUTH_TOKEN_PATH#/v1/}" ]] || AUTH_TOKEN_PATH="/cdmi/${AUTH_TOKEN_PATH#/v1/}" #If the proxy is temporary, delete it [[ "$AUTH_KEYSTONE_PROXY" == "$0.tempproxy" ]] && rm -f "$0.tempproxy" fi #Save data to a cache. So you do not have to autenticate each time you perform a request. The cache file expires when the token expires if [[ -n "$_LOCAL_AUTH_CACHE" ]]; then $_DEBUG && echo "[DEBUG] saving authorization token to cache." >&2 cat << EOF > $_LOCAL_AUTH_CACHE #This cache file is automatically generated. It will expire on $AUTH_TOKEN_EXPIRE_TIME . Delete it if you have problems in the authentication. CACHE_EXPIRE_TIME="$AUTH_TOKEN_EXPIRE_TIME" CACHE_RELATED_ENDPOINT="$_ENDPOINT" AUTH_TOKEN="$AUTH_TOKEN" AUTH_TOKEN_PATH="$AUTH_TOKEN_PATH" AUTH_KEYSTONE_URI="$AUTH_KEYSTONE_URI" AUTH_KEYSTONE_TENANT="$AUTH_KEYSTONE_TENANT" EOF fi fi #If keystone defines a token path for the service, add it to the endpoint if [[ -n "$AUTH_TOKEN_PATH" ]]; then _ENDPOINT="${_ENDPOINT%/}/${AUTH_TOKEN_PATH#/}" fi elif [[ -n "$_AUTH" ]]; then $_DEBUG && echo "[DEBUG] Manual authorization string specified. Using it." >&2 AUTH="$_AUTH" else error 242 "No authorization method specified. Please setup a local authorization file." fi #Add the specified path to the endpoint, to get the object full URI _ENDPOINT="${_ENDPOINT%/}/${_PATH#/}" $_DEBUG && echo "[DEBUG] Performing query $_ACTION..." >&2 if [[ "$_ACTION" == "auth" ]]; then #Only display auth information (and tenants list) echo "Auth type: $AUTH_TYPE" echo "User auth header: ${AUTH#-H }" if [[ "$AUTH_TYPE" == "keystone-voms" || "$AUTH_TYPE" == "keystone-basic" || "$AUTH_TYPE" == "keystone-myproxy" ]]; then [[ -n "$AUTH_KEYSTONE_URI" ]] && echo "Keystone URI: $AUTH_KEYSTONE_URI" || echo "Keystone URI: (none)" [[ -n "$AUTH_KEYSTONE_TENANT" ]] && echo "Tenant associated: $AUTH_KEYSTONE_TENANT" || echo "Tenant associated: (none)" [[ -n "$AUTH_KEYSTONE_TENANT" && -n "$_ENDPOINT" ]] && echo "Tenant associated endpoint: $_ENDPOINT" || echo "Tenant associated endpoint: (none)" if [[ -n "$AUTH_KEYSTONE_URI" ]]; then echo "Tenants list:" echo "tenant name,tenant id,tenant description" curl $_CURL_OPTS -s -S "$AUTH_KEYSTONE_URI/tenants" -H "$AUTH" -H 'Accept: application/json' -H 'Content-Type: application/json' | gawk 'BEGIN{RS="\""}{if($0=="name"){getline;getline;tmn=$0;}if($0=="id"){getline;getline;tmid=$0;}if($0=="description"){getline;getline;tmd=$0;}if((tmn!="")&&(tmid!="")&&(tmd!="")){print tmn","tmid","tmd;tmn="";tmid="";tmd=""}}' fi fi elif [[ -z "$_ACTION" || "$_ACTION" == "list" ]]; then #List contents of the container curl $_CURL_OPTS -s -S "$_ENDPOINT" -H "$AUTH" -H "X-CDMI-Specification-Version: $_CDMI_VERSION" | gawk 'BEGIN{RS="\""}{if($0=="children"){while($0!~"]|}"){getline;if($0~"]|}")break;getline;gsub(/ /,"%20",$0);print $0}}}' elif [[ "$_ACTION" == "get" ]]; then #Get content of the file curl $_CURL_OPTS -s -S "$_ENDPOINT" -H "$AUTH" elif [[ "$_ACTION" == "put" ]]; then [[ -z "$_FILE_TO_UPLOAD" ]] && error 243 "You need to specify a file to upload." curl $_CURL_OPTS "$_ENDPOINT" -H "$AUTH" -H 'Content-Type: application/binary' -T "$_FILE_TO_UPLOAD" elif [[ "$_ACTION" == "stat" ]]; then curl $_CURL_OPTS -s -S "$_ENDPOINT" -H "X-CDMI-Specification-Version: $_CDMI_VERSION" -H "$AUTH" elif [[ "$_ACTION" == "publicurl" ]]; then echo "$_ENDPOINT" elif [[ "$_ACTION" == "delete" ]]; then if $_RECURSIVE; then if [[ "${_ENDPOINT%/}" == "$_ENDPOINT" ]]; then #This is not a folder, delete the file curl $_CURL_OPTS -s -S "$_ENDPOINT" -X DELETE -H "X-CDMI-Specification-Version: $_CDMI_VERSION" -H "$AUTH" else #This is a folder, list the contents and delete all the contents recursively for f in `curl $_CURL_OPTS -s -S "$_ENDPOINT" -H "$AUTH" -H "X-CDMI-Specification-Version: $_CDMI_VERSION" | gawk 'BEGIN{RS="\""}{if($0=="children"){while($0!~"]|}"){getline;if($0~"]|}")break;getline;gsub(/ /,"%20",$0);print $0}}}'`; do if [[ "${f%/}" == "$f" ]]; then curl $_CURL_OPTS -s -S "$_ENDPOINT$f" -X DELETE -H "X-CDMI-Specification-Version: $_CDMI_VERSION" -H "$AUTH" else $0 -r -e "$_ENDPOINT" delete $f fi done #Then delete the folder itself curl $_CURL_OPTS -s -S "$_ENDPOINT" -H "X-CDMI-Specification-Version: $_CDMI_VERSION" -X DELETE -H "$AUTH" fi else curl $_CURL_OPTS -s -S "$_ENDPOINT" -H "X-CDMI-Specification-Version: $_CDMI_VERSION" -X DELETE -H "$AUTH" fi elif [[ "$_ACTION" == "mkdir" ]]; then curl $_CURL_OPTS -X PUT "${_ENDPOINT%/}/" -H "X-CDMI-Specification-Version: $_CDMI_VERSION" -H "$AUTH" -H 'Content-Type: application/cdmi-container' -H 'Content-Length: 0' elif [[ "$_ACTION" == "post" ]]; then #WARNING. This uses SWIFT API, because there is still no CDMI ACL implementation in SWIFT _ENDPOINT="${_ENDPOINT/\/cdmi\///v1/}" #switch to SWIFT API for META in ${_POST_META//|/ }; do META_CODE="${META%%=*}" META_VALUE="${META#*=}" case "$META_CODE" in readacl) META_CODE="X-Container-Read" ;; writeacl) META_CODE="X-Container-Write" ;; weblist) META_CODE="X-Container-Meta-Web-Listings" ;; *) error 125 "Metadata code $META_CODE not valid" esac curl $_CURL_OPTS -s -S "$_ENDPOINT" -X POST -H "$AUTH" -H "$META_CODE: $META_VALUE" -H 'Accept-Encoding: identity' done else error 150 "Action $_ACTION is not recognized." fi exit 0