~ubuntu-branches/ubuntu/precise/ceph/precise-proposed

« back to all changes in this revision

Viewing changes to src/rgw/rgw_admin.cc

  • Committer: Bazaar Package Importer
  • Author(s): Laszlo Boszormenyi (GCS)
  • Date: 2011-04-25 10:09:05 UTC
  • mfrom: (1.1.3 upstream) (0.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20110425100905-exm7dfvi2v5ick02
Tags: 0.27-1
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
5
5
 
6
6
using namespace std;
7
7
 
8
 
#include "config.h"
9
 
 
10
 
#include <cryptopp/osrng.h>
 
8
#include "common/config.h"
 
9
#include "common/ceph_argparse.h"
11
10
#include "common/common_init.h"
 
11
#include "common/errno.h"
12
12
 
13
13
#include "common/armor.h"
14
14
#include "rgw_user.h"
15
15
#include "rgw_access.h"
16
16
#include "rgw_acl.h"
 
17
#include "rgw_log.h"
 
18
#include "auth/Crypto.h"
17
19
 
18
20
 
19
21
#define SECRET_KEY_LEN 40
21
23
 
22
24
void usage() 
23
25
{
24
 
  cerr << "usage: radosgw_admin <--user-gen | --user-modify | --read-policy | --list-buckets > [options...]" << std::endl;
25
 
  cerr << "options:" << std::endl;
26
 
  cerr << "   --uid=<id> (S3 uid)" << std::endl;
27
 
  cerr << "   --auth_uid=<auid> (librados uid)" << std::endl;
28
 
  cerr << "   --secret=<key>" << std::endl;
29
 
  cerr << "   --email=<email>" << std::endl;
30
 
  cerr << "   --display-name=<name>" << std::endl;
31
 
  cerr << "   --bucket=<bucket>" << std::endl;
32
 
  cerr << "   --object=<object>" << std::endl;
33
 
  generic_usage();
 
26
  cerr << "usage: radosgw_admin <cmd> [options...]" << std::endl;
 
27
  cerr << "commands:\n";
 
28
  cerr << "  user create                create a new user\n" ;
 
29
  cerr << "  user modify                modify user\n";
 
30
  cerr << "  user info                  get user info\n";
 
31
  cerr << "  user rm                    remove user\n";
 
32
  cerr << "  buckets list               list buckets\n";
 
33
  cerr << "  bucket unlink              unlink bucket from specified user\n";
 
34
  cerr << "  policy                     read bucket/object policy\n";
 
35
  cerr << "  log show                   dump a log from specific bucket, date\n";
 
36
  cerr << "options:\n";
 
37
  cerr << "   --uid=<id>                user id\n";
 
38
  cerr << "   --access-key=<id>         S3 access key\n";
 
39
  cerr << "   --os-user=<group:name>    OpenStack user\n";
 
40
  cerr << "   --email=<email>\n";
 
41
  cerr << "   --auth_uid=<auid>         librados uid\n";
 
42
  cerr << "   --secret=<key>            S3 key\n";
 
43
  cerr << "   --os-secret=<key>         OpenStack key\n";
 
44
  cerr << "   --display-name=<name>\n";
 
45
  cerr << "   --bucket=<bucket>\n";
 
46
  cerr << "   --object=<object>\n";
 
47
  cerr << "   --date=<yyyy-mm-dd>\n";
 
48
  generic_client_usage();
34
49
  exit(1);
35
50
}
36
51
 
 
52
enum {
 
53
  OPT_NO_CMD = 0,
 
54
  OPT_USER_CREATE,
 
55
  OPT_USER_INFO,
 
56
  OPT_USER_MODIFY,
 
57
  OPT_USER_RM,
 
58
  OPT_BUCKETS_LIST,
 
59
  OPT_BUCKET_UNLINK,
 
60
  OPT_POLICY,
 
61
  OPT_LOG_SHOW,
 
62
};
 
63
 
 
64
static int get_cmd(const char *cmd, const char *prev_cmd, bool *need_more)
 
65
{
 
66
  *need_more = false;
 
67
  if (strcmp(cmd, "user") == 0 ||
 
68
      strcmp(cmd, "buckets") == 0 ||
 
69
      strcmp(cmd, "bucket") == 0 ||
 
70
      strcmp(cmd, "log") == 0) {
 
71
    *need_more = true;
 
72
    return 0;
 
73
  }
 
74
 
 
75
  if (strcmp(cmd, "policy") == 0)
 
76
    return OPT_POLICY;
 
77
 
 
78
  if (!prev_cmd)
 
79
    return -EINVAL;
 
80
 
 
81
  if (strcmp(prev_cmd, "user") == 0) {
 
82
    if (strcmp(cmd, "create") == 0)
 
83
      return OPT_USER_CREATE;
 
84
    if (strcmp(cmd, "info") == 0)
 
85
      return OPT_USER_INFO;
 
86
    if (strcmp(cmd, "modify") == 0)
 
87
      return OPT_USER_MODIFY;
 
88
    if (strcmp(cmd, "rm") == 0)
 
89
      return OPT_USER_RM;
 
90
  } else if (strcmp(prev_cmd, "buckets") == 0) {
 
91
    if (strcmp(cmd, "list") == 0)
 
92
      return OPT_BUCKETS_LIST;
 
93
  } else if (strcmp(prev_cmd, "bucket") == 0) {
 
94
    if (strcmp(cmd, "unlink") == 0)
 
95
      return OPT_BUCKET_UNLINK;
 
96
  } else if (strcmp(prev_cmd, "log") == 0) {
 
97
    if (strcmp(cmd, "show") == 0)
 
98
      return OPT_LOG_SHOW;
 
99
  }
 
100
 
 
101
  return -EINVAL;
 
102
}
 
103
 
37
104
int gen_rand_base64(char *dest, int size) /* size should be the required string size + 1 */
38
105
{
39
 
  unsigned char buf[size];
 
106
  char buf[size];
40
107
  char tmp_dest[size + 4]; /* so that there's space for the extra '=' characters, and some */
41
 
 
42
 
  CryptoPP::AutoSeededRandomPool rng;
43
 
  rng.GenerateBlock(buf, sizeof(buf));
44
 
 
45
 
  int ret = ceph_armor(tmp_dest, &tmp_dest[sizeof(tmp_dest)],
 
108
  int ret;
 
109
 
 
110
  ret = get_random_bytes(buf, sizeof(buf));
 
111
  if (ret < 0) {
 
112
    cerr << "cannot get random bytes: " << cpp_strerror(-ret) << std::endl;
 
113
    return -1;
 
114
  }
 
115
 
 
116
  ret = ceph_armor(tmp_dest, &tmp_dest[sizeof(tmp_dest)],
46
117
                   (const char *)buf, ((const char *)buf) + ((size - 1) * 3 + 4 - 1) / 4);
47
118
  if (ret < 0) {
48
119
    cerr << "ceph_armor failed" << std::endl;
59
130
 
60
131
int gen_rand_alphanumeric(char *dest, int size) /* size should be the required string size + 1 */
61
132
{
62
 
  CryptoPP::AutoSeededRandomPool rng;
63
 
  rng.GenerateBlock((unsigned char *)dest, size);
 
133
  int ret = get_random_bytes(dest, size);
 
134
  if (ret < 0) {
 
135
    cerr << "cannot get random bytes: " << cpp_strerror(-ret) << std::endl;
 
136
    return -1;
 
137
  }
64
138
 
65
139
  int i;
66
140
  for (i=0; i<size - 1; i++) {
72
146
  return 0;
73
147
}
74
148
 
75
 
 
76
 
 
 
149
string escape_str(string& src, char c)
 
150
{
 
151
  int pos = 0;
 
152
  string s = src;
 
153
  string dest;
 
154
 
 
155
  do {
 
156
    int new_pos = src.find(c, pos);
 
157
    if (new_pos >= 0) {
 
158
      dest += src.substr(pos, new_pos - pos);
 
159
      dest += "\\";
 
160
      dest += c;
 
161
    } else {
 
162
      dest += src.substr(pos);
 
163
      return dest;
 
164
    }
 
165
    pos = new_pos + 1;
 
166
  } while (pos < (int)src.size());
 
167
 
 
168
  return dest;
 
169
}
77
170
 
78
171
int main(int argc, char **argv) 
79
172
{
82
175
  argv_to_vec(argc, (const char **)argv, args);
83
176
  env_to_vec(args);
84
177
 
85
 
  common_set_defaults(true);
86
 
  common_init(args, "rgw", true);
 
178
  common_init(args, CEPH_ENTITY_TYPE_CLIENT, CODE_ENVIRONMENT_UTILITY, 0);
 
179
  keyring_init(&g_conf);
87
180
 
88
181
  const char *user_id = 0;
 
182
  const char *access_key = 0;
89
183
  const char *secret_key = 0;
90
184
  const char *user_email = 0;
91
185
  const char *display_name = 0;
92
186
  const char *bucket = 0;
93
187
  const char *object = 0;
94
 
  bool gen_user = false;
95
 
  bool mod_user = false;
96
 
  bool read_policy = false;
97
 
  bool list_buckets = false;
98
 
  bool delete_user = false;
99
 
  int actions = 0 ;
 
188
  const char *openstack_user = 0;
 
189
  const char *openstack_key = 0;
 
190
  const char *date = 0;
100
191
  uint64_t auid = 0;
101
192
  RGWUserInfo info;
102
193
  RGWAccess *store;
103
 
 
104
 
  if (g_conf.clock_tare) g_clock.tare();
 
194
  const char *prev_cmd = NULL;
 
195
  int opt_cmd = OPT_NO_CMD;
 
196
  bool need_more;
105
197
 
106
198
  FOR_EACH_ARG(args) {
107
 
    if (CONF_ARG_EQ("user-gen", 'g')) {
108
 
      gen_user = true;
109
 
    } else if (CONF_ARG_EQ("user-modify", 'm')) {
110
 
      mod_user = true;
111
 
    } else if (CONF_ARG_EQ("read-policy", 'p')) {
112
 
      read_policy = true;
113
 
    } else if (CONF_ARG_EQ("list-buckets", 'l')) {
114
 
      list_buckets = true;
115
 
    } else if (CONF_ARG_EQ("uid", 'i')) {
116
 
      CONF_SAFE_SET_ARG_VAL(&user_id, OPT_STR);
117
 
    } else if (CONF_ARG_EQ("secret", 's')) {
118
 
      CONF_SAFE_SET_ARG_VAL(&secret_key, OPT_STR);
119
 
    } else if (CONF_ARG_EQ("email", 'e')) {
120
 
      CONF_SAFE_SET_ARG_VAL(&user_email, OPT_STR);
121
 
    } else if (CONF_ARG_EQ("display-name", 'n')) {
122
 
      CONF_SAFE_SET_ARG_VAL(&display_name, OPT_STR);
123
 
    } else if (CONF_ARG_EQ("bucket", 'b')) {
124
 
      CONF_SAFE_SET_ARG_VAL(&bucket, OPT_STR);
125
 
    } else if (CONF_ARG_EQ("object", 'o')) {
126
 
      CONF_SAFE_SET_ARG_VAL(&object, OPT_STR);
127
 
    } else if (CONF_ARG_EQ("auth_uid", 'a')) {
128
 
      CONF_SAFE_SET_ARG_VAL(&auid, OPT_LONGLONG);
129
 
    } else if (CONF_ARG_EQ("delete_user", 'd')) {
130
 
      delete_user = true;
 
199
    if (CEPH_ARGPARSE_EQ("uid", 'i')) {
 
200
      CEPH_ARGPARSE_SET_ARG_VAL(&user_id, OPT_STR);
 
201
    } else if (CEPH_ARGPARSE_EQ("access-key", '\0')) {
 
202
      CEPH_ARGPARSE_SET_ARG_VAL(&access_key, OPT_STR);
 
203
    } else if (CEPH_ARGPARSE_EQ("secret", 's')) {
 
204
      CEPH_ARGPARSE_SET_ARG_VAL(&secret_key, OPT_STR);
 
205
    } else if (CEPH_ARGPARSE_EQ("email", 'e')) {
 
206
      CEPH_ARGPARSE_SET_ARG_VAL(&user_email, OPT_STR);
 
207
    } else if (CEPH_ARGPARSE_EQ("display-name", 'n')) {
 
208
      CEPH_ARGPARSE_SET_ARG_VAL(&display_name, OPT_STR);
 
209
    } else if (CEPH_ARGPARSE_EQ("bucket", 'b')) {
 
210
      CEPH_ARGPARSE_SET_ARG_VAL(&bucket, OPT_STR);
 
211
    } else if (CEPH_ARGPARSE_EQ("object", 'o')) {
 
212
      CEPH_ARGPARSE_SET_ARG_VAL(&object, OPT_STR);
 
213
    } else if (CEPH_ARGPARSE_EQ("auth-uid", 'a')) {
 
214
      CEPH_ARGPARSE_SET_ARG_VAL(&auid, OPT_LONGLONG);
 
215
    } else if (CEPH_ARGPARSE_EQ("os-user", '\0')) {
 
216
      CEPH_ARGPARSE_SET_ARG_VAL(&openstack_user, OPT_STR);
 
217
    } else if (CEPH_ARGPARSE_EQ("os-secret", '\0')) {
 
218
      CEPH_ARGPARSE_SET_ARG_VAL(&openstack_key, OPT_STR);
 
219
    } else if (CEPH_ARGPARSE_EQ("date", '\0')) {
 
220
      CEPH_ARGPARSE_SET_ARG_VAL(&date, OPT_STR);
131
221
    } else {
132
 
      cerr << "unrecognized arg " << args[i] << std::endl;
133
 
      ARGS_USAGE();
 
222
      if (!opt_cmd) {
 
223
        opt_cmd = get_cmd(CEPH_ARGPARSE_VAL, prev_cmd, &need_more);
 
224
        if (opt_cmd < 0) {
 
225
          cerr << "unrecognized arg " << args[i] << std::endl;
 
226
          usage();
 
227
        }
 
228
        if (need_more) {
 
229
          prev_cmd = CEPH_ARGPARSE_VAL;
 
230
          continue;
 
231
        }
 
232
      } else {
 
233
        cerr << "unrecognized arg " << args[i] << std::endl;
 
234
        usage();
 
235
      }
134
236
    }
135
237
  }
136
238
 
137
 
  store = RGWAccess::init_storage_provider("rados", argc, argv);
 
239
  if (opt_cmd == OPT_NO_CMD)
 
240
    usage();
 
241
 
 
242
  store = RGWAccess::init_storage_provider("rados", &g_conf);
138
243
  if (!store) {
139
244
    cerr << "couldn't init storage provider" << std::endl;
140
245
    return 5; //EIO
141
246
  }
142
247
 
143
 
 
144
 
  if (mod_user) {
145
 
    actions++;
146
 
 
 
248
  if (opt_cmd != OPT_USER_CREATE && opt_cmd != OPT_LOG_SHOW && !user_id) {
 
249
    bool found = false;
 
250
    string s;
 
251
    if (user_email) {
 
252
      s = user_email;
 
253
      if (rgw_get_user_info_by_email(s, info) >= 0) {
 
254
        found = true;
 
255
      } else {
 
256
        cerr << "could not find user by specified email" << std::endl;
 
257
      }
 
258
    }
 
259
    if (!found && access_key) {
 
260
      s = access_key;
 
261
      if (rgw_get_user_info_by_access_key(s, info) >= 0) {
 
262
        found = true;
 
263
      } else {
 
264
        cerr << "could not find user by specified access key" << std::endl;
 
265
      }
 
266
    }
 
267
    if (!found && openstack_user) {
 
268
      s = openstack_user;
 
269
      if (rgw_get_user_info_by_openstack(s, info) >= 0) {
 
270
        found = true;
 
271
      } else
 
272
        cerr << "could not find user by specified openstack username" << std::endl;
 
273
    }
 
274
    if (found)
 
275
      user_id = info.user_id.c_str();
 
276
  }
 
277
 
 
278
 
 
279
  if (opt_cmd == OPT_USER_CREATE || opt_cmd == OPT_USER_MODIFY ||
 
280
      opt_cmd == OPT_USER_INFO || opt_cmd == OPT_BUCKET_UNLINK) {
147
281
    if (!user_id) {
148
282
      cerr << "user_id was not specified, aborting" << std::endl;
149
 
      return 0;
 
283
      usage();
150
284
    }
151
285
 
152
286
    string user_id_str = user_id;
153
287
 
154
 
    if (rgw_get_user_info(user_id_str, info) < 0) {
 
288
    if (opt_cmd != OPT_USER_CREATE &&
 
289
        info.user_id.empty() &&
 
290
        rgw_get_user_info_by_uid(user_id_str, info) < 0) {
155
291
      cerr << "error reading user info, aborting" << std::endl;
156
292
      exit(1);
157
293
    }
158
294
  }
159
295
 
160
 
  if (gen_user) {
161
 
    actions++;
 
296
  if (opt_cmd == OPT_USER_CREATE) {
162
297
    char secret_key_buf[SECRET_KEY_LEN + 1];
163
298
    char public_id_buf[PUBLIC_ID_LEN + 1];
164
299
    int ret;
176
311
      }
177
312
      secret_key = secret_key_buf;
178
313
    }
179
 
    if (!user_id) {
 
314
    if (!access_key) {
180
315
      RGWUserInfo duplicate_check;
181
316
      string duplicate_check_id;
182
317
      do {
185
320
          cerr << "aborting" << std::endl;
186
321
          exit(1);
187
322
        }
188
 
        user_id = public_id_buf;
189
 
        duplicate_check_id = user_id;
190
 
      } while (!rgw_get_user_info(duplicate_check_id, duplicate_check));
 
323
        access_key = public_id_buf;
 
324
        duplicate_check_id = access_key;
 
325
      } while (!rgw_get_user_info_by_access_key(duplicate_check_id, duplicate_check));
191
326
    }
192
327
  }
193
328
 
194
 
  if (gen_user || mod_user) {
 
329
 
 
330
  int err;
 
331
  switch (opt_cmd) {
 
332
  case OPT_USER_CREATE:
 
333
  case OPT_USER_MODIFY:
195
334
    if (user_id)
196
335
      info.user_id = user_id;
 
336
    if (access_key)
 
337
      info.access_key = access_key;
197
338
    if (secret_key)
198
339
      info.secret_key = secret_key;
199
340
    if (display_name)
202
343
      info.user_email = user_email;
203
344
    if (auid)
204
345
      info.auid = auid;
205
 
 
206
 
    int err;
 
346
    if (openstack_user)
 
347
      info.openstack_name = openstack_user;
 
348
    if (openstack_key)
 
349
      info.openstack_key = openstack_key;
 
350
  
207
351
    if ((err = rgw_store_user_info(info)) < 0) {
208
 
      cerr << "error storing user info" << strerror(-err) << std::endl;
209
 
    } else {
210
 
      cout << "User ID: " << info.user_id << std::endl;
211
 
      cout << "Secret Key: " << info.secret_key << std::endl;
212
 
      cout << "Display Name: " << info.display_name << std::endl;
 
352
      cerr << "error storing user info: " << cpp_strerror(-err) << std::endl;
 
353
      break;
213
354
    }
 
355
 
 
356
    /* fall through */
 
357
 
 
358
  case OPT_USER_INFO:
 
359
    cout << "User ID: " << info.user_id << std::endl;
 
360
    cout << "Access Key: " << info.access_key << std::endl;
 
361
    cout << "Secret Key: " << info.secret_key << std::endl;
 
362
    cout << "Display Name: " << info.display_name << std::endl;
 
363
    cout << "OpenStack User: " << (info.openstack_name.size() ? info.openstack_name : "<undefined>")<< std::endl;
 
364
    cout << "OpenStack Key: " << (info.openstack_key.size() ? info.openstack_key : "<undefined>")<< std::endl;
 
365
    break;
214
366
  }
215
367
 
216
 
  if (read_policy) {
217
 
    actions++;
 
368
  if (opt_cmd == OPT_POLICY) {
218
369
    bufferlist bl;
219
370
    if (!bucket)
220
371
      bucket = "";
234
385
    }
235
386
  }
236
387
 
237
 
  if (list_buckets) {
238
 
    actions++;
 
388
  if (opt_cmd == OPT_BUCKETS_LIST) {
239
389
    string id;
240
390
    RGWAccessHandle handle;
241
391
 
242
392
    if (user_id) {
243
393
      RGWUserBuckets buckets;
244
 
      if (rgw_get_user_buckets(user_id, buckets) < 0) {
 
394
      if (rgw_read_user_buckets(user_id, buckets, false) < 0) {
245
395
        cout << "could not get buckets for uid " << user_id << std::endl;
246
396
      } else {
247
 
        cout << "listing buckets for uid " << user_id << std::endl;
248
 
        map<string, RGWObjEnt>& m = buckets.get_buckets();
249
 
        map<string, RGWObjEnt>::iterator iter;
 
397
        map<string, RGWBucketEnt>& m = buckets.get_buckets();
 
398
        map<string, RGWBucketEnt>::iterator iter;
250
399
 
251
400
        for (iter = m.begin(); iter != m.end(); ++iter) {
252
 
          RGWObjEnt obj = iter->second;
 
401
          RGWBucketEnt obj = iter->second;
253
402
          cout << obj.name << std::endl;
254
403
        }
255
404
      }
266
415
    }
267
416
  }
268
417
 
269
 
  if (delete_user) {
270
 
    ++actions;
 
418
  if (opt_cmd == OPT_BUCKET_UNLINK) {
 
419
    if (!bucket) {
 
420
      cerr << "bucket name was not specified" << std::endl;
 
421
      usage();
 
422
    }
 
423
    string bucket_str(bucket);
 
424
    int r = rgw_remove_bucket(user_id, bucket_str);
 
425
    if (r < 0)
 
426
      cerr << "error unlinking bucket " <<  cpp_strerror(-r) << std::endl;
 
427
    return -r;
 
428
  }
 
429
 
 
430
  if (opt_cmd == OPT_LOG_SHOW) {
 
431
    if (!date || !bucket) {
 
432
      if (!date)
 
433
        cerr << "date was not specified" << std::endl;
 
434
      if (!bucket)
 
435
        cerr << "bucket was not specified" << std::endl;
 
436
      usage();
 
437
    }
 
438
 
 
439
    string log_bucket = RGW_LOG_BUCKET_NAME;
 
440
    string oid = date;
 
441
    oid += "-";
 
442
    oid += string(bucket);
 
443
    uint64_t size;
 
444
    int r = store->obj_stat(log_bucket, oid, &size, NULL);
 
445
    if (r < 0) {
 
446
      cerr << "error while doing stat on " <<  log_bucket << ":" << oid
 
447
           << " " << cpp_strerror(-r) << std::endl;
 
448
      return -r;
 
449
    }
 
450
    bufferlist bl;
 
451
    r = store->read(log_bucket, oid, 0, size, bl);
 
452
    if (r < 0) {
 
453
      cerr << "error while reading from " <<  log_bucket << ":" << oid
 
454
           << " " << cpp_strerror(-r) << std::endl;
 
455
      return -r;
 
456
    }
 
457
 
 
458
    bufferlist::iterator iter = bl.begin();
 
459
 
 
460
    struct rgw_log_entry entry;
 
461
    const char *delim = " ";
 
462
 
 
463
    while (!iter.end()) {
 
464
      ::decode(entry, iter);
 
465
 
 
466
      cout << (entry.owner.size() ? entry.owner : "-" ) << delim
 
467
           << entry.bucket << delim
 
468
           << entry.time << delim
 
469
           << entry.remote_addr << delim
 
470
           << entry.user << delim
 
471
           << entry.op << delim
 
472
           << "\"" << escape_str(entry.uri, '"') << "\"" << delim
 
473
           << entry.http_status << delim
 
474
           << entry.error_code << delim
 
475
           << entry.bytes_sent << delim
 
476
           << entry.obj_size << delim
 
477
           << entry.total_time.usec() << delim
 
478
           << "\"" << escape_str(entry.user_agent, '"') << "\"" << delim
 
479
           << "\"" << escape_str(entry.referrer, '"') << "\"" << std::endl;
 
480
    }
 
481
  }
 
482
 
 
483
  if (opt_cmd == OPT_USER_RM) {
271
484
    rgw_delete_user(info);
272
485
  }
273
486
 
274
 
  if (!actions)
275
 
    ARGS_USAGE();
276
 
 
277
487
  return 0;
278
488
}