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/.

Table of Contents

WSDL

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.

User Account Management

# 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.

Service Provisioning Management

# curl -s http://127.0.0.1:8083/poe/srv?wsdl | xmllint --format -

User Keys Management

# curl -s http://127.0.0.1:8083/poe/aksk?wsdl | xmllint --format -

Modifying EC Configuration

# curl -s http://127.0.0.1:8083/poe/ec?wsdl | xmllint --format -

Usage

Add a User

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.xml
NOTE:
  • -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.
When successful, we get output like the following:
<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 -

Query a User

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 -

Modify a User

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 -

Remove a User

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 -

Erasure Code Configuration

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 -

LDAP

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 BDCAbbPkekimWTj5
where:
  • -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.
Use ldapdelete to delete a user:
# 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

See Also

References

  1. ^ How to disable Geronimo services to avoid port conflicts
  2. ^ SOAP Example
⚠️ **GitHub.com Fallback** ⚠️