Revision ec48ba70

View differences:

src/oca/java/src/org/opennebula/client/acl/Acl.java
1
/*******************************************************************************
2
 * Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org)
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *   http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 ******************************************************************************/
16
package org.opennebula.client.acl;
17

  
18

  
19
import java.util.Collections;
20
import java.util.HashMap;
21
import java.util.Map;
22

  
23
import org.opennebula.client.Client;
24
import org.opennebula.client.OneResponse;
25
import org.opennebula.client.PoolElement;
26
import org.w3c.dom.Node;
27

  
28
/**
29
 * This class represents an OpenNebula ACL rule.
30
 * It also offers static XML-RPC call wrappers.
31
 * <br/>
32
 * There is not a public constructor, because the information for an individual
33
 * ACL rule cannot be retrieved from OpenNebula.
34
 * <br/>
35
 * Instead, Acl objects should be obtained using AclPool.getById, after the
36
 * info method has been called.
37
 *
38
 * @see AclPool#getById
39
 */
40
public class Acl extends PoolElement{
41

  
42
    private static final String METHOD_PREFIX   = "acl.";
43
    private static final String ADDRULE         = METHOD_PREFIX + "addrule";
44
    private static final String DELRULE         = METHOD_PREFIX + "delrule";
45

  
46
    private static final Map<String, Long> USERS;
47
    private static final Map<String, Long> RESOURCES;
48
    private static final Map<String, Long> RIGHTS;
49

  
50
    static {
51
        HashMap<String, Long> tmpUsers = new HashMap<String, Long>();
52
        tmpUsers.put("#", 0x0000000100000000L);
53
        tmpUsers.put("@", 0x0000000200000000L);
54
        tmpUsers.put("*", 0x0000000400000000L);
55

  
56
        USERS = Collections.unmodifiableMap(tmpUsers);
57

  
58
        HashMap<String, Long> tmpResources = new HashMap<String, Long>();
59

  
60
        tmpResources.put("VM"       , 0x0000001000000000L);
61
        tmpResources.put("HOST"     , 0x0000002000000000L);
62
        tmpResources.put("NET"      , 0x0000004000000000L);
63
        tmpResources.put("IMAGE"    , 0x0000008000000000L);
64
        tmpResources.put("USER"     , 0x0000010000000000L);
65
        tmpResources.put("TEMPLATE" , 0x0000020000000000L);
66
        tmpResources.put("GROUP"    , 0x0000040000000000L);
67

  
68
        RESOURCES = Collections.unmodifiableMap(tmpResources);
69

  
70
        HashMap<String, Long> tmpRights = new HashMap<String, Long>();
71

  
72
        tmpRights.put("CREATE"        , 0x1L);
73
        tmpRights.put("DELETE"        , 0x2L);
74
        tmpRights.put("USE"           , 0x4L);
75
        tmpRights.put("MANAGE"        , 0x8L);
76
        tmpRights.put("INFO"          , 0x10L);
77
        tmpRights.put("INFO_POOL"     , 0x20L);
78
        tmpRights.put("INFO_POOL_MINE", 0x40L);
79
        tmpRights.put("INSTANTIATE"   , 0x80L);
80
        tmpRights.put("CHOWN"         , 0x100L);
81

  
82
        RIGHTS = Collections.unmodifiableMap(tmpRights);
83
    }
84

  
85
    /**
86
     * @see PoolElement
87
     */
88
    protected Acl(Node xmlElement, Client client)
89
    {
90
        super(xmlElement, client);
91
    }
92

  
93
    // =================================
94
    // Static XML-RPC methods
95
    // =================================
96

  
97
    /**
98
     * Allocates a new ACl rule in OpenNebula
99
     *
100
     * @param client XML-RPC Client.
101
     * @param user A string containing a hex number, e.g. 0x100000001
102
     * @param resource A string containing a hex number, e.g. 0x2100000001
103
     * @param rights A string containing a hex number, e.g. 0x10
104
     * @return If successful the message contains the associated
105
     * id generated for this rule.
106
     */
107
    public static OneResponse allocate(Client client, String user,
108
            String resource, String rights)
109
    {
110
        return client.call(ADDRULE, user, resource, rights);
111
    }
112

  
113
    /**
114
     * Allocates a new ACl rule in OpenNebula
115
     *
116
     * @param client XML-RPC Client.
117
     * @param user 64b encoded user
118
     * @param resource 64b encoded user
119
     * @param rights 64b encoded user
120
     * @return If successful the message contains the associated
121
     * id generated for this rule.
122
     */
123
    public static OneResponse allocate(Client client, long user, long resource,
124
            long rights)
125
    {
126
        return allocate(client,
127
                Long.toHexString(user),
128
                Long.toHexString(resource),
129
                Long.toHexString(rights));
130
    }
131

  
132
    /**
133
     * Allocates a new ACl rule in OpenNebula
134
     *
135
     * @param client XML-RPC Client.
136
     * @param rule a rule string, e.g. "#5 HOST+VM/@12 INFO+CREATE+DELETE"
137
     * @return If successful the message contains the associated
138
     * id generated for this rule.
139
     */
140
    public static OneResponse allocate(Client client, String rule)
141
    {
142
        String[] components = parseRule(rule);
143
        return allocate(client, components[0], components[1], components[2]);
144
    }
145

  
146
    /**
147
     * Deletes an ACL rule from OpenNebula.
148
     *
149
     * @param client XML-RPC Client.
150
     * @param id The ACL rule id.
151
     * @return A encapsulated response.
152
     */
153
    public static OneResponse delete(Client client, int id)
154
    {
155
        return client.call(DELRULE, id);
156
    }
157

  
158
    // =================================
159
    // Instanced object XML-RPC methods
160
    // =================================
161

  
162
    /**
163
     * Deletes the ACL rule from OpenNebula.
164
     *
165
     * @see Acl#delete(Client, int)
166
     */
167
    public OneResponse delete()
168
    {
169
        return delete(client, id);
170
    }
171

  
172
    // =================================
173
    // Helpers
174
    // =================================
175

  
176
    public long user()
177
    {
178
        long ret = 0;
179

  
180
        try
181
        {
182
            ret = Long.parseLong( xpath("USER"), 16 );
183
        }
184
        catch (NumberFormatException e)
185
        {}
186

  
187
        return ret;
188
    }
189

  
190
    public long resource()
191
    {
192
        long ret = 0;
193

  
194
        try
195
        {
196
            ret = Long.parseLong( xpath("RESOURCE"), 16 );
197
        }
198
        catch (NumberFormatException e)
199
        {}
200

  
201
        return ret;
202
    }
203

  
204
    public long rights()
205
    {
206
        long ret = 0;
207

  
208
        try
209
        {
210
            ret = Long.parseLong( xpath("RIGHTS"), 16 );
211
        }
212
        catch (NumberFormatException e)
213
        {}
214

  
215
        return ret;
216
    }
217

  
218
    public String toString()
219
    {
220
        String st = xpath("STRING");
221

  
222
        if( st == null )
223
        {
224
            st = "";
225
        }
226

  
227
        return st;
228
    }
229

  
230
    // =================================
231
    // Rule parsing
232
    // =================================
233

  
234
    /**
235
     * Parses a rule string, e.g. "#5 HOST+VM/@12 INFO+CREATE+DELETE"
236
     *
237
     * @param rule an ACL rule in string format
238
     * @return an Array containing 3 Strings (hex 64b numbers)
239
     */
240
    public static String[] parseRule(String rule)
241
    {
242
        String [] ret = new String[3];
243

  
244
        String [] components = rule.split(" ");
245

  
246
        if( components.length != 3 )
247
        {
248
            // TODO: throw "String needs three components: User, Resource, Rights"
249
            return ret;
250
        }
251

  
252
        ret[0] = parseUsers(components[0]);
253
        ret[1] = parseResources(components[1]);
254
        ret[2] = parseRights(components[2]);
255

  
256
        return ret;
257
    }
258

  
259
    /**
260
     * Converts a string in the form [#<id>, @<id>, *] to a hex. number
261
     *
262
     * @param users Users component string
263
     * @return A string containing a hex number
264
     */
265
    private static String parseUsers(String users)
266
    {
267
        return Long.toHexString( calculateIds(users) );
268
    }
269

  
270
    /**
271
     * Converts a resources string to a hex. number
272
     *
273
     * @param resources Resources component string
274
     * @return A string containing a hex number
275
     */
276
    private static String parseResources(String resources)
277
    {
278
        long ret = 0;
279
        String[] resourcesComponents = resources.split("/");
280

  
281
        if( resourcesComponents.length != 2 )
282
        {
283
            // TODO: throw "Resource '#{resources}' malformed"
284
            return "";
285
        }
286

  
287
        for( String resource : resourcesComponents[0].split("\\+") )
288
        {
289
            resource = resource.toUpperCase();
290

  
291
            if( !RESOURCES.containsKey(resource) )
292
            {
293
                // TODO: throw "Resource '#{resource}' does not exist"
294
            }
295

  
296
            ret += RESOURCES.get(resource);
297
        }
298

  
299
        ret += calculateIds(resourcesComponents[1]);
300

  
301
        return Long.toHexString(ret);
302
    }
303

  
304
    /**
305
     * Converts a rights string to a hex. number
306
     *
307
     * @param rights Rights component string
308
     * @return A string containing a hex number
309
     */
310
    private static String parseRights(String rights)
311
    {
312
        long ret = 0;
313

  
314

  
315
        for( String right : rights.split("\\+") )
316
        {
317
            right = right.toUpperCase();
318

  
319
            if( !RIGHTS.containsKey(right) )
320
            {
321
                // TODO throw "Right '#{right}' does not exist"
322
                return "";
323
            }
324

  
325
            ret += RIGHTS.get(right);
326
        }
327

  
328
        return Long.toHexString(ret);
329
    }
330

  
331
    /**
332
     * Calculates the numeric value for a String containing an individual
333
     * (#id), group (@id) or all (*) ID component
334
     *
335
     * @param id Rule Id string
336
     * @return the numeric value for the given id_str
337
     */
338
    private static long calculateIds(String id)
339
    {
340
        if( !id.matches("^([#@]\\d+|\\*)$") )
341
        {
342
            // TODO: throw "ID string '#{id_str}' malformed"
343
            return 0;
344
        }
345

  
346
        long value = USERS.get( "" + id.charAt(0) );
347

  
348
        if( id.charAt(0) != '*' )
349
        {
350
            value += Long.parseLong( id.substring(1) );
351
        }
352

  
353
        return value;
354
    }
355
}
src/oca/java/src/org/opennebula/client/acl/AclPool.java
1
/*******************************************************************************
2
 * Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org)
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *   http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 ******************************************************************************/
16
package org.opennebula.client.acl;
17

  
18
import java.util.AbstractList;
19
import java.util.Iterator;
20

  
21

  
22
import org.opennebula.client.Client;
23
import org.opennebula.client.OneResponse;
24
import org.opennebula.client.Pool;
25
import org.opennebula.client.PoolElement;
26
import org.w3c.dom.Node;
27

  
28
/**
29
 * This class represents an OpenNebula ACL rule pool.
30
 * It also offers static XML-RPC call wrappers.
31
 */
32
public class AclPool extends Pool implements Iterable<Acl>{
33

  
34
    private static final String ELEMENT_NAME = "ACL";
35
    private static final String INFO_METHOD  = "acl.info";
36

  
37
    /**
38
     * Creates a new ACL rule pool
39
     * @param client XML-RPC Client.
40
     */
41
    public AclPool(Client client)
42
    {
43
        super(ELEMENT_NAME, client);
44
    }
45

  
46
    @Override
47
    public PoolElement factory(Node node)
48
    {
49
        return new Acl(node, client);
50
    }
51

  
52
    /**
53
     * Retrieves all the hosts in the pool.
54
     *
55
     * @param client XML-RPC Client.
56
     * @return If successful the message contains the string
57
     * with the information returned by OpenNebula.
58
     */
59
    public static OneResponse info(Client client)
60
    {
61
        return client.call(INFO_METHOD);
62
    }
63

  
64
    /**
65
     * Loads the xml representation of the ACL rule pool.
66
     *
67
     * @see AclPool#info(Client)
68
     */
69
    public OneResponse info()
70
    {
71
        OneResponse response = info(client);
72
        super.processInfo(response);
73
        return response;
74
    }
75

  
76
    public Iterator<Acl> iterator()
77
    {
78
        AbstractList<Acl> ab = new AbstractList<Acl>()
79
        {
80
            public int size()
81
            {
82
                return getLength();
83
            }
84

  
85
            public Acl get(int index)
86
            {
87
                return (Acl) item(index);
88
            }
89
        };
90

  
91
        return ab.iterator();
92
    }
93

  
94
    public Acl getById(int id)
95
    {
96
        return (Acl) super.getById(id);
97
    }
98
}
src/oca/java/test/AclTest.java
1
/*******************************************************************************
2
 * Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org)
3
 * 
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 * 
8
 *   http://www.apache.org/licenses/LICENSE-2.0
9
 * 
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 ******************************************************************************/
16
import static org.junit.Assert.*;
17

  
18
import org.junit.After;
19
import org.junit.AfterClass;
20
import org.junit.Before;
21
import org.junit.BeforeClass;
22
import org.junit.Test;
23
import org.opennebula.client.Client;
24
import org.opennebula.client.OneResponse;
25
import org.opennebula.client.acl.*;
26

  
27
public class AclTest
28
{
29

  
30
    private static Acl          acl;
31
    private static AclPool      aclPool;
32

  
33
    private static Client       client;
34

  
35
    private static OneResponse  res;
36

  
37
    /**
38
     * @throws java.lang.Exception
39
     */
40
    @BeforeClass
41
    public static void setUpBeforeClass() throws Exception
42
    {
43
        client  = new Client();
44
        aclPool = new AclPool(client);
45
    }
46

  
47
    /**
48
     * @throws java.lang.Exception
49
     */
50
    @AfterClass
51
    public static void tearDownAfterClass() throws Exception
52
    {
53
    }
54

  
55
    /**
56
     * @throws java.lang.Exception
57
     */
58
    @Before
59
    public void setUp() throws Exception
60
    {
61
    }
62

  
63
    /**
64
     * @throws java.lang.Exception
65
     */
66
    @After
67
    public void tearDown() throws Exception
68
    {
69
        for(Acl rule : aclPool)
70
        {
71
            if( rule.id() != 0 )
72
            {
73
                rule.delete();
74
            }
75
        }
76
    }
77

  
78
    @Test
79
    public void defaultRules()
80
    {
81
        res = aclPool.info();
82
        assertTrue( !res.isError() );
83
        
84
        assertEquals(1, aclPool.getLength());
85
    }
86

  
87
    @Test
88
    public void hexAllocate()
89
    {
90
        // Allocate rule "#1 VM+HOST/@1 INFO+CREATE"
91
        res = Acl.allocate(client, "0x100000001", "0x3200000001", "0x11");
92
        assertTrue( !res.isError() );
93
        
94
        aclPool.info();
95
        acl = aclPool.getById( res.getIntMessage() );
96
        
97
        assertNotNull(acl);
98
        
99
        assertEquals(res.getIntMessage(),   acl.id());
100
        assertEquals(0x100000001L,          acl.user());
101
        assertEquals(0x3200000001L,         acl.resource());
102
        assertEquals(0x11L,                 acl.rights());
103
        assertEquals("#1 VM+HOST/@1 CREATE+INFO", acl.toString());
104
    }
105
    
106
    @Test
107
    public void numericAllocate()
108
    {
109
        // Allocate rule "#1 VM+HOST/@1 INFO+CREATE"
110
        res = Acl.allocate(client, 0x100000001L, 214748364801L, 0x11L);
111
        assertTrue( !res.isError() );
112
        
113
        aclPool.info();
114
        acl = aclPool.getById( res.getIntMessage() );
115
        
116
        assertNotNull(acl);
117
        
118
        assertEquals(res.getIntMessage(),   acl.id());
119
        assertEquals(0x100000001L,          acl.user());
120
        assertEquals(0x3200000001L,         acl.resource());
121
        assertEquals(0x11L,                 acl.rights());
122
        assertEquals("#1 VM+HOST/@1 CREATE+INFO", acl.toString());
123
    }
124
    
125
    @Test
126
    public void ruleAllocate()
127
    {
128
        res = Acl.allocate(client, "@507 IMAGE/#456 CREATE");
129
        assertTrue( !res.isError() );
130
        
131
        aclPool.info();
132
        acl = aclPool.getById( res.getIntMessage() );
133
        
134
        assertNotNull(acl);
135

  
136
        assertEquals(res.getIntMessage(),   acl.id());
137
        assertEquals(0x2000001fbL,          acl.user());
138
        assertEquals(0x81000001c8L,         acl.resource());
139
        assertEquals(0x1L,                 acl.rights());
140
        assertEquals("@507 IMAGE/#456 CREATE", acl.toString());
141
    }
142
    
143
    @Test
144
    public void parseRules()
145
    {
146
        String[] rules = { 
147
            "#3 TEMPLATE/#0 INFO",
148
            "#2 IMAGE/#0 INFO",
149
            "@107 IMAGE+TEMPLATE/@100 INFO",
150
            "* VM+IMAGE+TEMPLATE/@100 CREATE+INFO+INFO_POOL",
151
            "#2345 VM+IMAGE+TEMPLATE/* CREATE+INFO+INFO_POOL+INFO_POOL_MINE+INSTANTIATE"
152
        };
153

  
154
        long[] users = {
155
            0x100000003L,
156
            0x100000002L,
157
            0x20000006bL,
158
            0x400000000L,
159
            0x100000929L
160
        };
161
        
162
        long[] resources = {
163
            0x20100000000L,
164
            0x8100000000L,
165
            0x28200000064L,
166
            0x29200000064L,
167
            0x29400000000L
168
        };
169
        
170
        long[] rights = {
171
            0x10L,
172
            0x10L,
173
            0x10L,
174
            0x31L,
175
            0xf1L
176
        };
177

  
178
        for( int i = 0; i < rules.length; i++ )
179
        {
180
            res = Acl.allocate(client, rules[i]);
181
            assertTrue( !res.isError() );
182
            
183
            aclPool.info();
184
            acl = aclPool.getById( res.getIntMessage() );
185
            
186
            assertNotNull(acl);
187

  
188
            assertEquals(res.getIntMessage(),   acl.id());
189
            assertEquals(users[i],              acl.user());
190
            assertEquals(resources[i],          acl.resource());
191
            assertEquals(rights[i],             acl.rights());
192
        }
193

  
194
        assertTrue( true );
195
    }
196
    
197
    @Test
198
    public void delete()
199
    {
200
        res = Acl.allocate(client, "#1 HOST/@2 INFO_POOL");
201
        assertTrue( !res.isError() );
202
        
203
        aclPool.info();
204
        assertTrue( aclPool.getLength() == 2 );
205

  
206
        res = Acl.delete(client, res.getIntMessage());
207
        assertTrue( !res.isError() );
208
        
209
        aclPool.info();
210
        assertTrue( aclPool.getLength() == 1 );
211
    }
212

  
213
}
src/oca/java/test/all_tests.sh
1 1
#!/bin/bash
2 2

  
3
# -------------------------------------------------------------------------- #
4
# Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org)             #
5
#                                                                            #
6
# Licensed under the Apache License, Version 2.0 (the "License"); you may    #
7
# not use this file except in compliance with the License. You may obtain    #
8
# a copy of the License at                                                   #
9
#                                                                            #
10
# http://www.apache.org/licenses/LICENSE-2.0                                 #
11
#                                                                            #
12
# Unless required by applicable law or agreed to in writing, software        #
13
# distributed under the License is distributed on an "AS IS" BASIS,          #
14
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   #
15
# See the License for the specific language governing permissions and        #
16
# limitations under the License.                                             #
17
#--------------------------------------------------------------------------- #
18

  
3 19
if [ -z $ONE_LOCATION ]; then
4 20
    echo "ONE_LOCATION not defined."
5 21
    exit -1
......
42 58
./test.sh GroupTest
43 59
let RC=RC+$?
44 60

  
61
./test.sh AclTest
62
let RC=RC+$?
63

  
45 64
exit $RC
src/oca/java/test/test.sh
1 1
#!/bin/bash
2

  
3
# -------------------------------------------------------------------------- #
4
# Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org)             #
5
#                                                                            #
6
# Licensed under the Apache License, Version 2.0 (the "License"); you may    #
7
# not use this file except in compliance with the License. You may obtain    #
8
# a copy of the License at                                                   #
9
#                                                                            #
10
# http://www.apache.org/licenses/LICENSE-2.0                                 #
11
#                                                                            #
12
# Unless required by applicable law or agreed to in writing, software        #
13
# distributed under the License is distributed on an "AS IS" BASIS,          #
14
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   #
15
# See the License for the specific language governing permissions and        #
16
# limitations under the License.                                             #
17
#--------------------------------------------------------------------------- #
18

  
2 19
# Usage: test.sh <Test_name>
3 20
# For instance: test.sh ImageTest
4 21

  
......
16 33
    exit -1
17 34
fi
18 35

  
36
echo "========================================================================="
37
echo "Doing $1"
38
echo "========================================================================="
19 39

  
20 40
PID=$$
21 41

  

Also available in: Unified diff