Created
August 11, 2020 09:34
-
-
Save kvaps/44bc755e2bd115e99fdcc5cb88a0d476 to your computer and use it in GitHub Desktop.
Example XML-RPC filtering script for OpenNebula
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
from xmlrpc.server import SimpleXMLRPCServer | |
import xmlrpc.client | |
import xmltodict | |
import re | |
import os | |
import argparse | |
import logging | |
from socketserver import ThreadingMixIn | |
parser = argparse.ArgumentParser(description='Great Description To Be Here') | |
parser.add_argument("-f", "--filter", help="filter users by regexp [default: .*]", action="store", default=".*") | |
parser.add_argument("-v", "--verbose", help="increase output verbosity", action="store_true") | |
parser.add_argument("-b", "--bind", help="Specify alternate bind address [default: all interfaces]", action="store", metavar='ADDRESS', default="0.0.0.0") | |
parser.add_argument('port', help="Specify alternate port [default: 9000]", action="store", nargs='?', default=9000, type=int) | |
args = parser.parse_args() | |
# Setup logging | |
if args.verbose: | |
logging.basicConfig(level=logging.DEBUG, format='%(levelname)s: %(message)s') | |
else: | |
logging.basicConfig(level=logging.INFO, format='%(levelname)s: %(message)s') | |
# Setup XML-RPC client | |
try: | |
one_s = os.environ['ONE_XMLRPC'] | |
except: | |
one_s = 'http://localhost:2633/RPC2' | |
# Print info | |
logging.info('Upper server: ' + one_s) | |
logging.info('Listen on: http://' + args.bind + ':' + str(args.port) + '/RPC2') | |
logging.info('Before play, don\'t forget to run:') | |
logging.info('export ONE_XMLRPC=http://localhost:' + str(args.port) + '/RPC2') | |
# Setup XML-RPC server | |
class MyXMLRPCServer(ThreadingMixIn, SimpleXMLRPCServer): | |
pass | |
server = MyXMLRPCServer( | |
(args.bind, args.port), | |
logRequests=False,encoding='UTF-8' | |
) | |
# Define methods handler | |
class one: | |
def _dispatch(self, method, params): | |
# Make client | |
s = xmlrpc.client.ServerProxy(one_s) | |
logging.debug('Method called: ' + method + ' ' + str(params[1:])) | |
# ------------------------------------------------------------------------ | |
# Filter user by username | |
# ------------------------------------------------------------------------ | |
if method.startswith("one."): | |
token = params[0] | |
user_name = token.split(':')[0] | |
if not bool(re.match(args.filter, user_name)): | |
logging.info('User ' + user_name + ' filtered.' ) | |
answer = False, "[opennebula-filter] Invalid username", -1 | |
logging.debug('Answer: ' + str(answer)) | |
return answer | |
# ------------------------------------------------------------------------ | |
# Show reliable error, when quota limit for system disks has reached | |
# Workaround: https://github.com/OpenNebula/one/issues/3610 | |
# ------------------------------------------------------------------------ | |
if method == 'one.vm.attach': | |
try: | |
answer = getattr(s, 'one.vm.attach')(token, params[1], params[2]) | |
except: | |
answer = False, "[opennebula-filter] limit reached for SYSTEM_DISK_SIZE quota in VM.", -1 | |
logging.debug('Answer: ' + str(answer)) | |
return answer | |
return answer | |
if method == 'ping': | |
return(False, 'pong', -1) | |
# ------------------------------------------------------------------------ | |
# Everything is ok, let's ask server | |
# ------------------------------------------------------------------------ | |
answer = getattr(s, method)(*params) | |
logging.debug('Answer: ' + str(answer)) | |
return answer | |
# Register methods handler | |
server.register_instance(one()) | |
# Start XML-RPC server | |
server.serve_forever() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment