def test_components(self): """ Generate templates for roles with components. """ self.settings.environmentdefs = { 'any': ['host1'], } self.settings.roledefs = { 'role1': ['host1'], 'role2': ['host1'], 'role3': ['host1'], } self.settings.componentdefs = { 'role1': ['comp1'], 'role2': ['compgroup'], 'compgroup': ['comp2', 'comp3'], } with TempDir() as tmp_dir: for host_and_role in self.settings.for_env('any').all(): conffiles = ConfFiles( host_and_role, PackageEnvironmentLoader('confab.tests', 'templates/components'), DataLoader(join(dirname(__file__), 'data/components'))) conffiles.generate(tmp_dir.path) self.assertEquals('foo', tmp_dir.read('generated/host1/foo.txt')) self.assertEquals('bar', tmp_dir.read('generated/host1/bar/bar.txt')) self.assertEquals('baz', tmp_dir.read('generated/host1/baz.conf'))
def test_built_in_filters(self): """ Generated templates that use built-in filters have the correct values. """ conffiles = ConfFiles( self.settings.for_env('any').all().next(), PackageEnvironmentLoader('confab.tests', 'templates/jinjafilters/builtin'), lambda _: { 'bar': [1, 2, 3], 'pivot': 2, 'foo': { 'key1': 'foo1', 'key2': 'foo2', }, 'key': 'key2', }) with TempDir() as tmp_dir: conffiles.generate(tmp_dir.path) eq_('foo2', tmp_dir.read('generated/localhost/foo.txt')) eq_("['+2+', '+3+', '+1+']", tmp_dir.read('generated/localhost/bar/bar.txt'))
def test_components(self): """ Generate templates for roles with components. """ self.settings.environmentdefs = { 'any': ['host1'], } self.settings.roledefs = { 'role1': ['host1'], 'role2': ['host1'], 'role3': ['host1'], } self.settings.componentdefs = { 'role1': ['comp1'], 'role2': ['compgroup'], 'compgroup': ['comp2', 'comp3'], } with TempDir() as tmp_dir: for host_and_role in self.settings.for_env('any').all(): conffiles = ConfFiles(host_and_role, PackageEnvironmentLoader('confab.tests', 'templates/components'), DataLoader(join(dirname(__file__), 'data/components'))) conffiles.generate(tmp_dir.path) self.assertEquals('foo', tmp_dir.read('generated/host1/foo.txt')) self.assertEquals('bar', tmp_dir.read('generated/host1/bar/bar.txt')) self.assertEquals('baz', tmp_dir.read('generated/host1/baz.conf'))
def test_multiple_directories(self): """ Generate templates for roles with components where templates and data are in multiple directories. """ settings = Settings.load_from_dict( dict(environmentdefs={'any': ['host1']}, roledefs={ 'role1': ['host1'], 'role2': ['host1'] }, componentdefs={'role1': ['comp1', 'comp2']})) subdirs = ['roles', 'components'] template_dirs = map( lambda d: join(dirname(__file__), 'templates/multidir', d), subdirs) data_dirs = map(lambda d: join(dirname(__file__), 'data/multidir', d), subdirs) with TempDir() as tmp_dir: for host_and_role in settings.for_env('any').all(): conffiles = ConfFiles( host_and_role, FileSystemEnvironmentLoader(*template_dirs), DataLoader(data_dirs)) conffiles.generate(tmp_dir.path) self.assertEquals('foo', tmp_dir.read('generated/host1/foo.txt')) self.assertEquals('bar', tmp_dir.read('generated/host1/bar.txt')) self.assertEquals('baz', tmp_dir.read('generated/host1/baz.conf'))
def test_same_component_for_different_roles(self): """ Two roles using the same component on the same host. """ self.settings.roledefs = { 'role1': ['host'], 'role2': ['host'], } self.settings.componentdefs = { 'role1': ['comp'], 'role2': ['comp'], } environment_loader = PackageEnvironmentLoader('confab.tests', 'templates/validate') # use data that will create different conffiles for the same # component in the two roles. conffiles = ConfFiles( self.settings.for_env('any').with_roles('role1').all().next(), environment_loader, lambda comp: {'foo': 'role1'}) eq_(1, len(conffiles.conffiles)) ok_('role1.txt' == conffiles.conffiles[0].name) conffiles = ConfFiles( self.settings.for_env('any').with_roles('role2').all().next(), environment_loader, lambda comp: {'foo': 'role2'}) eq_(1, len(conffiles.conffiles)) ok_('role2.txt' == conffiles.conffiles[0].name)
def pull(templates_dir=None, data_dir=None, remotes_dir=None): """ Pull remote configuration files. """ validate_pull(templates_dir, data_dir, remotes_dir) conffiles = ConfFiles(FileSystemEnvironmentLoader(templates_dir), DataLoader(data_dir)) conffiles.pull(remotes_dir)
def pull(templates_dir=None, data_dir=None, remotes_dir=None): """ Pull remote configuration files. """ validate_pull(templates_dir, data_dir, remotes_dir) conffiles = ConfFiles(load_environment_from_dir(templates_dir), load_data_from_dir(data_dir)) conffiles.pull(remotes_dir)
def test_undefined(self): """ An exception is raised if a template value is undefined. """ conffiles = ConfFiles(load_environment_from_package("confab.tests"), {"bar": "bar"}) with settings(hide("user"), host_string="localhost"): with TempDir() as tmp_dir: with self.assertRaises(UndefinedError): conffiles.generate(tmp_dir.path)
def diff(templates_dir=None, data_dir=None, generated_dir=None, remotes_dir=None): """ Show configuration file diffs. """ validate_all(templates_dir, data_dir, generated_dir, remotes_dir) conffiles = ConfFiles(load_environment_from_dir(templates_dir), load_data_from_dir(data_dir)) conffiles.diff(generated_dir, remotes_dir)
def generate(templates_dir=None, data_dir=None, generated_dir=None): """ Generate configuration files. """ validate_generate(templates_dir, data_dir, generated_dir) conffiles = ConfFiles(load_environment_from_dir(templates_dir), load_data_from_dir(data_dir)) conffiles.generate(generated_dir)
def test_undefined(self): """ An exception is raised if a template value is undefined. """ conffiles = ConfFiles(self.settings.for_env('any').all().next(), PackageEnvironmentLoader('confab.tests', 'templates/default'), lambda _: {'bar': 'bar'}) with TempDir() as tmp_dir: with self.assertRaises(UndefinedError): conffiles.generate(tmp_dir.path)
def test_undefined(self): """ An exception is raised if a template value is undefined. """ conffiles = ConfFiles( self.settings.for_env('any').all().next(), PackageEnvironmentLoader('confab.tests', 'templates/default'), lambda _: {'bar': 'bar'}) with TempDir() as tmp_dir: with self.assertRaises(UndefinedError): conffiles.generate(tmp_dir.path)
def test_binary_template(self): """ Confab copies binary config files verbatim to generated folder. """ with settings(**self.settings): templates_dir = join(dirname(__file__), 'templates/binary') conffiles = ConfFiles(FileSystemEnvironmentLoader(templates_dir), lambda _: {}) with TempDir() as tmp_dir: conffiles.generate(tmp_dir.path) self.assertTrue(filecmp.cmp(join(tmp_dir.path, 'localhost/test.png'), join(templates_dir, 'role/test.png')))
def push(templates_dir=None, data_dir=None, generated_dir=None, remotes_dir=None): """ Push configuration files. """ validate_all(templates_dir, data_dir, generated_dir, remotes_dir) conffiles = ConfFiles(FileSystemEnvironmentLoader(templates_dir), DataLoader(data_dir)) conffiles.push(generated_dir, remotes_dir)
def push(templates_dir=None, data_dir=None, generated_dir=None, remotes_dir=None): """ Push configuration files. """ validate_all(templates_dir, data_dir, generated_dir, remotes_dir) conffiles = ConfFiles(load_environment_from_dir(templates_dir), load_data_from_dir(data_dir)) conffiles.push(generated_dir, remotes_dir)
def test_binary_template(self): """ Confab copies binary config files verbatim to generated folder. """ templates_dir = join(dirname(__file__), 'templates/binary') conffiles = ConfFiles(self.settings.for_env('any').all().next(), FileSystemEnvironmentLoader(templates_dir), lambda _: {}) with TempDir() as tmp_dir: conffiles.generate(tmp_dir.path) ok_(filecmp.cmp(join(tmp_dir.path, 'generated/localhost/test.png'), join(templates_dir, 'role/test.png')))
def test_should_render(self): """ Passing a mime_type_func controls whether templates are rendered. """ conffiles = ConfFiles(load_environment_from_package("confab.tests"), {"bar": "bar", "foo": "foo"}) with Options(should_render=lambda mime_type: False): with settings(hide("user"), host_string="localhost"): with TempDir() as tmp_dir: conffiles.generate(tmp_dir.path) # templates not rendered (though paths are) self.assertEquals("{{foo}}", tmp_dir.read("localhost/foo.txt")) self.assertEquals("{{bar}}", tmp_dir.read("localhost/bar/bar.txt"))
def test_unicode(self): """ Generated templates with unicode data. """ with settings(**self.settings): conffiles = ConfFiles(PackageEnvironmentLoader('confab.tests', 'templates/default'), lambda _: {'bar': 'bar', 'foo': u'\xc5\xae'}) with TempDir() as tmp_dir: conffiles.generate(tmp_dir.path) # foo.txt is populated with u'\xc5\xae' self.assertEquals(u'\xc5\xae', tmp_dir.read('localhost/foo.txt')) # bar.txt is populated with 'bar' and path is substituted self.assertEquals('bar', tmp_dir.read('localhost/bar/bar.txt'))
def test_generate(self): """ Generated templates have the correct values. """ conffiles = ConfFiles(load_environment_from_package("confab.tests"), {"bar": "bar", "foo": "foo"}) with settings(hide("user"), host_string="localhost"): with TempDir() as tmp_dir: conffiles.generate(tmp_dir.path) # foo.txt is populated with 'foo' self.assertEquals("foo", tmp_dir.read("localhost/foo.txt")) # bar.txt is populated with 'bar' and path is substituted self.assertEquals("bar", tmp_dir.read("localhost/bar/bar.txt"))
def test_binary_template(self): """ Confab copies binary config files verbatim to generated folder. """ templates_dir = join(dirname(__file__), 'templates/binary') conffiles = ConfFiles( self.settings.for_env('any').all().next(), FileSystemEnvironmentLoader(templates_dir), lambda _: {}) with TempDir() as tmp_dir: conffiles.generate(tmp_dir.path) ok_( filecmp.cmp(join(tmp_dir.path, 'generated/localhost/test.png'), join(templates_dir, 'role/test.png')))
def test_should_render(self): """ Passing a mime_type_func controls whether templates are rendered. """ with Options(should_render=lambda mime_type: False): conffiles = ConfFiles(self.settings.for_env('any').all().next(), PackageEnvironmentLoader('confab.tests', 'templates/default'), lambda _: {'bar': 'bar', 'foo': 'foo'}) with TempDir() as tmp_dir: conffiles.generate(tmp_dir.path) # templates not rendered (though paths are) eq_('{{foo}}', tmp_dir.read('generated/localhost/foo.txt')) eq_('{{bar}}', tmp_dir.read('generated/localhost/bar/bar.txt'))
def test_unicode(self): """ Generated templates with unicode data. """ conffiles = ConfFiles(self.settings.for_env('any').all().next(), PackageEnvironmentLoader('confab.tests', 'templates/default'), lambda _: {'bar': 'bar', 'foo': u'\xc5\xae'}) with TempDir() as tmp_dir: conffiles.generate(tmp_dir.path) # foo.txt is populated with u'\xc5\xae' eq_(u'\xc5\xae', tmp_dir.read('generated/localhost/foo.txt')) # bar.txt is populated with 'bar' and path is substituted eq_('bar', tmp_dir.read('generated/localhost/bar/bar.txt'))
def test_should_render(self): """ Passing a mime_type_func controls whether templates are rendered. """ conffiles = ConfFiles(load_environment_from_package('confab.tests'), {'bar': 'bar', 'foo': 'foo'}) with Options(should_render=lambda mime_type: False): with settings(hide('user'), host_string='localhost'): with TempDir() as tmp_dir: conffiles.generate(tmp_dir.path) # templates not rendered (though paths are) self.assertEquals('{{foo}}', tmp_dir.read('localhost/foo.txt')) self.assertEquals('{{bar}}', tmp_dir.read('localhost/bar/bar.txt'))
def test_unicode(self): """ Generated templates with unicode data. """ conffiles = ConfFiles(load_environment_from_package('confab.tests'), {'bar': 'bar', 'foo': u'\xc5\xae'}) with settings(hide('user'), host_string='localhost'): with TempDir() as tmp_dir: conffiles.generate(tmp_dir.path) # foo.txt is populated with u'\xc5\xae' self.assertEquals(u'\xc5\xae', tmp_dir.read('localhost/foo.txt')) # bar.txt is populated with 'bar' and path is substituted self.assertEquals('bar', tmp_dir.read('localhost/bar/bar.txt'))
def test_user_filters(self): """ Generated templates that use user-defined filters have the correct values. """ def multiply(value, mult): return value * mult with JinjaFilters(multiply): conffiles = ConfFiles(self.settings.for_env('any').all().next(), PackageEnvironmentLoader('confab.tests', 'templates/jinjafilters/user'), lambda _: {'foo': 'foo'}) with TempDir() as tmp_dir: conffiles.generate(tmp_dir.path) eq_('foofoofoo', tmp_dir.read('generated/localhost/foo.txt'))
def test_user_filters(self): """ Generated templates that use user-defined filters have the correct values. """ def multiply(value, mult): return value * mult with JinjaFilters(multiply): conffiles = ConfFiles( self.settings.for_env('any').all().next(), PackageEnvironmentLoader('confab.tests', 'templates/jinjafilters/user'), lambda _: {'foo': 'foo'}) with TempDir() as tmp_dir: conffiles.generate(tmp_dir.path) eq_('foofoofoo', tmp_dir.read('generated/localhost/foo.txt'))
def test_undefined(self): """ Raise an error if a template value is undefined. """ with self.assertRaises(UndefinedError): ConfFiles( self.settings.for_env('any').all().next(), PackageEnvironmentLoader('confab.tests', 'templates/default'), lambda _: {})
def test_unicode(self): """ Generated templates with unicode data. """ conffiles = ConfFiles( self.settings.for_env('any').all().next(), PackageEnvironmentLoader('confab.tests', 'templates/default'), lambda _: { 'bar': 'bar', 'foo': u'\xc5\xae' }) with TempDir() as tmp_dir: conffiles.generate(tmp_dir.path) # foo.txt is populated with u'\xc5\xae' eq_(u'\xc5\xae', tmp_dir.read('generated/localhost/foo.txt')) # bar.txt is populated with 'bar' and path is substituted eq_('bar', tmp_dir.read('generated/localhost/bar/bar.txt'))
def test_should_render(self): """ Passing a mime_type_func controls whether templates are rendered. """ with Options(should_render=lambda mime_type: False): conffiles = ConfFiles( self.settings.for_env('any').all().next(), PackageEnvironmentLoader('confab.tests', 'templates/default'), lambda _: { 'bar': 'bar', 'foo': 'foo' }) with TempDir() as tmp_dir: conffiles.generate(tmp_dir.path) # templates not rendered (though paths are) eq_('{{foo}}', tmp_dir.read('generated/localhost/foo.txt')) eq_('{{bar}}', tmp_dir.read('generated/localhost/bar/bar.txt'))
def test_warn_no_conffiles(self): """ Warn when a role doesn't have any configuration files. """ with Options(filter_func=lambda _: False): with catch_warnings(record=True) as captured_warnings: conffiles = ConfFiles( self.settings.for_env('any').all().next(), PackageEnvironmentLoader('confab.tests', 'templates/default'), lambda _: {}) eq_(0, len(conffiles.conffiles)) eq_(1, len(captured_warnings))
def test_built_in_filters(self): """ Generated templates that use built-in filters have the correct values. """ conffiles = ConfFiles(self.settings.for_env('any').all().next(), PackageEnvironmentLoader('confab.tests', 'templates/jinjafilters/builtin'), lambda _: { 'bar': [1, 2, 3], 'pivot': 2, 'foo': { 'key1': 'foo1', 'key2': 'foo2', }, 'key': 'key2', }) with TempDir() as tmp_dir: conffiles.generate(tmp_dir.path) eq_('foo2', tmp_dir.read('generated/localhost/foo.txt')) eq_("['+2+', '+3+', '+1+']", tmp_dir.read('generated/localhost/bar/bar.txt'))
def test_multiple_directories(self): """ Generate templates for roles with components where templates and data are in multiple directories. """ settings = Settings.load_from_dict(dict(environmentdefs={'any': ['host1']}, roledefs={'role1': ['host1'], 'role2': ['host1']}, componentdefs={'role1': ['comp1', 'comp2']})) subdirs = ['roles', 'components'] template_dirs = map(lambda d: join(dirname(__file__), 'templates/multidir', d), subdirs) data_dirs = map(lambda d: join(dirname(__file__), 'data/multidir', d), subdirs) with TempDir() as tmp_dir: for host_and_role in settings.for_env('any').all(): conffiles = ConfFiles(host_and_role, FileSystemEnvironmentLoader(*template_dirs), DataLoader(data_dirs)) conffiles.generate(tmp_dir.path) self.assertEquals('foo', tmp_dir.read('generated/host1/foo.txt')) self.assertEquals('bar', tmp_dir.read('generated/host1/bar.txt')) self.assertEquals('baz', tmp_dir.read('generated/host1/baz.conf'))
def test_components(self): """ Generate templates for roles with components. """ with settings(roledefs={'role1': ['host1'], 'role2': ['host1']}, componentdefs={'role1': ['comp1'], 'role2': ['compgroup'], 'compgroup': ['comp2', 'comp3']}, host_string='host1'): with TempDir() as tmp_dir: for role in ['role1', 'role2']: with settings(role=role): conffiles = ConfFiles(PackageEnvironmentLoader('confab.tests', 'templates/components'), lambda _: {'bar': 'bar', 'foo': 'foo', 'baz': 'baz'}) conffiles.generate(tmp_dir.path) self.assertEquals('foo', tmp_dir.read('host1/role1.txt')) self.assertEquals('foo', tmp_dir.read('host1/foo.txt')) self.assertEquals('bar', tmp_dir.read('host1/bar/bar.txt')) self.assertEquals('baz', tmp_dir.read('host1/baz.conf'))
def test_filter_func(self): """ Passing a filter_func limits which templates are generated. """ with Options(filter_func=lambda file_name: file_name != 'foo.txt'): conffiles = ConfFiles( self.settings.for_env('any').all().next(), PackageEnvironmentLoader('confab.tests', 'templates/default'), lambda _: {'bar': 'bar'}) eq_(1, len(conffiles.conffiles)) names = map(lambda x: x.name, conffiles.conffiles) self.assertTrue('bar/bar.txt' in names)
def test_get_conf_files(self): """ Generating conf files finds all templates in the package and generates their names properly. """ conffiles = ConfFiles( self.settings.for_env('any').all().next(), PackageEnvironmentLoader('confab.tests', 'templates/default'), lambda _: {'bar': 'bar'}) eq_(2, len(conffiles.conffiles)) names = map(lambda x: x.name, conffiles.conffiles) self.assertTrue('foo.txt' in names) self.assertTrue('bar/bar.txt' in names)
def make_conffiles(host_and_role, directory=None): """ Create a :class:`~confab.conffiles.ConfFiles` object for a ``host_and_role`` in an :term:`environment`. Uses the default :class:`~confab.loaders.FileSystemEnvironmentLoader` and :class:`~confab.data.DataLoader`. :param directory: Path to templates and data directories. """ directories = [directory or options.get_base_dir()] directories.extend(iter_extension_paths()) # Construct directories templates_dirs = map(lambda dir: join(dir, options.get_templates_dir()), directories) assert_exists(*templates_dirs) data_dirs = map(lambda dir: join(dir, options.get_data_dir()), directories) assert_exists(*data_dirs) return ConfFiles(host_and_role, FileSystemEnvironmentLoader(*templates_dirs), DataLoader(data_dirs))