]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgwam: rgw admin for multisite tool
authorYehuda Sadeh <yehuda@redhat.com>
Thu, 29 Apr 2021 12:24:24 +0000 (05:24 -0700)
committerYehuda Sadeh <yehuda@redhat.com>
Wed, 24 Nov 2021 20:54:25 +0000 (12:54 -0800)
initial work

Signed-off-by: Yehuda Sadeh <yehuda@redhat.com>
src/rgw/CMakeLists.txt
src/rgw/rgw_admin_multi.py [new file with mode: 0644]

index 5acbd17a2dd07e8369a99a9262c0efd89374685a..1dd8e2fc5b4051f5bfa088c9ad1d43591bba6963 100644 (file)
@@ -380,6 +380,19 @@ target_link_libraries(radosgw-admin ${rgw_libs} librados
   ${CURL_LIBRARIES} ${EXPAT_LIBRARIES} ${BLKID_LIBRARIES})
 install(TARGETS radosgw-admin DESTINATION bin)
 
+set(radosgw_admin_srcs
+  rgw_admin_cli.cc
+  rgw_sync_checkpoint.cc
+  rgw_orphan.cc)
+add_executable(radosgw-admin-cli ${radosgw_admin_srcs})
+target_link_libraries(radosgw-admin-cli ${rgw_libs} librados
+  cls_rgw_client cls_otp_client cls_lock_client cls_refcount_client
+  cls_log_client cls_timeindex_client neorados_cls_fifo
+  cls_version_client cls_user_client
+  global ${FCGI_LIBRARY} ${LIB_RESOLV}
+  ${CURL_LIBRARIES} ${EXPAT_LIBRARIES} ${BLKID_LIBRARIES})
+install(TARGETS radosgw-admin-cli DESTINATION bin)
+
 set(radosgw_es_srcs
   rgw_es_main.cc)
 add_executable(radosgw-es ${radosgw_es_srcs})
diff --git a/src/rgw/rgw_admin_multi.py b/src/rgw/rgw_admin_multi.py
new file mode 100644 (file)
index 0000000..4e8bb2e
--- /dev/null
@@ -0,0 +1,147 @@
+import subprocess
+import random
+import string
+import json
+import argparse
+import sys
+
+def rand_alphanum_lower(l):
+    return ''.join(random.choices(string.ascii_lowercase + string.digits, k=l))
+
+class RGWAMException(BaseException):
+    def __init__(self, message):
+        self.message = message
+
+
+class RGWAdminCmd:
+    def __init__(self):
+        self.cmd_prefix = [ 'radosgw-admin' ]
+
+    def run(self, cmd):
+        run_cmd = self.cmd_prefix + cmd
+        result = subprocess.run(run_cmd, stdout=subprocess.PIPE)
+        return (result.returncode, result.stdout)
+
+class RealmOp(RGWAdminCmd):
+    def __init__(self):
+        RGWAdminCmd.__init__(self)
+        
+    def create(self, name = None, is_default = True):
+        self.name = name
+        if not self.name:
+            self.name = 'realm-' + rand_alphanum_lower(8)
+
+        params = [ 'realm',
+                   'create',
+                   '--rgw-realm', self.name ]
+
+        if is_default:
+            params += [ '--default' ]
+
+        retcode, stdout = RGWAdminCmd.run(self, params)
+        if retcode != 0:
+            return None
+
+        self.info = json.loads(stdout)
+
+        return self.info
+
+
+class RGWAM:
+    def __init__(self):
+        pass
+
+    def realm_bootstrap(self, realm, zonegroup, zone, endpoints):
+        realm_info = RealmOp().create(realm)
+        if not realm_info:
+            return
+
+        realm_name = realm_info['name']
+        realm_id = realm_info['id']
+        print('Created realm %s (%s)' % (realm_name, realm_id))
+
+    def zonegroup_create(self, realm, zonegroup, zone, endpoints):
+        realm_op = RealmOp()
+
+        realm_info = realm_op.create(realm)
+        if not realm_info:
+            return
+
+        realm_name = realm_info['name']
+        realm_id = realm_info['id']
+        print('Created realm %s (%s)' % (realm_name, realm_id))
+
+
+class RealmCommand:
+    def __init__(self, args):
+        self.args = args
+
+    def parse(self):
+        parser = argparse.ArgumentParser(
+            description='S3 control tool',
+            usage='''rgwam realm <subcommand>
+
+The subcommands are:
+   bootstrap                     Manipulate bucket versioning
+''')
+        parser.add_argument('subcommand', help='Subcommand to run')
+        # parse_args defaults to [1:] for args, but you need to
+        # exclude the rest of the args too, or validation will fail
+        args = parser.parse_args(self.args[0:1])
+        if not hasattr(self, args.subcommand):
+            print('Unrecognized subcommand:', args.subcommand)
+            parser.print_help()
+            exit(1)
+        # use dispatch pattern to invoke method with same name
+        return getattr(self, args.subcommand)
+
+    def bootstrap(self):
+        parser = argparse.ArgumentParser(
+            description='Bootstrap new realm',
+            usage='rgwam realm bootstrap [<args>]')
+        parser.add_argument('--realm')
+        parser.add_argument('--zonegroup')
+        parser.add_argument('--zone')
+        parser.add_argument('--endpoints')
+
+        args = parser.parse_args(self.args[1:])
+
+        RGWAM().realm_bootstrap(args.realm, args.zonegroup, args.zone, args.endpoints)
+
+class TopLevelCommand:
+
+    def _parse(self):
+        parser = argparse.ArgumentParser(
+            description='RGW assist for multisite tool',
+            usage='''rgwam <command> [<args>]
+
+The commands are:
+   realm bootstrap               Bootstrap realm
+''')
+        parser.add_argument('command', help='Subcommand to run')
+        # parse_args defaults to [1:] for args, but you need to
+        # exclude the rest of the args too, or validation will fail
+        args = parser.parse_args(sys.argv[1:2])
+        if not hasattr(self, args.command) or args.command[0] == '_':
+            print('Unrecognized command:', args.command)
+            parser.print_help()
+            exit(1)
+        # use dispatch pattern to invoke method with same name
+        return getattr(self, args.command)
+
+    def realm(self):
+        cmd = RealmCommand(sys.argv[2:]).parse()
+        cmd()
+
+
+def main():
+    cmd = TopLevelCommand()._parse()
+    try:
+        cmd()
+    except RGWAMException as e:
+        print('ERROR: ' + e.message)
+
+
+if __name__ == '__main__':
+    main()
+