Thanks Fraser and Ade. Pushed the patches 97 and 98-3 to master. Closed the ProfileClient ticket. #1022 Opened the following ticket on Ade's suggestion - https://fedorahosted.org/pki/ticket/1060 --Abhishek On Tue, 2014-07-01 at 20:52 +0800, Ade Lee wrote:
On Mon, 2014-06-30 at 13:29 +1000, Fraser Tweedale wrote:
On Fri, Jun 27, 2014 at 01:08:13PM -0400, Abhishek Koneru wrote:
Please review the patch with fixes for Ade's comments on patch 98-2. Addressed all the comments except 8 and 10. which will be done separately.
Patch does seem to address those issues and __main__ still works nicely (including removing the added profile at end now - thanks).
Switching to serialising the profile as JSON now means that the upload-xml-profile codepath is no longer exercised by __main__. Not a blocker I think, but if it's easy to write out a profile as XML so that codepath is exercised, that would be a good idea.
ACK. Please open a ticket to add the missing XML tests/functions. We can triage accordingly. I would suggest a milestone of 10.3.
Ade
ACK modulo preceding comment.
Please apply patch 97 before applying 98-3 --Abhishek
On Thu, 2014-06-26 at 00:47 +0800, Ade Lee wrote:
In profile.py:
1. Usually, we set @author and so on after the copyright notice.
2. In PolicyDefault, you have methods to add/remove/get attributes and parameters, as in: def add_attribute(self, profile_attribute): self.policy_attributes.append(profile_attribute)
Change profile_attribute to policy_attribute etc. You should indicate in a docstring that the expected type for the policy_attribute etc. is a ProfileAttribute.
3. I'm not a big fan of your _send_profile_request() and _send_request_in_file() methods in that they mix create and update operations. That might make sense if the operations had a lot of common code and were doing the same HTTP operation, but otherwise is just confusing.
A better way to split this up might be to define:
def _send_profile_create(self, profile_data)
def _send_profile_modify(self, profile_id, profile_data)
@staticmethod def _get_profile_data_from_file(path_to_file, file_format)
and then call these as needed.
So for example, create_profile_using_file_input(self, path_to_file, file_format) -> which I would rename to create_profile_from_file(..) -> would call: profile_data = _get_profile_data_from_file(path_to_file, file_format) _send_profile_create(profile_data)
4. In the test where you add a duplicate profile, you should check for the specific exception thrown -- is there a specific exception?
5. Change the profileID in the test to MySampleProfile instead of MySampleCert.
6. In the test, we are testing file input using original.xml and modified.xml. Where do these files come from? It would be better if these files were generated as part of the previous tests - which means you need a function to save files to xml/json. You should then test xml and json.
7. The policy stuff gets confusing fast, so the example really helps. We need more function docstrings though that specify when inputs/outputs the functions have - and in particular the class of each input.
8. We also need more api documentation on the wiki as we have done in the past. This is not part of this patch of course.
9. There are Pycharm errors about unused variables. Most of these will be addressed by the refactoring I mention in point 3 above.
10. profile.py - which is all new code generates probably close to 200 new messages in pylint. We really should fix these. To keep things clear, you should do this in a separate patch.
On Wed, 2014-06-25 at 16:49 +1000, Fraser Tweedale wrote:
On Tue, Jun 24, 2014 at 05:32:25PM -0400, Abhishek Koneru wrote:
Please review the patch with fixes for comments on patch 98. Issues addressed: 1. Added a try catch block for issue 1(as noted below) caught by ftweedal(nice catch!). 2. Made the data_format mandatory for file_input methods. 3. Added code to create a profile with PolicyOutput and PolicySets.
-- Abhishek Please apply patch 97 before applying this patch.
ACK
On Fri, 2014-06-20 at 12:02 +1000, Fraser Tweedale wrote: > On Thu, Jun 19, 2014 at 09:58:43AM -0400, Abhishek Koneru wrote: > > Please review the attached patch which adds methods that allow users to > > pass the profile data in a file. > > > > Also attached two sample xml files, original.xml and modified.xml. > > Place them in /tmp before running the profile.py module. > > > > Thanks, > > Abhishek > > > > Hi Abhishek, > > Patch applied and __main__ example run. Seems to do what it says on > the tin; the usual "haven't used it in anger" caveat ^_^. Review > comments inline below. > > Fraser > > > + @pki.handle_exceptions() > > def modify_profile(self, profile_data): > > """ > > Modify an existing profile. > > """ > > - if profile_data is None: > > - raise ValueError("No ProfileData specified") > > + return self._send_profile_request(profile_data, 'modify') > > + > > + def _send_request_in_file(self, path_to_file, data_format, operation): > > + > > + if path_to_file is None: > > + raise ValueError("File path must be specified.") > > + > > + if data_format not in ['xml', 'json']: > > + raise ValueError("Unsupported data type: " + str(data_format)) > > + > > + if operation not in ['create', 'modify']: > > + raise ValueError("Invalid operation specified: " + str(operation)) > > + > > + data = None > > + with open(path_to_file) as input_file: > > + data = input_file.read() > > + > > + if data_format == 'xml': > > + self.headers['Content-type'] = 'application/xml' > > 1) > > Overwriting self.headers['Content-type'] is problematic. For > example, if the data cannot be parsed or lacks an 'id' key, an > exception will be raised and the ProfileClient will be stuck with > the wrong Content-Type header. > > Possible solutions: > > - use try/finally or a context manager to ensure the header gets > reset to 'application/json' even if an exception is raised. > - Modify the _put and _post methods to include an optional argument > to override the content-type header. To avoid special-cases too > many things, this arg could even be a dict that can be merged with > the default headers, e.g.: > > def _post(self, url, payload=None, headers=None): > self.account_client.login() > headers = dict(self.headers, **(headers or {})) > r = self.connection.post(url, payload, headers, query_params) > ... > > Then callers can supply custom headers for a single request > without potentially affecting other requests. > > > + > > + r = None > > + # Sending the data to the server. > > + if operation == 'create': > > + r = self._post(self.profiles_url, data) > > + else: > > + profile_id = None > > + if data_format == 'xml': > > + profile_id = etree.fromstring(data).get('id') > > + else: > > + profile_id = json.loads(data)['id'] > > + > > + if profile_id is None: > > + raise ValueError('Profile Id is not specified.') > > + url = self.profiles_url + '/' + profile_id > > + r = self._put(url, data) > > + > > + # Reset the Content-type header to json(As used by other methods). > > + if data_format == 'xml': > > + self.headers['Content-type'] = 'application/json' > > > > - url = self.profiles_url + '/' + str(profile_data.profile_id) > > - profile_object = json.dumps(profile_data, cls=encoder.CustomTypeEncoder, > > - sort_keys=True) > > - r = self._put(url, profile_object) > > return Profile.from_json(r.json()) > > > > + @pki.handle_exceptions() > > + def create_profile_using_file_input(self, path_to_file, data_format="xml"): > > + """ > > + Create a new profile from a profile object stored in a file. > > + Acceptable data formats - json, xml. > > + """ > > + return self._send_request_in_file(path_to_file, data_format, 'create') > > + > > 2) > > Default ``data_format="xml"`` makes it too easy for people to misuse > the API, e.g. a path to a JSON file, but no ``data_format`` kwarg > given, resulting in default "xml" being used. I suggest either > making it a compulsory argument, or making its default ``None`` and, > if no explicit ``data_format`` arg given, using the file extension. > > > > + @pki.handle_exceptions() > > + def modify_profile_using_file_input(self, path_to_file, data_format="xml"): > > + """ > > + Modify a profile from a profile object stored in a file. > > + Acceptable data formats - json, xml. > > + """ > > + return self._send_request_in_file(path_to_file, data_format, 'modify') > > + > > + @pki.handle_exceptions() > > def delete_profile(self, profile_id): > > """ > > Delete a profile. > > @@ -1185,6 +1253,23 @@ def main(): > > # pylint: disable-msg=W0703 > > except Exception as e: > > print str(e) > > + print > > + > > + # Creating a profile from file > > + print('Creating a profile using file input.') > > + print('------------------------------------') > > + original = profile_client.create_profile_using_file_input( > > + '/tmp/original.xml') > > + print(original) > > + print > > + > > + # Modifying a profile from file > > + print('Modifying a profile using file input.') > > + print('------------------------------------') > > + modified = profile_client.modify_profile_using_file_input( > > + '/tmp/modified.xml') > > + print(modified) > > + print > > 3) > > Nit-pick: could you delete the created profile here so that the > example can be run multiple times?
From 3a031e463e6fb0b5658ad9e1bc37a018c99f32de Mon Sep 17 00:00:00 2001 From: Abhishek Koneru <akoneru@redhat.com> Date: Thu, 19 Jun 2014 00:10:13 -0400 Subject: [PATCH] Added methods for providing file input for profile request.
Added new methods to allow user to provide file input to perform operations like create profile/modify profile. The supported file formats a re xml and json. --- base/common/python/pki/__init__.py | 4 +- base/common/python/pki/profile.py | 265 ++++++++++++++++++++++++++++++++++--- 2 files changed, 252 insertions(+), 17 deletions(-)
diff --git a/base/common/python/pki/__init__.py b/base/common/python/pki/__init__.py index e9b726cf763785b4a700ef314ff27774b13aba40..891d6ea6364b037f132ff3754b73b372c638b0f7 100644 --- a/base/common/python/pki/__init__.py +++ b/base/common/python/pki/__init__.py @@ -168,7 +168,7 @@ class PKIException(Exception, ResourceMessage): ret = cls(json_value['Message'], json_value['Code'], json_value['ClassName']) for attr in json_value['Attributes']['Attribute']: - print(str(attr)) + print str(attr) ret.add_attribute(attr["name"], attr["value"]) return ret
@@ -299,7 +299,7 @@ class PropertyFile(object): def show(self): """ Show contents of property file.""" for line in self.lines: - print(line) + print line
def insert_line(self, index, line): """ Insert line in property file """ diff --git a/base/common/python/pki/profile.py b/base/common/python/pki/profile.py index 4f08ee5ba9527855f63b2785c32f9aaddc8d1289..2d4ce5ace11bc6417032fb89ecf6b18707b6fca0 100644 --- a/base/common/python/pki/profile.py +++ b/base/common/python/pki/profile.py @@ -1,12 +1,27 @@ #!/usr/bin/python """ -Created on May 13,, 2014 +@author: Abhishek Koneru <akoneru@redhat.com>
-@author: akoneru + 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. + + Copyright (C) 2014 Red Hat, Inc. + All rights reserved. """
import json import types +from lxml import etree
import pki import pki.client as client @@ -433,6 +448,38 @@ class PolicyDefault(object): def policy_params(self, value): setattr(self, 'params', value)
+ def add_attribute(self, profile_attribute): + self.policy_attributes.append(profile_attribute) + + def remove_attribute(self, profile_attribute_name): + for attr in self.policy_attributes: + if attr.name == profile_attribute_name: + self.policy_attributes.remove(attr) + break + + def get_attribute(self, profile_attribute_name): + for attr in self.policy_attributes: + if attr.name == profile_attribute_name: + return attr + + return None + + def add_parameter(self, profile_parameter): + self.policy_params.append(profile_parameter) + + def remove_parameter(self, profile_parameter_name): + for param in self.policy_params: + if param.name == profile_parameter_name: + self.policy_params.remove(param) + break + + def get_parameter(self, profile_parameter_name): + for param in self.policy_params: + if param.name == profile_parameter_name: + return param + + return None + @classmethod def from_json(cls, json_value): policy_def = cls() @@ -531,6 +578,22 @@ class PolicyConstraint(object): def policy_constraint_values(self, value): setattr(self, 'constraint', value)
+ def add_constraint_value(self, policy_constraint_value): + self.policy_constraint_values.append(policy_constraint_value) + + def remove_attribute(self, policy_constraint_value_name): + for attr in self.policy_constraint_values: + if attr.name == policy_constraint_value_name: + self.policy_constraint_values.remove(attr) + break + + def get_attribute(self, policy_constraint_value_name): + for constraint in self.policy_constraint_values: + if constraint.name == policy_constraint_value_name: + return constraint + + return None + @classmethod def from_json(cls, json_value): policy_constraint = cls() @@ -995,31 +1058,99 @@ class ProfileClient(object): """ return self._modify_profile_state(profile_id, 'disable')
+ def _send_profile_request(self, profile_data, operation): + + if profile_data is None: + raise ValueError("No ProfileData specified") + + if operation not in ['create', 'modify']: + raise ValueError("Invalid operation specified: " + str(operation)) + + profile_object = json.dumps(profile_data, cls=encoder.CustomTypeEncoder, + sort_keys=True) + r = None + if operation == 'create': + r = self._post(self.profiles_url, profile_object) + else: + if profile_data.profile_id is None: + raise ValueError("Profile Id is not specified.") + url = self.profiles_url + '/' + str(profile_data.profile_id) + r = self._put(url, profile_object) + + return Profile.from_json(r.json()) + + @pki.handle_exceptions() def create_profile(self, profile_data): """ Create a new profile for the given ProfileData object. """ - if profile_data is None: - raise ValueError("No ProfileData specified") - - profile_object = json.dumps(profile_data, cls=encoder.CustomTypeEncoder, - sort_keys=True) - r = self._post(self.profiles_url, profile_object) - return Profile.from_json(r.json()) + return self._send_profile_request(profile_data, 'create')
+ @pki.handle_exceptions() def modify_profile(self, profile_data): """ Modify an existing profile. """ - if profile_data is None: - raise ValueError("No ProfileData specified") + return self._send_profile_request(profile_data, 'modify') + + def _send_request_in_file(self, path_to_file, data_format, operation): + + if path_to_file is None: + raise ValueError("File path must be specified.") + + if data_format not in ['xml', 'json']: + raise ValueError("Unsupported data type: " + str(data_format)) + + if operation not in ['create', 'modify']: + raise ValueError("Invalid operation specified: " + str(operation)) + + data = None + with open(path_to_file) as input_file: + data = input_file.read() + + if data_format == 'xml': + self.headers['Content-type'] = 'application/xml' + + r = None + try: + # Sending the data to the server. + if operation == 'create': + r = self._post(self.profiles_url, data) + else: + profile_id = None + if data_format == 'xml': + profile_id = etree.fromstring(data).get('id') + else: + profile_id = json.loads(data)['id'] + + if profile_id is None: + raise ValueError('Profile Id is not specified.') + url = self.profiles_url + '/' + profile_id + r = self._put(url, data) + finally: + # Reset the Content-type header to json(As used by other methods). + if data_format == 'xml': + self.headers['Content-type'] = 'application/json'
- url = self.profiles_url + '/' + str(profile_data.profile_id) - profile_object = json.dumps(profile_data, cls=encoder.CustomTypeEncoder, - sort_keys=True) - r = self._put(url, profile_object) return Profile.from_json(r.json())
+ @pki.handle_exceptions() + def create_profile_using_file_input(self, path_to_file, data_format): + """ + Create a new profile from a profile object stored in a file. + Acceptable data formats - json, xml. + """ + return self._send_request_in_file(path_to_file, data_format, 'create') + + @pki.handle_exceptions() + def modify_profile_using_file_input(self, path_to_file, data_format): + """ + Modify a profile from a profile object stored in a file. + Acceptable data formats - json, xml. + """ + return self._send_request_in_file(path_to_file, data_format, 'modify') + + @pki.handle_exceptions() def delete_profile(self, profile_id): """ Delete a profile. @@ -1108,6 +1239,7 @@ def main(): renewal=False, xml_output=False, authorization_acl="")
+ # Adding a profile input profile_input = ProfileInput("i1", "subjectNameInputImpl") profile_input.add_attribute(ProfileAttribute("sn_uid")) profile_input.add_attribute(ProfileAttribute("sn_e")) @@ -1121,6 +1253,92 @@ def main():
profile_data.add_input(profile_input)
+ # Adding a profile output + profile_output = ProfileOutput("o1", name="Certificate Output", + class_id="certOutputImpl") + profile_output.add_attribute(ProfileAttribute("pretty_cert")) + profile_output.add_attribute(ProfileAttribute("b64_cert")) + + profile_data.add_output(profile_output) + + # Create a Policy set with a list of profile policies + policy_list = [] + + # Creating profile policy + policy_default = PolicyDefault("Subject Name Default", + "userSubjectNameDefaultImpl", + "This default populates a User-Supplied " + "Certificate Subject Name to the request.") + + attr_descriptor = Descriptor(syntax="string", description="Subject Name") + policy_attribute = ProfileAttribute("name", descriptor=attr_descriptor) + policy_default.add_attribute(policy_attribute) + + policy_constraint = PolicyConstraint("Subject Name Constraint", + "This constraint accepts the subject " + "name that matches UID=.*", + "subjectNameConstraintImpl") + constraint_descriptor = Descriptor(syntax="string", + description="Subject Name Pattern") + policy_constraint_value = PolicyConstraintValue("pattern", + "UID=.*", + constraint_descriptor) + policy_constraint.add_constraint_value(policy_constraint_value) + + policy_list.append(ProfilePolicy("1", policy_default, policy_constraint)) + + # Creating another profile policy + # Defining the policy default + policy_default = PolicyDefault("Validity Default", "validityDefaultImpl", + "This default populates a Certificate " + "Validity to the request. The default " + "values are Range=180 in days") + attr_descriptor = Descriptor(syntax="string", description="Not Before") + policy_attribute = ProfileAttribute("notBefore", descriptor=attr_descriptor) + policy_default.add_attribute(policy_attribute) + + attr_descriptor = Descriptor(syntax="string", description="Not After") + policy_attribute = ProfileAttribute("notAfter", descriptor=attr_descriptor) + policy_default.add_attribute(policy_attribute) + + profile_param = ProfileParameter("range", 180) + profile_param2 = ProfileParameter("startTime", 0) + policy_default.add_parameter(profile_param) + policy_default.add_parameter(profile_param2) + + #Defining the policy constraint + policy_constraint = PolicyConstraint("Validity Constraint", + "This constraint rejects the validity " + "that is not between 365 days.", + "validityConstraintImpl") + constraint_descriptor = Descriptor(syntax="integer", + description="Validity Range (in days)", + default_value=365) + policy_constraint_value = PolicyConstraintValue("range", 365, + constraint_descriptor) + policy_constraint.add_constraint_value(policy_constraint_value) + + constraint_descriptor = Descriptor(syntax="boolean", default_value=False, + description="Check Not Before against" + " current time") + policy_constraint_value = PolicyConstraintValue("notBeforeCheck", False, + constraint_descriptor) + policy_constraint.add_constraint_value(policy_constraint_value) + + constraint_descriptor = Descriptor(syntax="boolean", default_value=False, + description="Check Not After against" + " Not Before") + policy_constraint_value = PolicyConstraintValue("notAfterCheck", False, + constraint_descriptor) + policy_constraint.add_constraint_value(policy_constraint_value) + + policy_list.append(ProfilePolicy("2", policy_default, policy_constraint)) + + policy_set = PolicySet("userCertSet", policy_list) + + profile_data.add_policy_set(policy_set) + + # Create a new profile created_profile = profile_client.create_profile(profile_data) print(created_profile) print @@ -1185,6 +1403,23 @@ def main(): # pylint: disable-msg=W0703 except Exception as e: print str(e) + print + + # Creating a profile from file + print('Creating a profile using file input.') + print('------------------------------------') + original = profile_client.create_profile_using_file_input( + '/tmp/original.xml', 'xml') + print(original) + print + + # Modifying a profile from file + print('Modifying a profile using file input.') + print('------------------------------------') + modified = profile_client.modify_profile_using_file_input( + '/tmp/modified.xml', 'xml') + print(modified) + print
if __name__ == "__main__": -- 1.8.5.3
_______________________________________________ Pki-devel mailing list Pki-devel@redhat.com https://www.redhat.com/mailman/listinfo/pki-devel
From 6f0acdb884fa8306be8d3478a22becb301cb6d79 Mon Sep 17 00:00:00 2001 From: Abhishek Koneru <akoneru@redhat.com> Date: Thu, 19 Jun 2014 00:10:13 -0400 Subject: [PATCH] Added methods for providing file input for profile request.
Added new methods to allow user to provide file input to perform operations like create profile/modify profile. The supported file formats a re xml and json. --- base/common/python/pki/__init__.py | 7 +- base/common/python/pki/profile.py | 636 +++++++++++++++++++++++++++++++------ 2 files changed, 541 insertions(+), 102 deletions(-)
diff --git a/base/common/python/pki/__init__.py b/base/common/python/pki/__init__.py index e9b726cf763785b4a700ef314ff27774b13aba40..b610a9f8d9dc13dcdaf1e7cc920a204d0277d3f3 100644 --- a/base/common/python/pki/__init__.py +++ b/base/common/python/pki/__init__.py @@ -168,7 +168,7 @@ class PKIException(Exception, ResourceMessage): ret = cls(json_value['Message'], json_value['Code'], json_value['ClassName']) for attr in json_value['Attributes']['Attribute']: - print(str(attr)) + print str(attr) ret.add_attribute(attr["name"], attr["value"]) return ret
@@ -299,7 +299,7 @@ class PropertyFile(object): def show(self): """ Show contents of property file.""" for line in self.lines: - print(line) + print line
def insert_line(self, index, line): """ Insert line in property file """ @@ -403,6 +403,9 @@ class Link:
@classmethod def from_json(cls, attr_list): + if attr_list is None: + return None + link = cls() for attr in attr_list: setattr(link, attr, attr_list[attr]) diff --git a/base/common/python/pki/profile.py b/base/common/python/pki/profile.py index 4f08ee5ba9527855f63b2785c32f9aaddc8d1289..f8caf10e0a89773f3287899c68a9ce60da5cee0e 100644 --- a/base/common/python/pki/profile.py +++ b/base/common/python/pki/profile.py @@ -1,13 +1,29 @@ #!/usr/bin/python """ -Created on May 13,, 2014 + 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.
-@author: akoneru + 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. + + Copyright (C) 2014 Red Hat, Inc. + All rights reserved. + + @author: Abhishek Koneru <akoneru@redhat.com> """
import json +import os import types
+ import pki import pki.client as client import pki.account as account @@ -36,6 +52,9 @@ class ProfileDataInfo(object):
@classmethod def from_json(cls, attr_list): + if attr_list is None: + return None + profile_data_info = cls() profile_data_info.profile_id = attr_list['profileId'] profile_data_info.profile_name = attr_list['profileName'] @@ -59,9 +78,9 @@ class ProfileDataInfoCollection(object): return iter(self.profile_data_list)
@classmethod - def from_json(cls, json_value): + def from_json(cls, attr_list): ret = cls() - profile_data_infos = json_value['entries'] + profile_data_infos = attr_list['entries'] if not isinstance(profile_data_infos, types.ListType): ret.profile_data_list.append( ProfileDataInfo.from_json(profile_data_infos)) @@ -70,7 +89,7 @@ class ProfileDataInfoCollection(object): ret.profile_data_list.append( ProfileDataInfo.from_json(profile_info))
- links = json_value['Link'] + links = attr_list['Link'] if not isinstance(links, types.ListType): ret.links.append(pki.Link.from_json(links)) else: @@ -128,6 +147,9 @@ class Descriptor(object):
@classmethod def from_json(cls, attr_list): + if attr_list is None: + return None + descriptor = cls() for attr in attr_list: setattr(descriptor, attr, attr_list[attr]) @@ -163,6 +185,9 @@ class ProfileAttribute(object):
@classmethod def from_json(cls, attr_list): + if attr_list is None: + return None + attribute = cls() attribute.name = attr_list['name'] if 'Value' in attr_list: @@ -241,15 +266,28 @@ class ProfileInput(object): setattr(self, 'ConfigAttribute', value)
def add_attribute(self, profile_attribute): + """ + Add a ProfileAttribute object to the attributes list. + """ + if not isinstance(profile_attribute, ProfileAttribute): + raise ValueError("Object passed is not a ProfileAttribute.") self.attributes.append(profile_attribute)
def remove_attribute(self, profile_attribute_name): + """ + Remove a ProfileAttribute object with the given name from the attributes + list. + """ for attr in self.attributes: if attr.name == profile_attribute_name: self.attributes.remove(attr) break
def get_attribute(self, profile_attribute_name): + """ + Returns a ProfileAttribute object for the given name. + None, if no match. + """ for attr in self.attributes: if attr.name == profile_attribute_name: return attr @@ -257,31 +295,46 @@ class ProfileInput(object): return None
def add_config_attribute(self, profile_attribute): - self.attributes.append(profile_attribute) + """ + Add a ProfileAttribute object to the config_attributes list. + """ + if not isinstance(profile_attribute, ProfileAttribute): + raise ValueError("Object passed is not a ProfileAttribute.") + self.config_attributes.append(profile_attribute)
def remove_config_attribute(self, config_attribute_name): + """ + Remove a ProfileAttribute object with the given name from the + config_attributes list. + """ for attr in self.config_attributes: if attr.name == config_attribute_name: - self.attributes.remove(attr) + self.config_attributes.remove(attr) break
def get_config_attribute(self, config_attribute_name): - for attr in self.attributes: + """ + Returns a ProfileAttribute object with the given name. + None, if there is no match in the config_attributes list. + """ + for attr in self.config_attributes: if attr.name == config_attribute_name: return attr
return None
@classmethod - def from_json(cls, json_value): + def from_json(cls, attr_list): + if attr_list is None: + return None profile_input = cls() - profile_input.profile_input_id = json_value['id'] - profile_input.class_id = json_value['ClassID'] - profile_input.name = json_value['Name'] - if 'Text' in json_value: - profile_input.text = json_value['Text'] + profile_input.profile_input_id = attr_list['id'] + profile_input.class_id = attr_list['ClassID'] + profile_input.name = attr_list['Name'] + if 'Text' in attr_list: + profile_input.text = attr_list['Text']
- attributes = json_value['Attribute'] + attributes = attr_list['Attribute'] if not isinstance(attributes, types.ListType): profile_input.attributes.append( ProfileAttribute.from_json(attributes)) @@ -290,7 +343,7 @@ class ProfileInput(object): profile_input.attributes.append( ProfileAttribute.from_json(profile_info))
- config_attributes = json_value['ConfigAttribute'] + config_attributes = attr_list['ConfigAttribute'] if not isinstance(config_attributes, types.ListType): profile_input.config_attributes.append( ProfileAttribute.from_json(config_attributes)) @@ -334,15 +387,28 @@ class ProfileOutput(object): setattr(self, 'classId', value)
def add_attribute(self, profile_attribute): + """ + Add a ProfileAttribute object to the attributes list. + """ + if not isinstance(profile_attribute, ProfileAttribute): + raise ValueError("Object passed is not a ProfileAttribute.") self.attributes.append(profile_attribute)
def remove_attribute(self, profile_attribute_name): + """ + Remove a ProfileAttribute object with the given name from the attributes + list. + """ for attr in self.attributes: if attr.name == profile_attribute_name: self.attributes.remove(attr) break
def get_attribute(self, profile_attribute_name): + """ + Returns a ProfileAttribute object for the given name. + None, if no match. + """ for attr in self.attributes: if attr.name == profile_attribute_name: return attr @@ -350,14 +416,17 @@ class ProfileOutput(object): return None
@classmethod - def from_json(cls, json_value): + def from_json(cls, attr_list): + if attr_list is None: + return None + profile_output = cls() - profile_output.profile_output_id = json_value['id'] - profile_output.name = json_value['name'] - if 'text' in json_value: - profile_output.text = json_value['text'] - profile_output.class_id = json_value['classId'] - attributes = json_value['attributes'] + profile_output.profile_output_id = attr_list['id'] + profile_output.name = attr_list['name'] + if 'text' in attr_list: + profile_output.text = attr_list['text'] + profile_output.class_id = attr_list['classId'] + attributes = attr_list['attributes'] if not isinstance(attributes, types.ListType): profile_output.attributes.append( ProfileAttribute.from_json(attributes)) @@ -375,6 +444,9 @@ class ProfileParameter(object):
@classmethod def from_json(cls, attr_list): + if attr_list is None: + return None + param = cls() for attr in attr_list: setattr(param, attr, attr_list[attr]) @@ -433,17 +505,76 @@ class PolicyDefault(object): def policy_params(self, value): setattr(self, 'params', value)
+ def add_attribute(self, policy_attribute): + """ + Add a policy attribute to the attribute list. + @param policy_attribute - A ProfileAttribute object + """ + if not isinstance(policy_attribute, ProfileAttribute): + raise ValueError("Object passed is not a ProfileAttribute.") + self.policy_attributes.append(policy_attribute) + + def remove_attribute(self, policy_attribute_name): + """ + Remove a policy attribute with the given name from the attributes list. + """ + for attr in self.policy_attributes: + if attr.name == policy_attribute_name: + self.policy_attributes.remove(attr) + break + + def get_attribute(self, policy_attribute_name): + """ + Fetch the policy attribute with the given name from the attributes list. + """ + for attr in self.policy_attributes: + if attr.name == policy_attribute_name: + return attr + + return None + + def add_parameter(self, policy_parameter): + """ + Add a profile parameter to the parameters list. + @param policy_parameter - A ProfileParameter object. + """ + if not isinstance(policy_parameter, ProfileParameter): + raise ValueError("Object passed is not a ProfileParameter.") + self.policy_params.append(policy_parameter) + + def remove_parameter(self, profile_parameter_name): + """ + Remove a profile parameter with the given name from the parameters list. + """ + for param in self.policy_params: + if param.name == profile_parameter_name: + self.policy_params.remove(param) + break + + def get_parameter(self, profile_parameter_name): + """ + Fetch a profile parameter with the given name from the parameters list. + """ + for param in self.policy_params: + if param.name == profile_parameter_name: + return param + + return None + @classmethod - def from_json(cls, json_value): + def from_json(cls, attr_list): + if attr_list is None: + return None + policy_def = cls() - if 'id' in json_value: - policy_def.name = json_value['id'] - if 'classId' in json_value: - policy_def.class_id = json_value['classId'] - if 'description' in json_value: - policy_def.description = json_value['description'] - if 'policyAttribute' in json_value: - attributes = json_value['policyAttribute'] + if 'id' in attr_list: + policy_def.name = attr_list['id'] + if 'classId' in attr_list: + policy_def.class_id = attr_list['classId'] + if 'description' in attr_list: + policy_def.description = attr_list['description'] + if 'policyAttribute' in attr_list: + attributes = attr_list['policyAttribute'] if not isinstance(attributes, types.ListType): policy_def.policy_attributes.append( ProfileAttribute.from_json(attributes)) @@ -452,8 +583,8 @@ class PolicyDefault(object): policy_def.policy_attributes.append( ProfileAttribute.from_json(attr))
- if 'params' in json_value: - params = json_value['params'] + if 'params' in attr_list: + params = attr_list['params'] if not isinstance(params, types.ListType): policy_def.policy_params.append( ProfileParameter.from_json(params)) @@ -480,13 +611,16 @@ class PolicyConstraintValue(object): setattr(self, 'id', value)
@classmethod - def from_json(cls, json_value): + def from_json(cls, attr_list): + if attr_list is None: + return None + ret = cls()
- ret.name = json_value['id'] - ret.value = json_value['value'] - if 'descriptor' in json_value: - ret.descriptor = Descriptor.from_json(json_value['descriptor']) + ret.name = attr_list['id'] + ret.value = attr_list['value'] + if 'descriptor' in attr_list: + ret.descriptor = Descriptor.from_json(attr_list['descriptor'])
return ret
@@ -531,17 +665,49 @@ class PolicyConstraint(object): def policy_constraint_values(self, value): setattr(self, 'constraint', value)
+ def add_constraint_value(self, policy_constraint_value): + """ + Add a ProfileConstraintValue to the policy_constraint_values list. + """ + if not isinstance(policy_constraint_value, PolicyConstraintValue): + raise ValueError("Object passed not of type PolicyConstraintValue") + self.policy_constraint_values.append(policy_constraint_value) + + def remove_constraint_value(self, policy_constraint_value_name): + """ + Removes a PolicyConstraintValue with the given name form the + policy_constraint_values list. + """ + for attr in self.policy_constraint_values: + if attr.name == policy_constraint_value_name: + self.policy_constraint_values.remove(attr) + break + + def get_constraint_value(self, policy_constraint_value_name): + """ + Returns a PolicyConstraintValue object with the given name. + None, if there is no match. + """ + for constraint in self.policy_constraint_values: + if constraint.name == policy_constraint_value_name: + return constraint + + return None + @classmethod - def from_json(cls, json_value): + def from_json(cls, attr_list): + if attr_list is None: + return None + policy_constraint = cls() - if 'id' in json_value: - policy_constraint.name = json_value['id'] - if 'description' in json_value: - policy_constraint.description = json_value['description'] - if 'classId' in json_value: - policy_constraint.class_id = json_value['classId'] - if 'constraint' in json_value: - constraints = json_value['constraint'] + if 'id' in attr_list: + policy_constraint.name = attr_list['id'] + if 'description' in attr_list: + policy_constraint.description = attr_list['description'] + if 'classId' in attr_list: + policy_constraint.class_id = attr_list['classId'] + if 'constraint' in attr_list: + constraints = attr_list['constraint'] if not isinstance(constraints, types.ListType): policy_constraint.policy_constraint_values.append( PolicyConstraintValue.from_json(constraints)) @@ -592,9 +758,12 @@ class ProfilePolicy(object): setattr(self, 'constraint', value)
@classmethod - def from_json(cls, json_value): - return cls(json_value['id'], PolicyDefault.from_json(json_value['def']), - PolicyConstraint.from_json(json_value['constraint'])) + def from_json(cls, attr_list): + if attr_list is None: + return None + + return cls(attr_list['id'], PolicyDefault.from_json(attr_list['def']), + PolicyConstraint.from_json(attr_list['constraint']))
class ProfilePolicySet(object): @@ -607,6 +776,9 @@ class ProfilePolicySet(object):
@classmethod def from_json(cls, attr_list): + if attr_list is None: + return None + policy_set = cls()
policies = attr_list['policies'] @@ -649,19 +821,40 @@ class PolicySet(object): setattr(self, 'value', value)
def add_policy(self, profile_policy): + """ + Add a ProfilePolicy object to the policy_list + """ + if not isinstance(profile_policy, ProfilePolicy): + raise ValueError("Object passed is not a ProfilePolicy.") self.policy_list.append(profile_policy)
def remove_policy(self, policy_id): + """ + Removes a ProfilePolicy with the given ID from the PolicySet. + """ for policy in self.policy_list: if policy.policy_id == policy_id: - self.policy_list.pop(policy) + self.policy_list.remove(policy) + break + + def get_policy(self, policy_id): + """ + Returns a ProfilePolicy object with the given profile id. + """ + for policy in self.policy_list: + if policy.policy_id == policy_id: + return policy + return None
@classmethod - def from_json(cls, json_value): + def from_json(cls, attr_list): + if attr_list is None: + return None + policy_set = cls()
- policy_set.name = json_value['id'] - policies = json_value['value'] + policy_set.name = attr_list['id'] + policies = attr_list['value'] if not isinstance(policies, types.ListType): policy_set.policy_list.append(ProfilePolicy.from_json(policies)) else: @@ -694,17 +887,39 @@ class PolicySetList(object): setattr(self, 'PolicySet', value)
def add_policy_set(self, policy_set): + """ + Add a PolicySet object to the policy_sets list. + """ + if not isinstance(policy_set, PolicySet): + raise ValueError("Object passed is not a PolicySet.") self.policy_sets.append(policy_set)
def remove_policy_set(self, policy_set_name): + """ + Remove a PolicySet object with the given name from the policy_sets list. + """ for policy_set in self.policy_sets: if policy_set.name == policy_set_name: - self.policy_sets.pop(policy_set) + self.policy_sets.remove(policy_set) + break + + def get_policy_set(self, policy_set_name): + """ + Fetch the PolicySet object for the given name. + Returns None, if not found. + """ + for policy_set in self.policy_sets: + if policy_set.name == policy_set_name: + return policy_set + return None
@classmethod - def from_json(cls, json_value): + def from_json(cls, attr_list): + if attr_list is None: + return None + policy_set_list = cls() - policy_sets = json_value['PolicySet'] + policy_sets = attr_list['PolicySet'] if not isinstance(policy_sets, types.ListType): policy_set_list.policy_sets.append(PolicySet.from_json(policy_sets)) else: @@ -824,51 +1039,101 @@ class Profile(object): setattr(self, 'PolicySets', value)
def add_input(self, profile_input): + """ + Add a ProfileInput object to the inputs list of the Profile. + """ + if not isinstance(profile_input, ProfileInput): + raise ValueError("Object passed is not a PolicyInput.") if profile_input is None: raise ValueError("No ProfileInput object provided.") self.inputs.append(profile_input)
def remove_input(self, profile_input_id): + """ + Remove a ProfileInput from the inputs list of the Profile. + """ for profile_input in self.inputs: if profile_input_id == profile_input.profile_input_id: - self.inputs.pop(profile_input) + self.inputs.remove(profile_input) + break + + def get_input(self, profile_input_id): + """ + Fetches a ProfileInput with the given ProfileInput id. + Returns None, if there is no matching input. + """ + for profile_input in self.inputs: + if profile_input_id == profile_input.profile_input_id: + return profile_input + return None
def add_output(self, profile_output): + """ + Add a ProfileOutput object to the outputs list of the Profile. + """ + if not isinstance(profile_output, ProfileOutput): + raise ValueError("Object passed is not a PolicyOutput.") if profile_output is None: raise ValueError("No ProfileOutput object provided.") self.outputs.append(profile_output)
def remove_output(self, profile_output_id): + """ + Remove a ProfileOutput from the outputs list of the Profile. + """ for profile_output in self.outputs: if profile_output_id == profile_output.profile_output_id: - self.inputs.pop(profile_output) + self.inputs.remove(profile_output) + + def get_output(self, profile_output_id): + """ + Fetches a ProfileOutput with the given ProfileOutput id. + Returns None, if there is no matching output. + """ + for profile_input in self.inputs: + if profile_output_id == profile_input.profile_input_id: + return profile_input + return None
def add_policy_set(self, policy_set): + """ + Add a PolicySet object to the policy_sets list of the Profile. + """ if policy_set is None: raise ValueError("No PolicySet object provided.") self.policy_set_list.add_policy_set(policy_set)
def remove_policy_set(self, policy_set_name): + """ + Remove a PolicySet from the policy_sets list of the Profile. + """ self.policy_set_list.remove_policy_set(policy_set_name)
+ def get_policy_set(self, policy_set_name): + """ + Fetches a ProfileInput with the given ProfileInput id. + Returns None, if there is no matching input. + """ + return self.policy_set_list.get_policy_set(policy_set_name) + @classmethod - def from_json(cls, json_value): + def from_json(cls, attr_list): profile_data = cls() - profile_data.profile_id = json_value['id'] - profile_data.class_id = json_value['classId'] - profile_data.name = json_value['name'] - profile_data.description = json_value['description'] - profile_data.enabled = json_value['enabled'] - profile_data.visible = json_value['visible'] - if 'enabledBy' in json_value: - profile_data.enabled_by = json_value['enabledBy'] - if 'authenticatorId' in json_value: - profile_data.authenticator_id = json_value['authenticatorId'] - profile_data.authorization_acl = json_value['authzAcl'] - profile_data.renewal = json_value['renewal'] - profile_data.xml_output = json_value['xmlOutput'] + profile_data.profile_id = attr_list['id'] + profile_data.class_id = attr_list['classId'] + profile_data.name = attr_list['name'] + profile_data.description = attr_list['description'] + profile_data.enabled = attr_list['enabled'] + profile_data.visible = attr_list['visible'] + if 'enabledBy' in attr_list: + profile_data.enabled_by = attr_list['enabledBy'] + if 'authenticatorId' in attr_list: + profile_data.authenticator_id = attr_list['authenticatorId'] + profile_data.authorization_acl = attr_list['authzAcl'] + profile_data.renewal = attr_list['renewal'] + profile_data.xml_output = attr_list['xmlOutput']
- profile_inputs = json_value['Input'] + profile_inputs = attr_list['Input'] if not isinstance(profile_inputs, types.ListType): profile_data.inputs.append(ProfileInput.from_json(profile_inputs)) else: @@ -876,7 +1141,7 @@ class Profile(object): profile_data.inputs.append( ProfileInput.from_json(profile_input))
- profile_outputs = json_value['Output'] + profile_outputs = attr_list['Output'] if not isinstance(profile_outputs, types.ListType): profile_data.outputs.append( ProfileOutput.from_json(profile_outputs)) @@ -886,9 +1151,9 @@ class Profile(object): ProfileOutput.from_json(profile_output))
profile_data.policy_set_list = \ - PolicySetList.from_json(json_value['PolicySets']) + PolicySetList.from_json(attr_list['PolicySets'])
- profile_data.link = pki.Link.from_json(json_value['link']) + profile_data.link = pki.Link.from_json(attr_list['link'])
return profile_data
@@ -904,6 +1169,20 @@ class Profile(object): } return str(attributes)
+ @staticmethod + def get_profile_data_from_file(path_to_file): + """ + Reads the file for the serialized Profile object. + Currently supports only data format in json. + """ + if path_to_file is None: + raise ValueError("File path must be specified.") + with open(path_to_file) as input_file: + data = input_file.read() + if data is not None: + return Profile.from_json(json.loads(data)) + return None +
class ProfileClient(object): """ @@ -995,34 +1274,67 @@ class ProfileClient(object): """ return self._modify_profile_state(profile_id, 'disable')
- def create_profile(self, profile_data): - """ - Create a new profile for the given ProfileData object. - """ + def _send_profile_create(self, profile_data): + if profile_data is None: raise ValueError("No ProfileData specified")
profile_object = json.dumps(profile_data, cls=encoder.CustomTypeEncoder, sort_keys=True) + r = self._post(self.profiles_url, profile_object) + return Profile.from_json(r.json())
- def modify_profile(self, profile_data): - """ - Modify an existing profile. - """ + def _send_profile_modify(self, profile_data): if profile_data is None: raise ValueError("No ProfileData specified")
+ profile_object = json.dumps(profile_data, cls=encoder.CustomTypeEncoder, + sort_keys=True) + if profile_data.profile_id is None: + raise ValueError("Profile Id is not specified.") url = self.profiles_url + '/' + str(profile_data.profile_id) - profile_object = json.dumps(profile_data, cls=encoder.CustomTypeEncoder, - sort_keys=True) r = self._put(url, profile_object) + return Profile.from_json(r.json())
+ @pki.handle_exceptions() + def create_profile(self, profile_data): + """ + Create a new profile for the given Profile object. + """ + return self._send_profile_create(profile_data) + + @pki.handle_exceptions() + def modify_profile(self, profile_data): + """ + Modify an existing profile with the given Profile object. + """ + return self._send_profile_modify(profile_data) + + def create_profile_from_file(self, path_to_file): + """ + Reads the file for the serialized Profile object. + Performs the profile create operation. + Currently supports only data format in json. + """ + profile_data = Profile.get_profile_data_from_file(path_to_file) + return self._send_profile_create(profile_data) + + def modify_profile_from_file(self, path_to_file): + """ + Reads the file for the serialized Profile object. + Performs the profile modify operation. + Currently supports only data format in json. + """ + profile_data = Profile.get_profile_data_from_file(path_to_file) + return self._send_profile_modify(profile_data) + + @pki.handle_exceptions() def delete_profile(self, profile_id): """ - Delete a profile. + Delete a profile with the given Profile Id. """ if profile_id is None: raise ValueError("Profile Id must be specified.") @@ -1058,6 +1370,11 @@ def main(): #Initialize the ProfileClient class profile_client = ProfileClient(connection)
+ # Folder to store the files generated during test + file_path = '/tmp/profile_client_test/' + if not os.path.exists(file_path): + os.makedirs(file_path) + #Fetching a list of profiles profile_data_infos = profile_client.list_profiles() print('List of profiles:') @@ -1102,12 +1419,14 @@ def main(): print('-----------------------')
profile_data = Profile(name="My Sample User Cert Enrollment", - profile_id="MySampleCert", class_id="caEnrollImpl", + profile_id="MySampleProfile", + class_id="caEnrollImpl", description="Example User Cert Enroll Impl", enabled_by='admin', enabled=False, visible=False, renewal=False, xml_output=False, authorization_acl="")
+ # Adding a profile input profile_input = ProfileInput("i1", "subjectNameInputImpl") profile_input.add_attribute(ProfileAttribute("sn_uid")) profile_input.add_attribute(ProfileAttribute("sn_e")) @@ -1121,6 +1440,97 @@ def main():
profile_data.add_input(profile_input)
+ # Adding a profile output + profile_output = ProfileOutput("o1", name="Certificate Output", + class_id="certOutputImpl") + profile_output.add_attribute(ProfileAttribute("pretty_cert")) + profile_output.add_attribute(ProfileAttribute("b64_cert")) + + profile_data.add_output(profile_output) + + # Create a Policy set with a list of profile policies + policy_list = [] + + # Creating profile policy + policy_default = PolicyDefault("Subject Name Default", + "userSubjectNameDefaultImpl", + "This default populates a User-Supplied " + "Certificate Subject Name to the request.") + + attr_descriptor = Descriptor(syntax="string", description="Subject Name") + policy_attribute = ProfileAttribute("name", descriptor=attr_descriptor) + policy_default.add_attribute(policy_attribute) + + policy_constraint = PolicyConstraint("Subject Name Constraint", + "This constraint accepts the subject " + "name that matches UID=.*", + "subjectNameConstraintImpl") + constraint_descriptor = Descriptor(syntax="string", + description="Subject Name Pattern") + policy_constraint_value = PolicyConstraintValue("pattern", + "UID=.*", + constraint_descriptor) + policy_constraint.add_constraint_value(policy_constraint_value) + + policy_list.append(ProfilePolicy("1", policy_default, policy_constraint)) + + # Creating another profile policy + # Defining the policy default + policy_default = PolicyDefault("Validity Default", "validityDefaultImpl", + "This default populates a Certificate " + "Validity to the request. The default " + "values are Range=180 in days") + attr_descriptor = Descriptor(syntax="string", description="Not Before") + policy_attribute = ProfileAttribute("notBefore", descriptor=attr_descriptor) + policy_default.add_attribute(policy_attribute) + + attr_descriptor = Descriptor(syntax="string", description="Not After") + policy_attribute = ProfileAttribute("notAfter", descriptor=attr_descriptor) + policy_default.add_attribute(policy_attribute) + + profile_param = ProfileParameter("range", 180) + profile_param2 = ProfileParameter("startTime", 0) + policy_default.add_parameter(profile_param) + policy_default.add_parameter(profile_param2) + + #Defining the policy constraint + policy_constraint = PolicyConstraint("Validity Constraint", + "This constraint rejects the validity " + "that is not between 365 days.", + "validityConstraintImpl") + constraint_descriptor = Descriptor(syntax="integer", + description="Validity Range (in days)", + default_value=365) + policy_constraint_value = PolicyConstraintValue("range", 365, + constraint_descriptor) + policy_constraint.add_constraint_value(policy_constraint_value) + + constraint_descriptor = Descriptor(syntax="boolean", default_value=False, + description="Check Not Before against" + " current time") + policy_constraint_value = PolicyConstraintValue("notBeforeCheck", False, + constraint_descriptor) + policy_constraint.add_constraint_value(policy_constraint_value) + + constraint_descriptor = Descriptor(syntax="boolean", default_value=False, + description="Check Not After against" + " Not Before") + policy_constraint_value = PolicyConstraintValue("notAfterCheck", False, + constraint_descriptor) + policy_constraint.add_constraint_value(policy_constraint_value) + + policy_list.append(ProfilePolicy("2", policy_default, policy_constraint)) + + policy_set = PolicySet("userCertSet", policy_list) + + profile_data.add_policy_set(policy_set) + + # Write the profile data object to a file for testing a file input + with open(file_path+'/original.json', 'w') as output_file: + output_file.write(json.dumps(profile_data, + cls=encoder.CustomTypeEncoder, + sort_keys=True, indent=4)) + # Create a new profile created_profile = profile_client.create_profile(profile_data) print(created_profile) print @@ -1131,7 +1541,7 @@ def main():
try: profile_data = Profile(name="My Sample User Cert Enrollment", - profile_id="MySampleCert", + profile_id="MySampleProfile", class_id="caEnrollImpl", description="Example User Cert Enroll Impl", enabled_by='admin', enabled=False, visible=False, @@ -1151,40 +1561,66 @@ def main(): profile_data.add_input(profile_input) profile_client.create_profile(profile_data) # pylint: disable-msg=W0703 - except Exception as e: - print str(e) + except pki.BadRequestException as e: + print 'MySampleProfile ' + str(e) print
# Modify the above created profile - print('Modifying the profile MySampleCert.') + print('Modifying the profile MySampleProfile.') print('-----------------------------------')
- fetch = profile_client.get_profile('MySampleCert') + fetch = profile_client.get_profile('MySampleProfile') profile_input2 = ProfileInput("i2", "keyGenInputImpl") profile_input2.add_attribute(ProfileAttribute("cert_request_type")) profile_input2.add_attribute(ProfileAttribute("cert_request")) fetch.add_input(profile_input2)
fetch.name += " (Modified)" + with open(file_path+'modified.json', 'w') as output_file: + output_file.write(json.dumps(fetch, cls=encoder.CustomTypeEncoder, + sort_keys=True, indent=4)) modified_profile = profile_client.modify_profile(fetch) print(modified_profile) print
# Delete a profile - print ("Deleting the profile MySampleCert.") + print ("Deleting the profile MySampleProfile.") print ("----------------------------------") - profile_client.delete_profile('MySampleCert') - print ("Deleted profile MySampleCert.") + profile_client.delete_profile('MySampleProfile') + print ("Deleted profile MySampleProfile.") print
# Testing deletion of a profile print('Test profile deletion.') print('----------------------') try: - profile_client.get_profile('MySampleCert') + profile_client.get_profile('MySampleProfile') # pylint: disable-msg=W0703 - except Exception as e: + except pki.ProfileNotFoundException as e: print str(e) + print + + # Creating a profile from file + print('Creating a profile using file input.') + print('------------------------------------') + original = profile_client.create_profile_from_file( + file_path + 'original.json') + print(original) + print + + # Modifying a profile from file + print('Modifying a profile using file input.') + print('------------------------------------') + modified = profile_client.modify_profile_from_file( + file_path + 'modified.json') + print(modified) + print + + # Test clean up + profile_client.delete_profile('MySampleProfile') + os.remove(file_path+'original.json') + os.remove(file_path+'modified.json') + os.removedirs(file_path)
if __name__ == "__main__": -- 1.8.5.3