def __init__(self, description): if not isinstance(description, dict): raise SetupDescriptionError( 'Section "{0}" of setup description must be a mapping.'.format( self._section_name)) possible_attrs = set([ attr for attr in dir(self) if not attr.startswith('_') and isinstance(getattr(self.__class__, attr), property) ]) if hasattr(self.__class__, '_OPTIONAL_ATTRS'): required_attrs = possible_attrs - self.__class__._OPTIONAL_ATTRS else: required_attrs = possible_attrs for k, v in description.items(): if k not in possible_attrs: raise SetupDescriptionError( 'Key "{0}" is not supported for section "{1}".'.format( k, self._section_name)) setattr(self, k, v) for k in required_attrs: if k not in description: raise SetupDescriptionError( 'Key "{0}" is required for section "{1}".'.format( k, self._section_name)) if not os.path.exists(CONFIG_DIR): os.makedirs(CONFIG_DIR)
def __init__(self, setup_file): setup_file = os.path.expanduser(os.path.expandvars(setup_file)) description = self._load_description(setup_file) for k, v in description.items(): if k not in dir(self): raise SetupDescriptionError( 'Key "{0}" is not supported for setup description.'.format( k)) setattr(self, k, v) for k in {'cloud', 'architecture'}: if k not in description: raise SetupDescriptionError( 'Setup description requires key "{0}"'.format(k))
def provider(self, value): self._check_value_type(value, 'provider', str) options = {'os', 'gce', 'ec2'} if value not in options: raise SetupDescriptionError( 'Cloud provider must be one of the following: "{0}"'.format( '", "'.join(options) ) ) if value == 'os': required_env_vars = { 'OS_AUTH_URL', 'OS_USERNAME', 'OS_PASSWORD', 'OS_PROJECT_NAME' } elif value == 'gce': required_env_vars = { 'GCE_EMAIL', 'GCE_PROJECT', 'GCE_CREDENTIALS_FILE_PATH' } elif value == 'ec2': required_env_vars = { 'AWS_ACCESS_KEY_ID', 'AWS_SECRET_ACCESS_KEY' } for var in required_env_vars: if var not in os.environ: raise SetupEnvironmentError( 'Environment variable "{0}" must be set ' 'for "{1}" provider.'.format(var, value) ) self._provider = value
def _load_description(self, description_file): if not os.path.exists(description_file): raise OSError( 'Setup file "{0}" does not exist!'.format(description_file)) description = read_yaml_file(description_file) if not isinstance(description, dict): raise SetupDescriptionError('Setup description must be a mapping.') return description
def key_file_public(self, value): self._check_value_type(value, 'key_file_public', str) value = os.path.expandvars(os.path.expanduser(value)) if not value.endswith('.pub'): raise SetupDescriptionError( 'Value of "key_file_public" must point to a ' 'public key: {0}'.format(value)) if not os.path.exists(value): logger.warn('public key file "%s" does not exist', value) self._key_file_public = value
def _check_value_type(self, value, name, required_type): type_translation = { int: 'a number', str: 'a string', dict: 'a mapping', list: 'an array' } if not isinstance(value, required_type): raise SetupDescriptionError( 'Value of "{0}" in section "{1}" must be {2}.'.format( name, self._section_name, type_translation[required_type]))
def _check_subsection_type(self, value, name, required_type, index=None): if index is None: message = 'Subsection "{0}" in setup'.format(name) mapping = value else: message = 'Item #{0} of subsection "{1}" in setup'.format( index, name) mapping = value[index] type_translation = {dict: 'a mapping', list: 'an array'} if not isinstance(mapping, required_type): raise SetupDescriptionError( '{0} configuration must be {1}.'.format( message, type_translation[required_type]))
def key_file_private(self, value): self._check_value_type(value, 'key_file_private', str) value = os.path.expandvars(os.path.expanduser(value)) if value.endswith('.pub'): raise SetupDescriptionError( 'Value of "key_file_private" must point to a ' 'private key: {0}'.format(value)) if not os.path.exists(value): logger.warn('private key file "%s" does not exist', value) key_file_public = self.key_file_public logger.info('create SSH key pair') logger.warn('SSH key is not protected by a passphrase') key = RSA.generate(2048) with open(value, 'w') as f: os.chmod(value, 0o400) f.write(key.exportKey('PEM')) pubkey = key.publickey() with open(key_file_public, 'w') as f: f.write(pubkey.exportKey('OpenSSH')) self._key_file_private = value