Skip to content

Commit 4f50645

Browse files
author
Matthew Fisher
committed
Merge pull request #3556 from bacongobbler/3441-support-san-certificates
feat(controller): support SAN certificates
2 parents ee9f00e + 6554120 commit 4f50645

4 files changed

Lines changed: 48 additions & 5 deletions

File tree

client/deis.py

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1043,18 +1043,36 @@ def certs_add(self, args):
10431043
"""
10441044
Binds a certificate/key pair to an application.
10451045
1046-
Usage: deis certs:add <cert> <key>
1046+
Usage: deis certs:add <cert> <key> [options]
10471047
10481048
Arguments:
10491049
<cert>
10501050
The public key of the SSL certificate.
10511051
<key>
10521052
The private key of the SSL certificate.
1053+
1054+
Options:
1055+
--common-name=<cname>
1056+
The common name of the certificate. If none is provided, the controller will
1057+
interpret the common name from the certificate.
1058+
--subject-alt-names=<sans>
1059+
The subject alternate names (SAN) of the certificate, separated by commas. This will
1060+
create multiple Certificate objects in the controller, one for each SAN.
10531061
"""
10541062
cert = args.get('<cert>')
10551063
key = args.get('<key>')
1064+
self._certs_add(cert, key, args.get('--common-name'))
1065+
sans = args.get('--subject-alt-names')
1066+
if sans:
1067+
[self._certs_add(cert, key, san) for san in sans.split(',')]
1068+
1069+
def _certs_add(self, cert, key, common_name=None):
10561070
body = {'certificate': file(cert).read().strip(), 'key': file(key).read().strip()}
1057-
sys.stdout.write("Adding SSL endpoint... ")
1071+
if common_name:
1072+
body['common_name'] = common_name
1073+
sys.stdout.write("Adding SSL endpoint {}...".format(common_name))
1074+
else:
1075+
sys.stdout.write("Adding SSL endpoint... ")
10581076
sys.stdout.flush()
10591077
try:
10601078
progress = TextProgress()
@@ -1066,7 +1084,8 @@ def certs_add(self, args):
10661084
if response.status_code == requests.codes.created:
10671085
self._logger.info("done")
10681086
data = response.json()
1069-
self._logger.info("{common_name}".format(**data))
1087+
if not common_name:
1088+
self._logger.info("{common_name}".format(**data))
10701089
else:
10711090
raise ResponseError(response)
10721091

controller/api/serializers.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -275,8 +275,9 @@ class Meta:
275275
"""Metadata options for a DomainCertSerializer."""
276276
model = models.Certificate
277277
extra_kwargs = {'certificate': {'write_only': True},
278-
'key': {'write_only': True}}
279-
read_only_fields = ['common_name', 'expires', 'created', 'updated']
278+
'key': {'write_only': True},
279+
'common_name': {'required': False}}
280+
read_only_fields = ['expires', 'created', 'updated']
280281

281282

282283
class PushSerializer(ModelSerializer):

controller/api/tests/test_certificate.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,20 @@ def test_create_certificate_with_domain(self):
8080
HTTP_AUTHORIZATION='token {}'.format(self.token))
8181
self.assertEqual(response.status_code, 201)
8282

83+
def test_create_certificate_with_different_common_name(self):
84+
"""
85+
In some cases such as with SAN certificates, the certificate can cover more
86+
than a single domain. In that case, we want to be able to specify the common
87+
name for the certificate/key.
88+
"""
89+
body = {'certificate': self.autotest_example_com_cert,
90+
'key': self.key,
91+
'common_name': 'foo.example.com'}
92+
response = self.client.post(self.url, json.dumps(body), content_type='application/json',
93+
HTTP_AUTHORIZATION='token {}'.format(self.token))
94+
self.assertEqual(response.status_code, 201)
95+
self.assertEqual(response.data['common_name'], 'foo.example.com')
96+
8397
def test_get_certificate_screens_data(self):
8498
"""
8599
When a user retrieves a certificate, only the common name and expiry date should be

docs/reference/api-v1.3.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ What's New
1414

1515
**New!** ``/users`` endpoint for listing users
1616
**New!** ``/logs`` endpoint now has a option for limiting the number of log lines returned
17+
**New!** ``/certs`` endpoint now has an optional parameter to set the common name for a certificate
1718

1819

1920
Authentication
@@ -385,6 +386,14 @@ Example Request:
385386
"key": "-----BEGIN RSA PRIVATE KEY-----"
386387
}
387388
389+
Optional Parameters:
390+
391+
.. code-block:: console
392+
393+
{
394+
"common_name": "test.example.com"
395+
}
396+
388397
389398
Example Response:
390399

0 commit comments

Comments
 (0)