Mini Shell
# rhn-client-tools
#
# Copyright (c) 2006--2016 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301 USA
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the
# OpenSSL library under certain conditions as described in each
# individual source file, and distribute linked combinations
# including the two.
# You must obey the GNU General Public License in all respects
# for all of the code used other than OpenSSL. If you modify
# file(s) with this exception, you may extend this exception to your
# version of the file(s), but you are not obligated to do so. If you
# do not wish to do so, delete this exception statement from your
# version. If you delete this exception statement from all source
# files in the program, then also delete it here.
from rhn.tb import raise_with_tb
from up2date_client import rpcServer
from up2date_client import up2dateErrors
from up2date_client import capabilities
import sys
import OpenSSL
try: # python2
import xmlrpclib
except ImportError: # python3
import xmlrpc.client as xmlrpclib
class _DoCallWrapper(object):
"""
A callable object that will handle multiple levels of attributes,
and catch exceptions.
"""
def __init__(self, server, method_name):
self._server = server
self._method_name = method_name
def __getattr__(self, method_name):
""" Recursively build up the method name to pass to the server. """
return _DoCallWrapper(self._server,
"%s.%s" % (self._method_name, method_name))
def __call__(self, *args, **kwargs):
""" Call the method. Catch faults and translate them. """
method = getattr(self._server, self._method_name)
try:
return rpcServer.doCall(method, *args, **kwargs)
except xmlrpclib.Fault:
raise_with_tb(self.__exception_from_fault(sys.exc_info()[1]))
except OpenSSL.SSL.Error:
# TODO This should probably be moved to rhnlib and raise an
# exception that subclasses OpenSSL.SSL.Error
# TODO Is there a better way to detect cert failures?
error = str(sys.exc_info()[1])
error = error.strip("[()]")
pieces = error.split(',')
message = ""
if len(pieces) > 2:
message = pieces[2]
elif len(pieces) == 2:
message = pieces[1]
message = message.strip(" '")
if message == 'certificate verify failed':
raise_with_tb(up2dateErrors.SSLCertificateVerifyFailedError())
else:
raise_with_tb(up2dateErrors.NetworkError(message))
def __exception_from_fault(self, fault):
if fault.faultCode == -3:
# This username is already taken, or the password is incorrect.
exception = up2dateErrors.AuthenticationOrAccountCreationError(fault.faultString)
elif fault.faultCode == -2:
# Invalid username and password combination.
exception = up2dateErrors.AuthenticationOrAccountCreationError(fault.faultString)
elif fault.faultCode == -110:
# Account is disabled
exception = up2dateErrors.AuthenticationOrAccountCreationError(fault.faultString)
elif fault.faultCode == -1:
exception = up2dateErrors.UnknownMethodException(fault.faultString)
elif fault.faultCode == -13:
# Username is too short.
exception = up2dateErrors.LoginMinLengthError(fault.faultString)
elif fault.faultCode == -14:
# too short password
exception = up2dateErrors.PasswordMinLengthError(
fault.faultString)
elif fault.faultCode == -15:
# bad chars in username
exception = up2dateErrors.ValidationError(fault.faultString)
elif fault.faultCode == -16:
# Invalid product registration code.
# TODO Should this really be a validation error?
exception = up2dateErrors.ValidationError(fault.faultString)
elif fault.faultCode == -19:
# invalid
exception = up2dateErrors.NoBaseChannelError(fault.faultString)
elif fault.faultCode == -31:
# No entitlement
exception = up2dateErrors.InsuffMgmntEntsError(fault.faultString)
elif fault.faultCode == -36:
# rhnException.py says this means "Invalid action."
# TODO find out which is right
exception = up2dateErrors.PasswordError(fault.faultString)
elif abs(fault.faultCode) == 49:
exception = up2dateErrors.AbuseError(fault.faultString)
elif abs(fault.faultCode) == 60:
exception = up2dateErrors.AuthenticationTicketError(fault.faultString)
elif abs(fault.faultCode) == 74:
exception = up2dateErrors.RegistrationDeniedError()
elif abs(fault.faultCode) == 105:
exception = up2dateErrors.RhnUuidUniquenessError(fault.faultString)
elif fault.faultCode == 99:
exception = up2dateErrors.DelayError(fault.faultString)
elif abs(fault.faultCode) == 91:
exception = up2dateErrors.InsuffMgmntEntsError(fault.faultString)
elif fault.faultCode == -106:
# Invalid username.
exception = up2dateErrors.ValidationError(fault.faultString)
elif fault.faultCode == -600:
# Invalid username.
exception = up2dateErrors.InvalidRegistrationNumberError(fault.faultString)
elif fault.faultCode == -601:
# No entitlements associated with given hardware info
exception = up2dateErrors.NotEntitlingError(fault.faultString)
elif fault.faultCode == -602:
# No entitlements associated with reg num
exception = up2dateErrors.NotEntitlingError(fault.faultString)
elif fault.faultCode == -2001 or fault.faultCode == -700:
exception = up2dateErrors.AuthenticationOrAccountCreationError(
fault.faultString)
elif fault.faultCode == -701:
exception = up2dateErrors.PasswordMaxLengthError(
fault.faultString)
elif fault.faultCode == -61:
exception = up2dateErrors.ActivationKeyUsageLimitError(
fault.faultString)
elif fault.faultCode == -5:
exception = up2dateErrors.UnableToCreateUser(
fault.faultString)
else:
exception = up2dateErrors.CommunicationError(fault.faultString)
return exception
class RhnServer(object):
"""
An rpc server object that calls doCall for you, and catches lower
level exceptions
"""
def __init__(self, serverOverride=None, timeout=None, rpcServerOverride=None):
if rpcServerOverride is None:
self._server = rpcServer.getServer(serverOverride=serverOverride,
timeout=timeout)
else:
self._server = rpcServerOverride
self._capabilities = None
def __get_capabilities(self):
if self._capabilities is None:
headers = self._server.get_response_headers()
if headers is None:
self.registration.welcome_message()
headers = self._server.get_response_headers()
self._capabilities = capabilities.Capabilities()
self._capabilities.populate(headers)
return self._capabilities
capabilities = property(__get_capabilities)
def add_header(self, key, value):
self._server.add_header(key, value)
def __getattr__(self, method_name):
""" Return a callable object that will do the work for us. """
return _DoCallWrapper(self._server, method_name)
Zerion Mini Shell 1.0