def handler(catchall_path=None, fmt=None, target=None): ''' Main endpoint handler; generic for every endpoint, including catchall. Handles the catchall, anything with <.fmt>, anything with embedded <target>. Partial match or ?help cause the HTML-table "show_human_help" output. ''' ep = catchall_path or flask.request.endpoint ep = ep.replace('.<fmt>', '') if ep[0] != '/': ep = '/' + ep # demand that endpoint begin with app.ceph_baseurl if not ep.startswith(app.ceph_baseurl): return make_response(fmt, '', 'Page not found', 404) rel_ep = ep[len(app.ceph_baseurl) + 1:] # Extensions override Accept: headers override defaults if not fmt: if 'application/json' in flask.request.accept_mimetypes.values(): fmt = 'json' elif 'application/xml' in flask.request.accept_mimetypes.values(): fmt = 'xml' prefix = '' pgid = None cmdtarget = 'mon', '' if target: # got tell/<target>; validate osdid or pgid name = CephOsdName() pgidobj = CephPgid() try: name.valid(target) except ArgumentError: # try pgid try: pgidobj.valid(target) except ArgumentError: return flask.make_response("invalid osdid or pgid", 400) else: # it's a pgid pgid = pgidobj.val cmdtarget = 'pg', pgid else: # it's an osd cmdtarget = name.nametype, name.nameid # prefix does not include tell/<target>/ prefix = ' '.join(rel_ep.split('/')[2:]).strip() else: # non-target command: prefix is entire path prefix = ' '.join(rel_ep.split('/')).strip() # show "match as much as you gave me" help for unknown endpoints if ep not in app.ceph_urls: helptext = show_human_help(prefix) if helptext: resp = flask.make_response(helptext, 400) resp.headers['Content-Type'] = 'text/html' return resp else: return make_response(fmt, '', 'Invalid endpoint ' + ep, 400) found = None exc = '' for urldict in app.ceph_urls[ep]: if flask.request.method not in urldict['methods']: continue paramsig = urldict['paramsig'] # allow '?help' for any specifically-known endpoint if 'help' in flask.request.args: response = flask.make_response('{0}: {1}'. format(prefix + concise_sig(paramsig), urldict['help'])) response.headers['Content-Type'] = 'text/plain' return response # if there are parameters for this endpoint, process them if paramsig: args = {} for k, l in flask.request.args.iterlists(): if len(l) == 1: args[k] = l[0] else: args[k] = l # is this a valid set of params? try: argdict = validate(args, paramsig) found = urldict break except Exception as e: exc += str(e) continue else: if flask.request.args: continue found = urldict argdict = {} break if not found: return make_response(fmt, '', exc + '\n', 400) argdict['format'] = fmt or 'plain' argdict['module'] = found['module'] argdict['perm'] = found['perm'] if pgid: argdict['pgid'] = pgid if not cmdtarget: cmdtarget = ('mon', '') app.logger.debug('sending command prefix %s argdict %s', prefix, argdict) ret, outbuf, outs = json_command(app.ceph_cluster, prefix=prefix, target=cmdtarget, inbuf=flask.request.data, argdict=argdict) if ret: return make_response(fmt, '', 'Error: {0} ({1})'.format(outs, ret), 400) response = make_response(fmt, outbuf, outs or 'OK', 200) if fmt: contenttype = 'application/' + fmt.replace('-pretty', '') else: contenttype = 'text/plain' response.headers['Content-Type'] = contenttype return response
def handler(catchall_path=None, fmt=None, target=None): ''' Main endpoint handler; generic for every endpoint, including catchall. Handles the catchall, anything with <.fmt>, anything with embedded <target>. Partial match or ?help cause the HTML-table "show_human_help" output. ''' ep = catchall_path or flask.request.endpoint ep = ep.replace('.<fmt>', '') if ep[0] != '/': ep = '/' + ep # demand that endpoint begin with app.ceph_baseurl if not ep.startswith(app.ceph_baseurl): return make_response(fmt, '', 'Page not found', 404) rel_ep = ep[len(app.ceph_baseurl) + 1:] # Extensions override Accept: headers override defaults if not fmt: if 'application/json' in flask.request.accept_mimetypes.values(): fmt = 'json' elif 'application/xml' in flask.request.accept_mimetypes.values(): fmt = 'xml' prefix = '' pgid = None cmdtarget = 'mon', '' if target: # got tell/<target>; validate osdid or pgid name = CephOsdName() pgidobj = CephPgid() try: name.valid(target) except ArgumentError: # try pgid try: pgidobj.valid(target) except ArgumentError: return flask.make_response("invalid osdid or pgid", 400) else: # it's a pgid pgid = pgidobj.val cmdtarget = 'pg', pgid else: # it's an osd cmdtarget = name.nametype, name.nameid # prefix does not include tell/<target>/ prefix = ' '.join(rel_ep.split('/')[2:]).strip() else: # non-target command: prefix is entire path prefix = ' '.join(rel_ep.split('/')).strip() # show "match as much as you gave me" help for unknown endpoints if ep not in app.ceph_urls: helptext = show_human_help(prefix) if helptext: resp = flask.make_response(helptext, 400) resp.headers['Content-Type'] = 'text/html' return resp else: return make_response(fmt, '', 'Invalid endpoint ' + ep, 400) found = None exc = '' for urldict in app.ceph_urls[ep]: if flask.request.method not in urldict['methods']: continue paramsig = urldict['paramsig'] # allow '?help' for any specifically-known endpoint if 'help' in flask.request.args: response = flask.make_response('{0}: {1}'.format( prefix + concise_sig(paramsig), urldict['help'])) response.headers['Content-Type'] = 'text/plain' return response # if there are parameters for this endpoint, process them if paramsig: args = {} for k, l in flask.request.args.iterlists(): if len(l) == 1: args[k] = l[0] else: args[k] = l # is this a valid set of params? try: argdict = validate(args, paramsig) found = urldict break except Exception as e: exc += str(e) continue else: if flask.request.args: continue found = urldict argdict = {} break if not found: return make_response(fmt, '', exc + '\n', 400) argdict['format'] = fmt or 'plain' argdict['module'] = found['module'] argdict['perm'] = found['perm'] if pgid: argdict['pgid'] = pgid if not cmdtarget: cmdtarget = ('mon', '') app.logger.debug('sending command prefix %s argdict %s', prefix, argdict) for _ in range(DEFAULT_TRIES): ret, outbuf, outs = json_command(app.ceph_cluster, prefix=prefix, target=cmdtarget, inbuf=flask.request.data, argdict=argdict, timeout=DEFAULT_TIMEOUT) if ret != -errno.EINTR: break else: return make_response(fmt, '', 'Timedout: {0} ({1})'.format(outs, ret), 504) if ret: return make_response(fmt, '', 'Error: {0} ({1})'.format(outs, ret), 400) response = make_response(fmt, outbuf, outs or 'OK', 200) if fmt: contenttype = 'application/' + fmt.replace('-pretty', '') else: contenttype = 'text/plain' response.headers['Content-Type'] = contenttype return response
def handler(catchall_path=None, fmt=None, target=None): """ Main endpoint handler; generic for every endpoint, including catchall. Handles the catchall, anything with <.fmt>, anything with embedded <target>. Partial match or ?help cause the HTML-table "show_human_help" output. """ ep = catchall_path or flask.request.endpoint ep = ep.replace(".<fmt>", "") if ep[0] != "/": ep = "/" + ep # demand that endpoint begin with app.ceph_baseurl if not ep.startswith(app.ceph_baseurl): return make_response(fmt, "", "Page not found", 404) rel_ep = ep[len(app.ceph_baseurl) + 1 :] # Extensions override Accept: headers override defaults if not fmt: if "application/json" in flask.request.accept_mimetypes.values(): fmt = "json" elif "application/xml" in flask.request.accept_mimetypes.values(): fmt = "xml" prefix = "" pgid = None cmdtarget = "mon", "" if target: # got tell/<target>; validate osdid or pgid name = CephOsdName() pgidobj = CephPgid() try: name.valid(target) except ArgumentError: # try pgid try: pgidobj.valid(target) except ArgumentError: return flask.make_response("invalid osdid or pgid", 400) else: # it's a pgid pgid = pgidobj.val cmdtarget = "pg", pgid else: # it's an osd cmdtarget = name.nametype, name.nameid # prefix does not include tell/<target>/ prefix = " ".join(rel_ep.split("/")[2:]).strip() else: # non-target command: prefix is entire path prefix = " ".join(rel_ep.split("/")).strip() # show "match as much as you gave me" help for unknown endpoints if not ep in app.ceph_urls: helptext = show_human_help(prefix) if helptext: resp = flask.make_response(helptext, 400) resp.headers["Content-Type"] = "text/html" return resp else: return make_response(fmt, "", "Invalid endpoint " + ep, 400) found = None exc = "" for urldict in app.ceph_urls[ep]: if flask.request.method not in urldict["methods"]: continue paramsig = urldict["paramsig"] # allow '?help' for any specifically-known endpoint if "help" in flask.request.args: response = flask.make_response("{0}: {1}".format(prefix + concise_sig(paramsig), urldict["help"])) response.headers["Content-Type"] = "text/plain" return response # if there are parameters for this endpoint, process them if paramsig: args = {} for k, l in flask.request.args.iterlists(): if len(l) == 1: args[k] = l[0] else: args[k] = l # is this a valid set of params? try: argdict = validate(args, paramsig) found = urldict break except Exception as e: exc += str(e) continue else: if flask.request.args: continue found = urldict argdict = {} break if not found: return make_response(fmt, "", exc + "\n", 400) argdict["format"] = fmt or "plain" argdict["module"] = found["module"] argdict["perm"] = found["perm"] if pgid: argdict["pgid"] = pgid if not cmdtarget: cmdtarget = ("mon", "") app.logger.debug("sending command prefix %s argdict %s", prefix, argdict) ret, outbuf, outs = json_command( app.ceph_cluster, prefix=prefix, target=cmdtarget, inbuf=flask.request.data, argdict=argdict ) if ret: return make_response(fmt, "", "Error: {0} ({1})".format(outs, ret), 400) response = make_response(fmt, outbuf, outs or "OK", 200) if fmt: contenttype = "application/" + fmt.replace("-pretty", "") else: contenttype = "text/plain" response.headers["Content-Type"] = contenttype return response