From c9a081037aa5bf15cf6226f06ea54ea98deba5bc Mon Sep 17 00:00:00 2001 From: Ade Lee Date: Mon, 18 Mar 2013 11:29:52 -0400 Subject: Refactor installation code to remove dependency on jython Connection is now made to the installation servlet through a python client using JSON. The code to construct the ConfgurationRequest and parse the results has been moved to pkihelper.py, and configuration.py no longer calls a separate jython process to create the Configuration object and parse the results. The jython code has therefore been removed. Also added status servlet to other java subsystems, to be tested prior to starting configuration. Trac Ticket 532 --- base/common/python/pki/account.py | 4 +-- base/common/python/pki/client.py | 24 +++++++++++++----- base/common/python/pki/encoder.py | 31 +++++++++++++++++++++++ base/common/python/pki/system.py | 52 ++++++++++++++++++++++++++++++++++++++- 4 files changed, 102 insertions(+), 9 deletions(-) create mode 100644 base/common/python/pki/encoder.py (limited to 'base/common/python/pki') diff --git a/base/common/python/pki/account.py b/base/common/python/pki/account.py index 84f2d0ef0..be87f8343 100644 --- a/base/common/python/pki/account.py +++ b/base/common/python/pki/account.py @@ -25,7 +25,7 @@ class AccountClient: self.connection = connection def login(self): - self.connection.get('account/login') + self.connection.get('/rest/account/login') def logout(self): - self.connection.get('account/logout') + self.connection.get('/rest/account/logout') diff --git a/base/common/python/pki/client.py b/base/common/python/pki/client.py index 7635fe879..05f42ba06 100644 --- a/base/common/python/pki/client.py +++ b/base/common/python/pki/client.py @@ -27,7 +27,8 @@ class PKIConnection: protocol='http', hostname='localhost', port=80, - subsystem='ca'): + subsystem='ca', + accept='application/json'): self.protocol = protocol self.hostname = hostname @@ -39,15 +40,26 @@ class PKIConnection: self.subsystem self.session = requests.Session() - self.session.headers.update({'Accept': 'application/json'}) + if accept: + self.session.headers.update({'Accept': accept}) def authenticate(self, username=None, password=None): if username is not None and password is not None: self.session.auth = (username, password) - def get(self, path): + def get(self, path, headers=None): r = self.session.get( - self.serverURI + '/rest/' + path, - verify=False) + self.serverURI + path, + verify=False, + headers=headers) r.raise_for_status() - return r \ No newline at end of file + return r + + def post(self, path, payload, headers=None): + r = self.session.post( + self.serverURI + path, + verify=False, + data=payload, + headers=headers) + r.raise_for_status() + return r diff --git a/base/common/python/pki/encoder.py b/base/common/python/pki/encoder.py new file mode 100644 index 000000000..7fee57e71 --- /dev/null +++ b/base/common/python/pki/encoder.py @@ -0,0 +1,31 @@ +import json +import pki.system + +TYPES = {} +NOTYPES = {} + +class CustomTypeEncoder(json.JSONEncoder): + """A custom JSONEncoder class that knows how to encode core custom + objects. + + Custom objects are encoded as JSON object literals (ie, dicts) with + one key, 'TypeName' where 'TypeName' is the actual name of the + type to which the object belongs. That single key maps to another + object literal which is just the __dict__ of the object encoded.""" + + def default(self, obj): + for k, v in TYPES.items(): + if isinstance(obj, v): + return { k: obj.__dict__ } + for k, v in NOTYPES.items(): + if isinstance(obj, v): + return obj.__dict__ + return json.JSONEncoder.default(self, obj) + + +def CustomTypeDecoder(dct): + if len(dct) == 1: + type_name, value = dct.items()[0] + if type_name in TYPES: + return TYPES[type_name].from_dict(value) + return dct diff --git a/base/common/python/pki/system.py b/base/common/python/pki/system.py index f49cc402e..23ad06bb2 100644 --- a/base/common/python/pki/system.py +++ b/base/common/python/pki/system.py @@ -19,6 +19,12 @@ # All rights reserved. # +import pki.encoder as encoder + +encoder.TYPES['ConfigurationRequest'] = ConfigurationRequest +encoder.TYPES['ConfigurationResponse'] = ConfigurationResponse +encoder.NOTYPES['SystemCertData'] = SystemCertData + class SecurityDomainInfo: def __init__(self): @@ -30,10 +36,54 @@ class SecurityDomainClient: self.connection = connection def getSecurityDomainInfo(self): - r = self.connection.get('securityDomain/domainInfo') + r = self.connection.get('/rest/securityDomain/domainInfo') j = r.json() info = SecurityDomainInfo() info.name = j['DomainInfo']['@id'] return info + +class ConfigurationRequest: + + def __init__(self): + self.token = "Internal Key Storage Token" + self.isClone = "false" + self.secureConn = "off" + self.importAdminCert = "false" + self.generateServerCert = "true" + +class ConfigurationResponse: + + def __init__(self): + pass + +class SystemCertData: + + def __init__(self): + pass + +class SystemConfigClient: + + def __init__(self, connection): + self.connection = connection + + def configure(self, data): + headers = {'Content-type': 'application/json', + 'Accept': 'application/json'} + r = self.connection.post('/rest/installer/configure', data, headers) + info = r.json()['ConfigurationResponse'] + return info + +class SystemStatusClient: + + def __init__(self, connection): + self.connection = connection + + def getStatus(self): + r = self.connection.get('/admin/' +\ + self.connection.subsystem + '/getStatus') + return r.text + + + -- cgit