Managing Access Keys on Huawei UDS - shawfdong/hyades GitHub Wiki
The Huawei Universal Distributed Storage (UDS) is a clone of Amazon S3 (Simple Storage Service). Huawei UDS provides storage through web services interfaces. To use any service on web, a user ID and password is required. The access key ID and secret access key serve as user ID and password to Huawei UDS.
On UDS, the access keys are managed by an Apache Geronimo server running on the active OMS (Operation Maintenance Server):
OMS01:~ # cat /opt/obs-V100R001C00SPC100/geronimo/version geronimo-jetty7-javaee5-2.2.1
The Apache Geronimo server appears to be listening on many ports[1]:
OMS01:~ # netstat -lnp | grep 19204 tcp 0 0 127.0.0.1:1099 :::* LISTEN 19204/java tcp 0 0 127.0.0.1:9998 :::* LISTEN 19204/java tcp 0 0 127.0.0.1:9999 :::* LISTEN 19204/java tcp 0 0 172.16.0.12:61616 :::* LISTEN 19204/java tcp 0 0 127.0.0.1:9009 :::* LISTEN 19204/java tcp 0 0 127.0.0.1:8083 :::* LISTEN 19204/java tcp 0 0 127.0.0.1:6743 :::* LISTEN 19204/java tcp 0 0 127.0.0.1:5719 :::* LISTEN 19204/java tcp 0 0 127.0.0.1:1527 :::* LISTEN 19204/java tcp 0 0 :::9443 :::* LISTEN 19204/java udp 0 0 :::44262 :::* 19204/java udp 0 0 :::54008 :::* 19204/java udp 0 0 :::59701 :::* 19204/java
The web application that manages access keys listens on TCP port 8083. It is located at /opt/obs-V100R001C00SPC100/geronimo/repository/default/poe/1.0/poe-1.0.car/.
The web application uses SOAP to exchange structured information with clients. The file /opt/obs-V100R001C00SPC100/geronimo/repository/default/poe/1.0/poe-1.0.car/WEB-INF/beans.xml indicates that there are 4 address endpoints (web services): /user, /srv, /aksk, & /ec. We can extract the WSDL (Web Services Description Language) description for those web services, as follows.
# curl -s http://127.0.0.1:8083/poe/user?wsdl | xmllint --format -NOTE we use the -s option to run curl in silent mode so that it doesn't show progress meter or error messages; we then use xmllint to pretty print the XML output.
# curl -s http://127.0.0.1:8083/poe/srv?wsdl | xmllint --format -
# curl -s http://127.0.0.1:8083/poe/aksk?wsdl | xmllint --format -
# curl -s http://127.0.0.1:8083/poe/ec?wsdl | xmllint --format -
To add a user, first create a file addUserWithAll.xml:
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:soap1="http://obs.huawei.com/soap/"> <soap:Header/> <soap:Body> <soap1:addUserWithAll> <userId>newton</userid> <userName>IsaacNewton</username> <email>[email protected]</email> <status>active</status> </soap1:adduserwithall> </soap:body> </soap:envelope>
Then run:
# curl -s -H "content-type: application/soap+xml" \ -d @addUserWithAll.xml http://127.0.0.1:8083/poe/user?wsdl \ | xmllint --format - | tee newton.xmlNOTE:
- -d @addUserWithAll.xml enables curl to send the content of addUserWithAll.xml in a POST request to the web application;
- -H "content-type: application/soap+xml" specifies the extra header to use when getting a web page[2]. It can be omitted.
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"> <soap:Body> <ns2:addUserWithAllResponse xmlns:ns2="http://obs.huawei.com/soap/"> <Result> <resultCode>0</resultcode> <resultDesc>add user, register all the service and create the ak/sk pair successfully!</resultdesc> <userinfo> <userId>newton</userid> <userName>IsaacNewton</username> <canoUserId>90E2BA2C3F640000013FCFE54D730001</canouserid> <email>[email protected]</email> <status>active</status> </userinfo> <serviceinfo> <serviceType>BASE</servicetype> <status>active</status> <createTime>1373582478793</createtime> </serviceinfo> <akskinfo> <ak>ABCDEF0123456789ABCD</ak> <sk>Wx/lb2T6UuJV9FcDiw/i/KcM2u4ZZZZ/z+VOnwpS</sk> <status>active</status> <createTime>1373582479013</createtime> </akskinfo> </result> </ns2:adduserwithallresponse> </soap:body> </soap:envelope>In this example, the access key ID is ABCDEF0123456789ABCD; and secret access key is Wx/lb2T6UuJV9FcDiw/i/KcM2u4ZZZZ/z+VOnwpS.
The above method creates a user with service and access keys in a single step. Alternatively, one can create a user without service and access keys; and then add service and access keys to the user in separate steps.
Create a file addUser.xml:
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:soap1="http://obs.huawei.com/soap/"> <soap:Header/> <soap:Body> <soap1:addUser> <userId>einstein</userid> <userName>AlbertEinstein</username> <email>[email protected]</email> <status>active</status> </soap1:adduser> </soap:body> </soap:envelope>
Make a SOAP request to add the user:
# curl -s -H "content-type: application/soap+xml" \ -d @addUser.xml http://127.0.0.1:8083/poe/user?wsdl \ | xmllint --format -
We get a SOAP response like the following (Note there is no serviceinfo or akskinfo ):
<?xml version="1.0"?> <soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"> <soap:Body> <ns2:addUserResponse xmlns:ns2="http://obs.huawei.com/soap/"> <Result> <resultCode>0</resultcode> <resultDesc>add user success</resultdesc> <userinfo> <userId>einstein</userid> <userName>AlbertEinstein</username> <canoUserId>90E2BA2C3F6400000140363CAE4F000B</canouserid> <email>[email protected]</email> <status>active</status> <createTime>1375299481167</createtime> </userinfo> </result> </ns2:adduserresponse> </soap:body> </soap:envelope>
Create a file addService.xml:
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:soap1="http://obs.huawei.com/soap/"> <soap:Header/> <soap:Body> <soap1:addService> <userId>einstein</userid> <serviceType>BASE</servicetype> <status>active</status> </soap1:addservice> </soap:body> </soap:envelope>
Make a SOAP request to add the service to the user:
# curl -s -H "content-type: application/soap+xml" \ -d @addService.xml http://127.0.0.1:8083/poe/srv?wsdl \ | xmllint --format
Create a file addAccountKeySecretKey.xml:
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:soap1="http://obs.huawei.com/soap/"> <soap:Header/> <soap:Body> <soap1:addAccountKeySecretKey> <userId>einstein</userid> <status>active</status> </soap1:addaccountkeysecretkey> </soap:body> </soap:envelope>
Make a SOAP request to add access keys to the user:
# curl -s -H "content-type: application/soap+xml" \ -d @addAccountKeySecretKey.xml http://127.0.0.1:8083/poe/aksk?wsdl \ | xmllint --format -
To query the user info, create a file queryUser.xml:
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:soap1="http://obs.huawei.com/soap/"> <soap:Header/> <soap:Body> <soap1:queryUser> <userId>einstein</userid> </soap1:queryuser> </soap:body> </soap:envelope>
then make a SOAP request:
# curl -s -H "content-type: application/soap+xml" \ -d @queryUser.xml http://127.0.0.1:8083/poe/user?wsdl \ | xmllint --format -
To query the user's access keys, create a file queryAccountKeySecretKey.xml:
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:soap1="http://obs.huawei.com/soap/"> <soap:Header/> <soap:Body> <soap1:queryAccountKeySecretKey> <userId>einstein</userid> <ak></ak> </soap1:queryaccountkeysecretkey> </soap:body> </soap:envelope>
then make a SOAP request:
# curl -s -H "content-type: application/soap+xml" \ -d @queryAccountKeySecretKey.xml http://127.0.0.1:8083/poe/aksk?wsdl \ | xmllint --format -
To modify a user, create a file modifyUser.xml (for example, to change the userName):
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:soap1="http://obs.huawei.com/soap/"> <soap:Header/> <soap:Body> <soap1:modifyUser> <userId>einstein</userid> <userName>Einstein</username> </soap1:modifyuser> </soap:body> </soap:envelope>
then make a SOAP request:
# curl -s -H "content-type: application/soap+xml" \ -d @modifyUser.xml http://127.0.0.1:8083/poe/user?wsdl \ | xmllint --format -
To remove a user, create a file removeUser.xml:
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:soap1="http://obs.huawei.com/soap/"> <soap:Header/> <soap:Body> <soap1:removeUser> <userId>test</userid> </soap1:removeuser> </soap:body> </soap:envelope>
then make a SOAP request:
# curl -s -H "content-type: application/soap+xml" \ -d @removeUser.xml http://127.0.0.1:8083/poe/user?wsdl \ | xmllint --format -
By default, the Huawei UDS saves 3 copies of each object, which, although providing great protection against data loss, results in much less effective storage capacity. Fortunately, Huawei has implemented Erasure Code (EC) for UDS (but doesn't enable it by default). Optimal erasure codes have the property that any k out of the n code word symbols are sufficient to recover the original message. So EC offers much improved effective storage capacity, while maintaining good protection against data loss.
To enable EC, create a file modifyECConf.xml (code rate = 9/12):
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:soap1="http://obs.huawei.com/soap/"> <soap:Header/> <soap:Body> <soap1:modifyECConf> <userId>einstein</userid> <ECEnable>TRUE</ecenable> <GroupSize>12</groupsize> <NumParities>3</numparities> </soap1:modifyecconf> </soap:body> </soap:envelope>
then make a SOAP request to modify EC configuration for a user:
# curl -s -H "content-type: application/soap+xml" \ -d @modifyECConf.xml http://127.0.0.1:8083/poe/ec?wsdl \ | xmllint --format -
To query a user's EC configuration, create a file queryECConf.xml:
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:soap1="http://obs.huawei.com/soap/"> <soap:Header/> <soap:Body> <soap1:queryECConf> <userId>einstein</userid> </soap1:queryecconf> </soap:body> </soap:envelope>
then make a SOAP request:
# curl -s -H "content-type: application/soap+xml" \ -d @queryECConf.xml http://127.0.0.1:8083/poe/ec?wsdl \ | xmllint --format -
The Huawei UDS uses LDAP directory as the backend to store user data. So we can use LDAP tools to directly manipulate the data, albeit a bit dangerously.
We can run slapcat to generate an LDAP Directory Interchange Format (LDIF) output based upon the contents of the slapd database:
# slapcat
LDAP search:
# ldapsearch -x -b 'dc=cloud,dc=com' -D 'dc=cloud,dc=com' \ -w BDCAbbPkekimWTj5where:
- -x: Use simple authentication instead of SASL;
- -b 'dc=cloud,dc=com' : Use 'dc=cloud,dc=com' as the starting point for the search instead of the defaul;
- -D 'dc=cloud,dc=com' : Use the Distinguished Name 'dc=cloud,dc=com' to bind to the LDAP directory;
- -w BDCAbbPkekimWTj5: Use BDCAbbPkekimWTj5 as the password for simple authentication.
# ldapdelete 'AKID=819706105F122117A309,USERIDENTITY=test,dc=UserInfo,dc=cloud,dc=com' \ -x -D 'dc=cloud,dc=com' -w BDCAbbPkekimWTj5 # ldapdelete 'SERVICETYPE=BASE,USERIDENTITY=test,dc=UserInfo,dc=cloud,dc=com' \ -x -D 'dc=cloud,dc=com' -w BDCAbbPkekimWTj5 # ldapdelete 'USERIDENTITY=test,dc=UserInfo,dc=cloud,dc=com' -x -D 'dc=cloud,dc=com' -w BDCAbbPkekimWTj5