]> git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/rgwam.py
import quincy beta 17.1.0
[ceph.git] / ceph / src / rgw / rgwam.py
1 #!@Python3_EXECUTABLE@
2 # -*- mode:python -*-
3 # vim: ts=4 sw=4 smarttab expandtab
4 #
5 # Processed in Makefile to add python #! line and version variable
6 #
7 #
8
9 import subprocess
10 import random
11 import string
12 import json
13 import argparse
14 import sys
15 import socket
16 import base64
17 import logging
18
19 from urllib.parse import urlparse
20
21 from ceph.rgw.rgwam_core import RGWAM, EnvArgs
22 from ceph.rgw.types import RGWAMEnvMgr, RGWAMException
23
24 class RGWAMCLIMgr(RGWAMEnvMgr):
25 def __init__(self, common_args):
26 args = []
27
28 if common_args.conf_path:
29 args += [ '-c', common_args.conf_path ]
30
31 if common_args.ceph_name:
32 args += [ '-n', common_args.ceph_name ]
33
34 if common_args.ceph_keyring:
35 args += [ '-k', common_args.ceph_keyring ]
36
37 self.args_prefix = args
38
39 def tool_exec(self, prog, args):
40 run_cmd = [ prog ] + self.args_prefix + args
41
42 result = subprocess.run(run_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
43
44 stdout = result.stdout.decode('utf-8')
45 stderr = result.stderr.decode('utf-8')
46
47 return run_cmd, result.returncode, stdout, stderr
48
49 def apply_rgw(self, svc_id, realm_name, zone_name, port = None):
50 return None
51
52 def list_daemons(self, service_name, daemon_type = None, daemon_id = None, hostname = None, refresh = True):
53 return []
54
55 class RealmCommand:
56 def __init__(self, env, args):
57 self.env = env
58 self.args = args
59
60 def parse(self):
61 parser = argparse.ArgumentParser(
62 usage='''rgwam realm <subcommand>
63
64 The subcommands are:
65 bootstrap Bootstrap new realm
66 new-zone-creds Create credentials for connecting new zone
67 ''')
68 parser.add_argument('subcommand', help='Subcommand to run')
69 # parse_args defaults to [1:] for args, but you need to
70 # exclude the rest of the args too, or validation will fail
71 args = parser.parse_args(self.args[0:1])
72
73 sub = args.subcommand.replace('-', '_')
74
75 if not hasattr(self, sub):
76 print('Unrecognized subcommand:', args.subcommand)
77 parser.print_help()
78 exit(1)
79 # use dispatch pattern to invoke method with same name
80
81 return getattr(self, sub)
82
83 def bootstrap(self):
84 parser = argparse.ArgumentParser(
85 description='Bootstrap new realm',
86 usage='rgwam realm bootstrap [<args>]')
87 parser.add_argument('--realm')
88 parser.add_argument('--zonegroup')
89 parser.add_argument('--zone')
90 parser.add_argument('--endpoints')
91 parser.add_argument('--sys-uid')
92 parser.add_argument('--uid')
93 parser.add_argument('--start-radosgw', action='store_true', dest='start_radosgw', default=True)
94 parser.add_argument('--no-start-radosgw', action='store_false', dest='start_radosgw')
95
96 args = parser.parse_args(self.args[1:])
97
98 return RGWAM(self.env).realm_bootstrap(args.realm, args.zonegroup, args.zone, args.endpoints,
99 args.sys_uid, args.uid, args.start_radosgw)
100
101 def new_zone_creds(self):
102 parser = argparse.ArgumentParser(
103 description='Bootstrap new realm',
104 usage='rgwam realm new-zone-creds [<args>]')
105 parser.add_argument('--endpoints')
106 parser.add_argument('--sys-uid')
107
108 args = parser.parse_args(self.args[1:])
109
110 return RGWAM(self.env).realm_new_zone_creds(args.endpoints, args.sys_uid)
111
112
113 class ZoneCommand:
114 def __init__(self, env, args):
115 self.env = env
116 self.args = args
117
118 def parse(self):
119 parser = argparse.ArgumentParser(
120 usage='''rgwam zone <subcommand>
121
122 The subcommands are:
123 run run radosgw daemon in current zone
124 ''')
125 parser.add_argument('subcommand', help='Subcommand to run')
126 # parse_args defaults to [1:] for args, but you need to
127 # exclude the rest of the args too, or validation will fail
128 args = parser.parse_args(self.args[0:1])
129 if not hasattr(self, args.subcommand):
130 print('Unrecognized subcommand:', args.subcommand)
131 parser.print_help()
132 exit(1)
133 # use dispatch pattern to invoke method with same name
134 return getattr(self, args.subcommand)
135
136 def run(self):
137 parser = argparse.ArgumentParser(
138 description='Run radosgw daemon',
139 usage='rgwam zone run [<args>]')
140 parser.add_argument('--port')
141 parser.add_argument('--log-file')
142 parser.add_argument('--debug-ms')
143 parser.add_argument('--debug-rgw')
144
145 args = parser.parse_args(self.args[1:])
146
147 return RGWAM(self.env).run_radosgw(port = args.port)
148
149 def create(self):
150 parser = argparse.ArgumentParser(
151 description='Create new zone to join existing realm',
152 usage='rgwam zone create [<args>]')
153 parser.add_argument('--realm-token')
154 parser.add_argument('--zone')
155 parser.add_argument('--zonegroup')
156 parser.add_argument('--endpoints')
157 parser.add_argument('--start-radosgw', action='store_true', dest='start_radosgw', default=True)
158 parser.add_argument('--no-start-radosgw', action='store_false', dest='start_radosgw')
159
160 args = parser.parse_args(self.args[1:])
161
162 return RGWAM(self.env).zone_create(args.realm_token, args.zonegroup, args.zone, args.endpoints, args.start_radosgw)
163
164 class CommonArgs:
165 def __init__(self, ns):
166 self.conf_path = ns.conf_path
167 self.ceph_name = ns.ceph_name
168 self.ceph_keyring = ns.ceph_keyring
169
170 class TopLevelCommand:
171
172 def _parse(self):
173 parser = argparse.ArgumentParser(
174 description='RGW assist for multisite tool',
175 formatter_class=argparse.RawDescriptionHelpFormatter,
176 epilog='''
177 The commands are:
178 realm bootstrap Bootstrap new realm
179 realm new-zone-creds Create credentials to connect new zone to realm
180 zone create Create new zone and connect it to existing realm
181 zone run Run radosgw in current zone
182 ''')
183
184 parser.add_argument('command', help='command to run', default=None)
185 parser.add_argument('-c', help='ceph conf path', dest='conf_path')
186 parser.add_argument('-n', help='ceph user name', dest='ceph_name')
187 parser.add_argument('-k', help='ceph keyring', dest='ceph_keyring')
188
189 removed_args = []
190
191 args = sys.argv[1:]
192 if len(args) > 0:
193 if hasattr(self, args[0]):
194 # remove -h/--help if top command is not empty so that top level help
195 # doesn't override subcommand, we'll add it later
196 help_args = [ '-h', '--help' ]
197 removed_args = [arg for arg in args if arg in help_args]
198 args = [arg for arg in args if arg not in help_args]
199
200 (ns, args) = parser.parse_known_args(args)
201 if not hasattr(self, ns.command) or ns.command[0] == '_':
202 print('Unrecognized command:', ns.command)
203 parser.print_help()
204 exit(1)
205 # use dispatch pattern to invoke method with same name
206 args += removed_args
207 return (getattr(self, ns.command), CommonArgs(ns), args)
208
209 def realm(self, env, args):
210 cmd = RealmCommand(env, args).parse()
211 return cmd()
212
213 def zone(self, env, args):
214 cmd = ZoneCommand(env, args).parse()
215 return cmd()
216
217
218 def main():
219 logging.basicConfig(level=logging.INFO)
220
221 log = logging.getLogger(__name__)
222
223 (cmd, common_args, args)= TopLevelCommand()._parse()
224
225 env = EnvArgs(RGWAMCLIMgr(common_args))
226
227 try:
228 retval, out, err = cmd(env, args)
229 if retval != 0:
230 log.error('stdout: '+ out + '\nstderr: ' + err)
231 sys.exit(retval)
232 except RGWAMException as e:
233 print('ERROR: ' + e.message)
234
235 sys.exit(0)
236
237
238 if __name__ == '__main__':
239 main()
240