def config_check_service(environments, root, path): try: service = validate.path_val(root, path, 'object') env_name = validate.path_val(root, path + ['environment'], 'string', 'default') default = env_name == 'default' env = environments.get(env_name) if env is None: if default: raise validate.ConfigError( ('The service at %s has no environment field, and no ' + 'environment called "default" exists.') % validate.render_path(path)) else: raise validate.ConfigError( 'In %s, unrecognized environment %s' % (validate.render_path(path), env_name)) compiler = service_compilers.get(env['kind']) compiler.validateService(root, path) for child_name, child in compiler.children(service): config_check_service(environments, root, path + [child_name]) except validate.ConfigError as e: if e.note is None: e.note = ( 'Did you mean for %s to be a visible field (: instead of ::)?' % validate.render_path(path)) raise
def validateInfrastructure(self, root, service_name, path): infrastructure = validate.path_val(root, path, 'object', {}) for rtype in sorted(infrastructure.keys()): resources = validate.path_val(root, path + [rtype], 'object', {}) for resource_name in sorted(resources.keys()): if not resource_name.startswith(service_name): validate.err( path, 'Expected "%s" to be prefixed by "%s"' % (resource_name, service_name), 'Resource names must be prefixed by the name of the service defining them' )
def validateService(self, root, path): super(AmazonService, self).validateService(root, path) infra_path = path + ['infrastructure'] validate.path_val(root, infra_path, 'object', {}) inst_path = infra_path + ['aws_instance'] instances = validate.path_val(root, inst_path, 'object', {}) # Validate image configs for inst_name, inst in instances.iteritems(): self.validateCmds(root, inst_path + [inst_name, 'cmds']) self.validateCmds(root, inst_path + [inst_name, 'bootCmds']) image = inst.get('ami') if isinstance(image, dict): self.validateImage(root, inst_path + [inst_name, 'ami'])
def config_check(config): validate.path_val(config, [], 'object') environments = validate.path_val(config, ['environments'], 'object', {}) # Check environments environments = config['environments'] for env_name, env in environments.iteritems(): kind_name = validate.path_val(config, ['environments', env_name, 'kind'], 'string') compiler = service_compilers.get(kind_name) if not compiler: raise validate.ConfigError( 'Unrecognized kind "%s" in environment %s' % (kind_name, env_name)) compiler.validateEnvironment(config, ['environments', env_name]) # Check services for service_name, service in services(config): config_check_service(environments, config, [service_name])
def validateService(self, root, path): super(GoogleService, self).validateService(root, path) infra_path = path + ['infrastructure'] validate.path_val(root, infra_path, 'object', {}) inst_path = infra_path + ['google_compute_instance'] instances = validate.path_val(root, inst_path, 'object', {}) disk_path = infra_path + ['google_compute_disk'] disks = validate.path_val(root, disk_path, 'object', {}) # Validate image configs for inst_name, inst in instances.iteritems(): self.validateCmds(root, inst_path + [inst_name, 'cmds']) self.validateCmds(root, inst_path + [inst_name, 'bootCmds']) # Assume instances have a boot disk. validate.path_val(root, inst_path + [inst_name, 'boot_disk'], 'object') boot_disk_path = inst_path + [inst_name, 'boot_disk'] boot_disk = validate.path_val(root, boot_disk_path, 'object') image = boot_disk.get('initialize_params', {}).get('image') if isinstance(image, dict): self.validateImage( root, boot_disk_path + ['initialize_params', 'image']) for disk_name, disk in disks.iteritems(): image = disk.get('image') if isinstance(image, dict): self.validateImage(root, disk_path + [disk_name, 'image'])
def validateCmds(self, root, path): cmds = validate.array(root, path, validate.is_any_type({'string', 'object'}), []) for i, cmd in enumerate(cmds): cmd_path = path + [i] if isinstance(cmd, basestring): # Any string will do for validation purposes. pass elif isinstance(cmd, dict): kinds = {'CopyFile', 'LiteralFile', 'EnsureDir'} kind = validate.path_val(root, cmd_path + ['kind'], validate.is_any_value(kinds)) if kind == 'CopyFile': fields = {'owner', 'group', 'dirPermissions', 'filePermissions', 'from', 'to'} for f in fields: validate.path_val(root, cmd_path + [f], 'string') validate.obj_only(root, cmd_path, fields | {'kind'}) elif kind == 'LiteralFile': fields = {'owner', 'group', 'filePermissions', 'content', 'to'} for f in fields: validate.path_val(root, cmd_path + [f], 'string') validate.obj_only(root, cmd_path, fields | {'kind'}) elif cmd['kind'] == 'EnsureDir': fields = {'owner', 'group', 'dirPermissions', 'dir'} for f in fields: validate.path_val(root, cmd_path + [f], 'string') validate.obj_only(root, cmd_path, fields | {'kind'}) else: raise RuntimeError('Internal error: %s' % kind) else: raise RuntimeError('Internal error: %s' % type(cmd))
def validateImage(self, root, path): super(GoogleService, self).validateImage(root, path) validate.path_val(root, path + ['machineType'], 'string', 'n1-standard-1') validate.path_val(root, path + ['source'], 'string') validate.path_val(root, path + ['zone'], 'string') validate.obj_only(root, path, {'cmds', 'machineType', 'source', 'zone'})
def validateImage(self, root, path): super(AmazonService, self).validateImage(root, path) validate.path_val(root, path + ['instanceType'], 'string', 'n1-standard-1') validate.path_val(root, path + ['sourceAmi'], 'string') validate.path_val(root, path + ['sshUser'], 'string') validate.obj_only(root, path, {'cmds', 'instanceType', 'sourceAmi', 'sshUser'})
def config_check_service(environments, root, path): try: service = validate.path_val(root, path, 'object') env_name = validate.path_val(root, path + ['environment'], 'string', 'default') default = env_name == 'default' env = environments.get(env_name) if env is None: if default: raise validate.ConfigError(('The service at %s has no environment field, and no ' + 'environment called "default" exists.') % validate.render_path(path)) else: raise validate.ConfigError('In %s, unrecognized environment %s' % (validate.render_path(path), env_name)) compiler = service_compilers.get(env['kind']) compiler.validateService(root, path) for child_name, child in compiler.children(service): config_check_service(environments, root, path + [child_name]) except validate.ConfigError as e: if e.note is None: e.note = ('Did you mean for %s to be a visible field (: instead of ::)?' % validate.render_path(path)) raise
def validateService(self, root, path): super(GoogleService, self).validateService(root, path) infra_path = path + ['infrastructure'] validate.path_val(root, infra_path, 'object', {}) inst_path = infra_path + ['google_compute_instance'] instances = validate.path_val(root, inst_path, 'object', {}) disk_path = infra_path + ['google_compute_disk'] disks = validate.path_val(root, disk_path, 'object', {}) # Validate image configs for inst_name, inst in instances.iteritems(): self.validateCmds(root, inst_path + [inst_name, 'cmds']) self.validateCmds(root, inst_path + [inst_name, 'bootCmds']) # Assume instances have a root disk. validate.path_val(root, inst_path + [inst_name, 'disk'], 'array') inst_disk_path = inst_path + [inst_name, 'disk', 0] disk = validate.path_val(root, inst_disk_path, 'object') image = disk.get('image') if isinstance(image, dict): self.validateImage(root, inst_disk_path + ['image']) for disk_name, disk in disks.iteritems(): image = disk.get('image') if isinstance(image, dict): self.validateImage(root, disk_path + [disk_name, 'image'])
def validateCmds(self, root, path): cmds = validate.array(root, path, validate.is_any_type({'string', 'object'}), []) for i, cmd in enumerate(cmds): cmd_path = path + [i] if isinstance(cmd, basestring): # Any string will do for validation purposes. pass elif isinstance(cmd, dict): kinds = {'CopyFile', 'LiteralFile', 'EnsureDir'} kind = validate.path_val(root, cmd_path + ['kind'], validate.is_any_value(kinds)) if kind == 'CopyFile': fields = { 'owner', 'group', 'dirPermissions', 'filePermissions', 'from', 'to' } for f in fields: validate.path_val(root, cmd_path + [f], 'string') validate.obj_only(root, cmd_path, fields | {'kind'}) elif kind == 'LiteralFile': fields = { 'owner', 'group', 'filePermissions', 'content', 'to' } for f in fields: validate.path_val(root, cmd_path + [f], 'string') validate.obj_only(root, cmd_path, fields | {'kind'}) elif cmd['kind'] == 'EnsureDir': fields = {'owner', 'group', 'dirPermissions', 'dir'} for f in fields: validate.path_val(root, cmd_path + [f], 'string') validate.obj_only(root, cmd_path, fields | {'kind'}) else: raise RuntimeError('Internal error: %s' % kind) else: raise RuntimeError('Internal error: %s' % type(cmd))
def validateService(self, root, path): validate.path_val(root, path + ['outputs'], validate.is_string_map, {}) validate.path_val(root, path + ['infrastructure'], 'object', {})
def validateEnvironment(self, root, path): fields = {'kind', 'accessKey', 'secretKey', 'region'} validate.obj_only(root, path, fields) validate.path_val(root, path + ['region'], 'string') validate.path_val(root, path + ['accessKey'], 'string') validate.path_val(root, path + ['secretKey'], 'string')
def validateEnvironment(self, root, path): fields = {'kind', 'project', 'region', 'sshUser', 'serviceAccount'} validate.obj_only(root, path, fields) validate.path_val(root, path + ['project'], 'string') validate.path_val(root, path + ['region'], 'string') validate.path_val(root, path + ['sshUser'], 'string') acc = validate.path_val(root, path + ['serviceAccount'], 'object') validate.path_val(root, path + ['serviceAccount', 'client_email'], 'string') validate.path_val(root, path + ['serviceAccount', 'private_key'], 'string') validate.path_val(root, path + ['serviceAccount', 'type'], validate.is_value('service_account'), 'service_account') validate.path_val(root, path + ['serviceAccount', 'client_id'], 'string', '') validate.path_val(root, path + ['serviceAccount', 'private_key_id'], 'string', '') fields = {'client_email', 'private_key', 'type', 'client_id', 'private_key_id'} validate.obj_only(root, path + ['serviceAccount'], fields)
def validateService(self, root, path): validate.path_val(root, path + ['outputs'], validate.is_string_map, {}) self.validateInfrastructure(root, self.fullName(path), path + ['infrastructure'])
def validateEnvironment(self, root, path): fields = {'kind', 'project', 'region', 'sshUser', 'serviceAccount'} validate.obj_only(root, path, fields) validate.path_val(root, path + ['project'], 'string') validate.path_val(root, path + ['region'], 'string') validate.path_val(root, path + ['sshUser'], 'string') acc = validate.path_val(root, path + ['serviceAccount'], 'object') validate.path_val(root, path + ['serviceAccount', 'client_email'], 'string') validate.path_val(root, path + ['serviceAccount', 'private_key'], 'string') validate.path_val(root, path + ['serviceAccount', 'type'], validate.is_value('service_account'), 'service_account') validate.path_val(root, path + ['serviceAccount', 'client_id'], 'string', '') validate.path_val(root, path + ['serviceAccount', 'private_key_id'], 'string', '') fields = { 'client_email', 'private_key', 'type', 'client_id', 'private_key_id' } validate.obj_only(root, path + ['serviceAccount'], fields)