Skip to content
25 changes: 21 additions & 4 deletions cfssl/cfssl.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@
# License MIT (https://opensource.org/licenses/MIT).

import requests
import logging

from .exceptions import CFSSLException, CFSSLRemoteException

from .models.config_key import ConfigKey

log = logging.getLogger(__name__)


class CFSSL(object):
""" It provides Python bindings to a remote CFSSL server via HTTP(S).
Expand Down Expand Up @@ -375,21 +378,35 @@ def call(self, endpoint, method='GET', params=None, data=None):
method=method,
url=endpoint,
params=params,
data=data,
json=data,
verify=self.verify,
)
response = response.json()
if not response['success']:
raise CFSSLRemoteException(
'\n'.join([
'Errors:',
'\n'.join(response.get('errors', [])),
'\n'.join(map(CFSSL._format_response_message, response.get('errors', []))),
'Messages:'
'\n'.join(response.get('messages', [])),
'\n'.join(map(CFSSL._format_response_message, response.get('messages', []))),
])
)
if response['messages']:
for message in response['messages']:
log.warning(CFSSL._format_response_message(message))
return response['result']

@staticmethod
def _format_response_message(error):
message = ''
if 'message' in error:
message += error['message']
if 'code' in error:
message += ' (%s)' % error['code']
if not message:
message = str(error)
return message

def _clean_mapping(self, mapping):
""" It removes false entries from mapping """
return {k:v for k, v in mapping.iteritems() if v}
return {k:v for k, v in mapping.items() if v}
17 changes: 10 additions & 7 deletions cfssl/models/certificate_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@
class CertificateRequest(object):
""" It provides a Certificate Request compatible with CFSSL. """

def __init__(self, common_name, names=None, hosts=None, key=None):
def __init__(self, common_name=None, names=None, hosts=None, key=None):
""" Initialize a new CertificateRequest.

Args:
common_name (str): The fully qualified domain name for the
common_name (str, optional): The fully qualified domain name for the
server. This must be an exact match.
names (tuple of SubjectInfo, optional):
Subject Information to be added to the request.
Expand All @@ -26,17 +26,20 @@ def __init__(self, common_name, names=None, hosts=None, key=None):
self.common_name = common_name
self.names = names or []
self.hosts = hosts or []
self.key = key or KeyConfig()
self.key = key

def to_api(self):
""" It returns an object compatible with the API. """
return {
'CN': self.common_name,
api = {
'names': [
name.to_api() for name in self.names
],
'hosts': [
host.to_api() for host in self.hosts
],
'key': self.key.to_api(),
]
}
if self.common_name:
api['CN'] = self.common_name
if self.key:
api['key'] = self.key.to_api()
return api
2 changes: 2 additions & 0 deletions cfssl/models/subject_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ def __init__(self, org_name, org_unit, city, state, country):
org_unit (str): Section of the organization.
city (str): The city where the organization is legally
located.
state (str): The state or province where your organization
is legally located. Can not be abbreviated.
country (str): The two letter ISO abbreviation for the
country.
"""
Expand Down