Skip to content

Instantly share code, notes, and snippets.

@kvaps
Created August 11, 2020 09:34
Show Gist options
  • Save kvaps/44bc755e2bd115e99fdcc5cb88a0d476 to your computer and use it in GitHub Desktop.
Save kvaps/44bc755e2bd115e99fdcc5cb88a0d476 to your computer and use it in GitHub Desktop.
Example XML-RPC filtering script for OpenNebula
#!/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