admin_user: Allow relative paths to pubkeys

The paths are relative to the manifest.

Also, the file validation happens during the validation phase.
This commit is contained in:
Nicolas Braud-Santoni 2016-08-14 01:24:40 +02:00
parent 734afd892b
commit 9de36b9d99
No known key found for this signature in database
GPG key ID: 9D4F88010CFE19E3
3 changed files with 32 additions and 14 deletions

View file

@ -1,13 +1,8 @@
def validate_manifest(data, validator, error):
import os.path
schema_path = os.path.normpath(os.path.join(os.path.dirname(__file__), 'manifest-schema.yml'))
validator(data, schema_path)
pubkey = data['plugins']['admin_user'].get('pubkey', None)
if pubkey is not None and not os.path.exists(pubkey):
msg = 'Could not find public key at %s' % pubkey
error(msg, ['plugins', 'admin_user', 'pubkey'])
def resolve_tasks(taskset, manifest):
@ -24,6 +19,7 @@ def resolve_tasks(taskset, manifest):
taskset.add(tasks.AdminUserPassword)
if 'pubkey' in manifest.plugins['admin_user']:
taskset.add(tasks.CheckPublicKeyFile)
taskset.add(tasks.AdminUserPublicKey)
elif manifest.provider['name'] == 'ec2':
logging.getLogger(__name__).info("The SSH key will be obtained from EC2")

View file

@ -11,10 +11,10 @@ properties:
properties:
username: {type: string}
password: {type: string}
pubkey: {$ref: '#/definitions/absolute_path'}
pubkey: {$ref: '#/definitions/path'}
required: [username]
additionalProperties: false
definitions:
absolute_path:
pattern: ^/[^\0]+$
path:
pattern: ^[^\0]+$
type: string

View file

@ -8,6 +8,21 @@ import logging
log = logging.getLogger(__name__)
class CheckPublicKeyFile(Task):
description = 'Check that the public key is a valid file'
phase = phases.validation
@classmethod
def run(cls, info):
from bootstrapvz.common.tools import log_call, rel_path
pubkey = info.manifest.plugins['admin_user'].get('pubkey', None)
if pubkey is not None:
if not os.path.isfile(rel_path(info.manifest.path, pubkey)):
msg = 'Could not find public key at %s' % pubkey
info.manifest.validation_error(msg, ['plugins', 'admin_user', 'pubkey'])
class AddSudoPackage(Task):
description = 'Adding `sudo\' to the image packages'
phase = phases.preparation
@ -74,14 +89,21 @@ class AdminUserPublicKey(Task):
# Get the stuff we need (username & public key)
username = info.manifest.plugins['admin_user']['username']
with open(info.manifest.plugins['admin_user']['pubkey']) as pubkey_handle:
from bootstrapvz.common.tools import rel_path
pubkey_path = rel_path(info.manifest.path,
info.manifest.plugins['admin_user']['pubkey'])
with open(pubkey_path) as pubkey_handle:
pubkey = pubkey_handle.read()
# paths
ssh_dir_rel = os.path.join('home', username, '.ssh')
auth_keys_rel = os.path.join(ssh_dir_rel, 'authorized_keys')
ssh_dir_abs = os.path.join(info.root, ssh_dir_rel)
auth_keys_abs = os.path.join(info.root, auth_keys_rel)
from os.path import join
ssh_dir_rel = join('home', username, '.ssh')
auth_keys_rel = join(ssh_dir_rel, 'authorized_keys')
ssh_dir_abs = join(info.root, ssh_dir_rel)
auth_keys_abs = join(info.root, auth_keys_rel)
# Create the ssh dir if nobody has created it yet
if not os.path.exists(ssh_dir_abs):
os.mkdir(ssh_dir_abs, 0700)