def test_pillar_top_compound_match(self, grains=None): ''' Test that a compound match topfile that refers to a nodegroup via N@ works as expected. ''' if not grains: grains = {} grains['os'] = 'Fedora' nodegroup_opts = salt.utils.yaml.safe_load( textwrap.dedent('''\ nodegroups: min: minion sub_min: sub_minion mins: N@min or N@sub_min missing_minion: L@minion,ghostminion ''')) opts = self._build_opts(nodegroup_opts) pillar_obj = pillar.Pillar(opts, grains, 'minion', 'base') ret = pillar_obj.compile_pillar() self.assertEqual(ret.get('pillar_from_nodegroup_with_ghost'), True) self.assertEqual(ret.get('pillar_from_nodegroup'), None) sub_pillar_obj = pillar.Pillar(opts, grains, 'sub_minion', 'base') sub_ret = sub_pillar_obj.compile_pillar() self.assertEqual(sub_ret.get('pillar_from_nodegroup_with_ghost'), None) self.assertEqual(sub_ret.get('pillar_from_nodegroup'), True)
def test_pillar_top_compound_match(self, grains=None): """ Test that a compound match topfile that refers to a nodegroup via N@ works as expected. """ if not grains: grains = {} grains["os"] = "Fedora" nodegroup_opts = salt.utils.yaml.safe_load( textwrap.dedent("""\ nodegroups: min: minion sub_min: sub_minion mins: N@min or N@sub_min missing_minion: L@minion,ghostminion """)) opts = self._build_opts(nodegroup_opts) pillar_obj = pillar.Pillar(opts, grains, "minion", "base") ret = pillar_obj.compile_pillar() self.assertEqual(ret.get("pillar_from_nodegroup_with_ghost"), True) self.assertEqual(ret.get("pillar_from_nodegroup"), None) sub_pillar_obj = pillar.Pillar(opts, grains, "sub_minion", "base") sub_ret = sub_pillar_obj.compile_pillar() self.assertEqual(sub_ret.get("pillar_from_nodegroup_with_ghost"), None) self.assertEqual(sub_ret.get("pillar_from_nodegroup"), True)
def test_decrypt_pillar_invalid_renderer(self, grains=None): ''' Test decryption using a renderer which is not permitted. It should fail, leaving the encrypted keys intact, and add an error to the pillar dictionary. ''' decrypt_pillar_opts = salt.utils.yaml.safe_load( textwrap.dedent('''\ decrypt_pillar_default: foo decrypt_pillar_renderers: - foo - bar decrypt_pillar: - 'secrets:vault': gpg ''')) opts = self._build_opts(decrypt_pillar_opts) pillar_obj = pillar.Pillar(opts, grains, 'test', 'base') ret = pillar_obj.compile_pillar() expected = copy.deepcopy(GPG_PILLAR_ENCRYPTED) expected['_errors'] = [ 'Failed to decrypt pillar key \'secrets:vault\': \'gpg\' is ' 'not a valid decryption renderer. Valid choices are: foo, bar' ] self.assertEqual(ret['_errors'], expected['_errors']) self.assertEqual(ret['secrets']['vault']['foo'], expected['secrets']['vault']['foo']) self.assertEqual(ret['secrets']['vault']['bar'], expected['secrets']['vault']['bar']) self.assertEqual(ret['secrets']['vault']['baz'], expected['secrets']['vault']['baz']) self.assertEqual(ret['secrets']['vault']['qux'], expected['secrets']['vault']['qux'])
def test_decrypt_pillar_missing_renderer(self, grains=None): ''' Test decryption using a missing renderer. It should fail, leaving the encrypted keys intact, and add an error to the pillar dictionary. ''' decrypt_pillar_opts = salt.utils.yaml.safe_load( textwrap.dedent('''\ decrypt_pillar_default: asdf decrypt_pillar_renderers: - asdf decrypt_pillar: - 'secrets:vault' ''')) opts = self._build_opts(decrypt_pillar_opts) pillar_obj = pillar.Pillar(opts, grains, 'test', 'base') ret = pillar_obj.compile_pillar() expected = copy.deepcopy(GPG_PILLAR_ENCRYPTED) expected['_errors'] = [ 'Failed to decrypt pillar key \'secrets:vault\': Decryption ' 'renderer \'asdf\' is not available' ] self.assertEqual(ret['_errors'], expected['_errors']) self.assertEqual(ret['secrets']['vault']['foo'], expected['secrets']['vault']['foo']) self.assertEqual(ret['secrets']['vault']['bar'], expected['secrets']['vault']['bar']) self.assertEqual(ret['secrets']['vault']['baz'], expected['secrets']['vault']['baz']) self.assertEqual(ret['secrets']['vault']['qux'], expected['secrets']['vault']['qux'])
def test_decrypt_pillar_invalid_renderer(self, grains=None): """ Test decryption using a renderer which is not permitted. It should fail, leaving the encrypted keys intact, and add an error to the pillar dictionary. """ decrypt_pillar_opts = salt.utils.yaml.safe_load( textwrap.dedent("""\ decrypt_pillar_default: foo decrypt_pillar_renderers: - foo - bar decrypt_pillar: - 'secrets:vault': gpg """)) opts = self._build_opts(decrypt_pillar_opts) pillar_obj = pillar.Pillar(opts, grains, "test", "base") ret = pillar_obj.compile_pillar() expected = copy.deepcopy(GPG_PILLAR_ENCRYPTED) expected["_errors"] = [ "Failed to decrypt pillar key 'secrets:vault': 'gpg' is " "not a valid decryption renderer. Valid choices are: foo, bar" ] self.assertEqual(ret["_errors"], expected["_errors"]) self.assertEqual(ret["secrets"]["vault"]["foo"], expected["secrets"]["vault"]["foo"]) self.assertEqual(ret["secrets"]["vault"]["bar"], expected["secrets"]["vault"]["bar"]) self.assertEqual(ret["secrets"]["vault"]["baz"], expected["secrets"]["vault"]["baz"]) self.assertEqual(ret["secrets"]["vault"]["qux"], expected["secrets"]["vault"]["qux"])
def test_decrypt_pillar_missing_renderer(self, grains=None): """ Test decryption using a missing renderer. It should fail, leaving the encrypted keys intact, and add an error to the pillar dictionary. """ decrypt_pillar_opts = salt.utils.yaml.safe_load( textwrap.dedent("""\ decrypt_pillar_default: asdf decrypt_pillar_renderers: - asdf decrypt_pillar: - 'secrets:vault' """)) opts = self._build_opts(decrypt_pillar_opts) pillar_obj = pillar.Pillar(opts, grains, "test", "base") ret = pillar_obj.compile_pillar() expected = copy.deepcopy(GPG_PILLAR_ENCRYPTED) expected["_errors"] = [ "Failed to decrypt pillar key 'secrets:vault': Decryption " "renderer 'asdf' is not available" ] self.assertEqual(ret["_errors"], expected["_errors"]) self.assertEqual(ret["secrets"]["vault"]["foo"], expected["secrets"]["vault"]["foo"]) self.assertEqual(ret["secrets"]["vault"]["bar"], expected["secrets"]["vault"]["bar"]) self.assertEqual(ret["secrets"]["vault"]["baz"], expected["secrets"]["vault"]["baz"]) self.assertEqual(ret["secrets"]["vault"]["qux"], expected["secrets"]["vault"]["qux"])
def test_pillar_top_compound_match(self, grains=None): ''' Test that a compound match topfile that refers to a nodegroup via N@ works as expected. ''' if not grains: grains = {} grains['os'] = 'Fedora' pillar_obj = pillar.Pillar(self.get_config('master', from_scratch=True), grains, 'minion', 'base') ret = pillar_obj.compile_pillar() self.assertEqual(ret.get('pillar_from_nodegroup_with_ghost'), True) self.assertEqual(ret.get('pillar_from_nodegroup'), None) sub_pillar_obj = pillar.Pillar(self.get_config('master', from_scratch=True), grains, 'sub_minion', 'base') sub_ret = sub_pillar_obj.compile_pillar() self.assertEqual(sub_ret.get('pillar_from_nodegroup_with_ghost'), None) self.assertEqual(sub_ret.get('pillar_from_nodegroup'), True)
def test_decrypt_pillar_default_renderer(self, grains=None): ''' Test recursive decryption of secrets:vault as well as the fallback to default decryption renderer. ''' decrypt_pillar_opts = yaml.safe_load(textwrap.dedent('''\ decrypt_pillar: - 'secrets:vault' ''')) opts = self._build_opts(decrypt_pillar_opts) pillar_obj = pillar.Pillar(opts, grains, 'test', 'base') ret = pillar_obj.compile_pillar() self.assertEqual(ret, GPG_PILLAR_DECRYPTED)
def test_decrypt_pillar_alternate_delimiter(self, grains=None): ''' Test recursive decryption of secrets:vault using a pipe instead of a colon as the nesting delimiter. ''' decrypt_pillar_opts = yaml.safe_load(textwrap.dedent('''\ decrypt_pillar_delimiter: '|' decrypt_pillar: - 'secrets|vault' ''')) opts = self._build_opts(decrypt_pillar_opts) pillar_obj = pillar.Pillar(opts, grains, 'test', 'base') ret = pillar_obj.compile_pillar() self.assertEqual(ret, GPG_PILLAR_DECRYPTED)
def test_decrypt_pillar_default_renderer(self, grains=None): """ Test recursive decryption of secrets:vault as well as the fallback to default decryption renderer. """ decrypt_pillar_opts = salt.utils.yaml.safe_load( textwrap.dedent("""\ decrypt_pillar: - 'secrets:vault' """)) opts = self._build_opts(decrypt_pillar_opts) pillar_obj = pillar.Pillar(opts, grains, "test", "base") ret = pillar_obj.compile_pillar() self.assertEqual(ret, GPG_PILLAR_DECRYPTED)
def test_decrypt_pillar_alternate_delimiter(self, grains=None): """ Test recursive decryption of secrets:vault using a pipe instead of a colon as the nesting delimiter. """ decrypt_pillar_opts = salt.utils.yaml.safe_load( textwrap.dedent("""\ decrypt_pillar_delimiter: '|' decrypt_pillar: - 'secrets|vault' """)) opts = self._build_opts(decrypt_pillar_opts) pillar_obj = pillar.Pillar(opts, grains, "test", "base") ret = pillar_obj.compile_pillar() self.assertEqual(ret, GPG_PILLAR_DECRYPTED)
def test_decrypt_pillar_deeper_nesting(self, grains=None): ''' Test recursive decryption, only with a more deeply-nested target. This should leave the other keys in secrets:vault encrypted. ''' decrypt_pillar_opts = yaml.safe_load(textwrap.dedent('''\ decrypt_pillar: - 'secrets:vault:qux' ''')) opts = self._build_opts(decrypt_pillar_opts) pillar_obj = pillar.Pillar(opts, grains, 'test', 'base') ret = pillar_obj.compile_pillar() expected = copy.deepcopy(GPG_PILLAR_ENCRYPTED) expected['secrets']['vault']['qux'][-1] = \ GPG_PILLAR_DECRYPTED['secrets']['vault']['qux'][-1] self.assertEqual(ret, expected)
def test_decrypt_pillar_deeper_nesting(self, grains=None): """ Test recursive decryption, only with a more deeply-nested target. This should leave the other keys in secrets:vault encrypted. """ decrypt_pillar_opts = salt.utils.yaml.safe_load( textwrap.dedent("""\ decrypt_pillar: - 'secrets:vault:qux' """)) opts = self._build_opts(decrypt_pillar_opts) pillar_obj = pillar.Pillar(opts, grains, "test", "base") ret = pillar_obj.compile_pillar() expected = copy.deepcopy(GPG_PILLAR_ENCRYPTED) expected["secrets"]["vault"]["qux"][-1] = GPG_PILLAR_DECRYPTED[ "secrets"]["vault"]["qux"][-1] self.assertEqual(ret, expected)
def test_decrypt_pillar_explicit_renderer(self, grains=None): ''' Test recursive decryption of secrets:vault, with the renderer explicitly defined, overriding the default. Setting the default to a nonexistant renderer so we can be sure that the override happened. ''' decrypt_pillar_opts = yaml.safe_load(textwrap.dedent('''\ decrypt_pillar_default: asdf decrypt_pillar_renderers: - asdf - gpg decrypt_pillar: - 'secrets:vault': gpg ''')) opts = self._build_opts(decrypt_pillar_opts) pillar_obj = pillar.Pillar(opts, grains, 'test', 'base') ret = pillar_obj.compile_pillar() self.assertEqual(ret, GPG_PILLAR_DECRYPTED)