Skip to content

Commit 75f2aa2

Browse files
author
Gabriel Monroy
committed
move auto-generated ssh keys to formation, add tests for ssh key override on formation create. fixes #17
1 parent 60814b9 commit 75f2aa2

13 files changed

Lines changed: 298 additions & 23 deletions

api/migrations/0002_auto__del_field_flavor_ssh_username__del_field_flavor_ssh_private_key_.py

Lines changed: 251 additions & 0 deletions
Large diffs are not rendered by default.

api/models.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,6 @@ class Flavor(UuidAuditedModel):
116116
params = fields.ParamsField()
117117
init = fields.CloudInitField()
118118

119-
ssh_username = models.CharField(max_length=64, default='ubuntu')
120-
ssh_private_key = models.TextField()
121-
ssh_public_key = models.TextField()
122-
123119
class Meta:
124120
unique_together = (('owner', 'id'),)
125121

@@ -187,6 +183,10 @@ class Formation(UuidAuditedModel):
187183
image = models.CharField(max_length=256, default='ubuntu')
188184
structure = fields.JSONField(default='{}', blank=True)
189185

186+
ssh_username = models.CharField(max_length=64, default='ubuntu')
187+
ssh_private_key = models.TextField()
188+
ssh_public_key = models.TextField()
189+
190190
class Meta:
191191
unique_together = (('owner', 'id'),)
192192

@@ -506,11 +506,11 @@ def _prepare_launch_args(self):
506506
'proxy', {}).setdefault('formations', [ self.formation.id ])
507507
# add the formation's ssh pubkey
508508
init.setdefault('ssh_authorized_keys', []).append(
509-
self.formation.flavor.ssh_public_key)
509+
self.formation.ssh_public_key)
510510
# add all of the owner's SSH keys
511511
init['ssh_authorized_keys'].extend([k.public for k in self.formation.owner.key_set.all() ])
512-
ssh_username = self.formation.flavor.ssh_username
513-
ssh_private_key = self.formation.flavor.ssh_private_key
512+
ssh_username = self.formation.ssh_username
513+
ssh_private_key = self.formation.ssh_private_key
514514
args = (self.uuid, creds, params, init, ssh_username, ssh_private_key)
515515
return args
516516

@@ -521,9 +521,9 @@ def converge(self, *args, **kwargs):
521521
return tasks.converge_node.subtask(args)
522522

523523
def _prepare_converge_args(self):
524-
ssh_username = self.formation.flavor.ssh_username
524+
ssh_username = self.formation.ssh_username
525525
fqdn = self.fqdn
526-
ssh_private_key = self.formation.flavor.ssh_private_key
526+
ssh_private_key = self.formation.ssh_private_key
527527
args = (self.uuid, ssh_username, fqdn, ssh_private_key)
528528
return args
529529

api/serializers.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,15 @@ class Meta:
128128
model = models.Formation
129129
read_only_fields = ('created', 'updated')
130130

131+
@property
132+
def data(self):
133+
"Custom data property that removes secure fields"
134+
d = super(FormationSerializer, self).data
135+
for f in ('ssh_private_key',):
136+
if f in d:
137+
del d[f]
138+
return d
139+
131140

132141
class NodeSerializer(serializers.ModelSerializer):
133142

api/tests/backend.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def setUp(self):
2626
response = self.client.post(url, json.dumps(body), content_type='application/json')
2727
self.assertEqual(response.status_code, 201)
2828
url = '/api/flavors'
29-
body = {'id': 'autotest', 'provider': 'autotest', 'ssh_username': 'ubuntu',
29+
body = {'id': 'autotest', 'provider': 'autotest',
3030
'params': json.dumps({'region': 'us-west-2', 'instance_size': 'm1.medium'})}
3131
response = self.client.post(url, json.dumps(body), content_type='application/json')
3232
self.assertEqual(response.status_code, 201)

api/tests/build.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def setUp(self):
2929
response = self.client.post(url, json.dumps(body), content_type='application/json')
3030
self.assertEqual(response.status_code, 201)
3131
url = '/api/flavors'
32-
body = {'id': 'autotest', 'provider': 'autotest', 'ssh_username': 'ubuntu',
32+
body = {'id': 'autotest', 'provider': 'autotest',
3333
'params': json.dumps({'region': 'us-west-2', 'instance_size': 'm1.medium'})}
3434
response = self.client.post(url, json.dumps(body), content_type='application/json')
3535
self.assertEqual(response.status_code, 201)

api/tests/config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def setUp(self):
2626
response = self.client.post(url, json.dumps(body), content_type='application/json')
2727
self.assertEqual(response.status_code, 201)
2828
url = '/api/flavors'
29-
body = {'id': 'autotest', 'provider': 'autotest', 'ssh_username': 'ubuntu',
29+
body = {'id': 'autotest', 'provider': 'autotest',
3030
'params': json.dumps({'region': 'us-west-2', 'instance_size': 'm1.medium'})}
3131
response = self.client.post(url, json.dumps(body), content_type='application/json')
3232
self.assertEqual(response.status_code, 201)

api/tests/container.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def setUp(self):
2929
response = self.client.post(url, json.dumps(body), content_type='application/json')
3030
self.assertEqual(response.status_code, 201)
3131
url = '/api/flavors'
32-
body = {'id': 'autotest', 'provider': 'autotest', 'ssh_username': 'ubuntu',
32+
body = {'id': 'autotest', 'provider': 'autotest',
3333
'params': json.dumps({'region': 'us-west-2', 'instance_size': 'm1.medium'})}
3434
response = self.client.post(url, json.dumps(body), content_type='application/json')
3535
self.assertEqual(response.status_code, 201)

api/tests/flavor.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def test_flavor(self):
3232
Test that a user can create, read, update and delete a node flavor
3333
"""
3434
url = '/api/flavors'
35-
body = {'id': 'autotest', 'provider': 'autotest', 'ssh_username': 'ubuntu',
35+
body = {'id': 'autotest', 'provider': 'autotest',
3636
'params': json.dumps({'region': 'us-west-2', 'instance_size': 'm1.medium'})}
3737
response = self.client.post(url, json.dumps(body), content_type='application/json')
3838
self.assertEqual(response.status_code, 201)

api/tests/formation.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import json
1010

1111
from django.test import TestCase
12+
from Crypto.PublicKey import RSA
1213

1314

1415
class FormationTest(TestCase):
@@ -26,7 +27,7 @@ def setUp(self):
2627
response = self.client.post(url, json.dumps(body), content_type='application/json')
2728
self.assertEqual(response.status_code, 201)
2829
url = '/api/flavors'
29-
body = {'id': 'autotest', 'provider': 'autotest', 'ssh_username': 'ubuntu',
30+
body = {'id': 'autotest', 'provider': 'autotest',
3031
'params': json.dumps({'region': 'us-west-2', 'instance_size': 'm1.medium'})}
3132
response = self.client.post(url, json.dumps(body), content_type='application/json')
3233
self.assertEqual(response.status_code, 201)
@@ -62,6 +63,19 @@ def test_formation_auto_id(self):
6263
self.assertTrue(response.data['id'])
6364
return response
6465

66+
def test_formation_ssh_override(self):
67+
key = RSA.generate(2048)
68+
body = {'id': 'autotest', 'flavor': 'autotest', 'image': 'deis/autotest',
69+
'ssh_private_key': key.exportKey('PEM'),
70+
'ssh_public_key': key.exportKey('OpenSSH')}
71+
url = '/api/formations'
72+
response = self.client.post(url, json.dumps(body), content_type='application/json')
73+
self.assertEqual(response.status_code, 201)
74+
self.assertIn('ssh_public_key', response.data)
75+
self.assertEquals(response.data['ssh_public_key'], body['ssh_public_key'])
76+
# ssh private key should be hidden
77+
self.assertNotIn('ssh_private_key', response.data)
78+
6579
def test_formation_errors(self):
6680
# test duplicate id
6781
body = {'flavor': 'autotest', 'image': 'deis/autotest'}

api/tests/node.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def setUp(self):
2626
response = self.client.post(url, json.dumps(body), content_type='application/json')
2727
self.assertEqual(response.status_code, 201)
2828
url = '/api/flavors'
29-
body = {'id': 'autotest', 'provider': 'autotest', 'ssh_username': 'ubuntu',
29+
body = {'id': 'autotest', 'provider': 'autotest',
3030
'params': json.dumps({'region': 'us-west-2', 'instance_size': 'm1.medium'})}
3131
response = self.client.post(url, json.dumps(body), content_type='application/json')
3232
self.assertEqual(response.status_code, 201)

0 commit comments

Comments
 (0)