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): def validate_manifest(data, validator, error):
import os.path import os.path
schema_path = os.path.normpath(os.path.join(os.path.dirname(__file__), 'manifest-schema.yml')) schema_path = os.path.normpath(os.path.join(os.path.dirname(__file__), 'manifest-schema.yml'))
validator(data, schema_path) 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): def resolve_tasks(taskset, manifest):
@ -24,6 +19,7 @@ def resolve_tasks(taskset, manifest):
taskset.add(tasks.AdminUserPassword) taskset.add(tasks.AdminUserPassword)
if 'pubkey' in manifest.plugins['admin_user']: if 'pubkey' in manifest.plugins['admin_user']:
taskset.add(tasks.CheckPublicKeyFile)
taskset.add(tasks.AdminUserPublicKey) taskset.add(tasks.AdminUserPublicKey)
elif manifest.provider['name'] == 'ec2': elif manifest.provider['name'] == 'ec2':
logging.getLogger(__name__).info("The SSH key will be obtained from EC2") logging.getLogger(__name__).info("The SSH key will be obtained from EC2")

View file

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

View file

@ -8,6 +8,21 @@ import logging
log = logging.getLogger(__name__) 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): class AddSudoPackage(Task):
description = 'Adding `sudo\' to the image packages' description = 'Adding `sudo\' to the image packages'
phase = phases.preparation phase = phases.preparation
@ -74,14 +89,21 @@ class AdminUserPublicKey(Task):
# Get the stuff we need (username & public key) # Get the stuff we need (username & public key)
username = info.manifest.plugins['admin_user']['username'] 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() pubkey = pubkey_handle.read()
# paths # paths
ssh_dir_rel = os.path.join('home', username, '.ssh') from os.path import join
auth_keys_rel = os.path.join(ssh_dir_rel, 'authorized_keys') ssh_dir_rel = join('home', username, '.ssh')
ssh_dir_abs = os.path.join(info.root, ssh_dir_rel) auth_keys_rel = join(ssh_dir_rel, 'authorized_keys')
auth_keys_abs = os.path.join(info.root, auth_keys_rel) 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 # Create the ssh dir if nobody has created it yet
if not os.path.exists(ssh_dir_abs): if not os.path.exists(ssh_dir_abs):
os.mkdir(ssh_dir_abs, 0700) os.mkdir(ssh_dir_abs, 0700)