saltstack/salt — pull request #5805 by elbaschid (2013-06-30 13:30:29+00:00)
Title: Using files from other envs in source lists of file.managed states

I have been restructuring our configuration today trying to share files across environments. I looked a the docs of ``state.file`` where two scenarios are described:

1) Specifying a list of files and using the first one that can be found:
```
/etc/foo.conf:
file.managed:
- source:
- salt://foo.conf.{{ grains['fqdn'] }}
- salt://foo.conf.fallback
```

2) Specify a file in another environment:
```
/etc/foo.conf:
file.managed:
- source:
- salt://foo.conf?env=dev
```

My assumption based on this was that it would be possible to use a file specification similar to 2) in a list of files as in 1). Unfortunately, something like this does not work:
```
/etc/foo.conf:
file.managed:
- source:
- salt://foo.conf?env=dev
- salt://foo.conf.fallback
```

The reason why it doesn't work is that the ``modules.file.source_list`` function does not process the ``?env=dev`` part of a specified file/directory. It only retrieves the files/dirs for the current environment which doesn't produce a match for the first file in this example.

I guess my first question is, is my example a use case that salt should be able to do? Or am I trying to use it in a way that it is not meant for?

I think this is a very useful feature that allows for writing a generic state using a specific file from an environment 'dev' that prevent me from having to duplicate the state in the 'dev' and 'base' environment. And it gracefully falls back to a default configuration.

I've also put together a very naive implementation for ``salt/modules/file.py`` in [L1098](https://github.com/saltstack/salt/blob/develop/salt/modules/file.py#L1098) that makes source lists across environments possible. I'm sure this can be solve in a better way so this is just for reference:
```
def source_list(source, source_hash, env):
'''
Check the source list and return the source to use

CLI Example::
salt '*' file.source_list salt://http/httpd.conf '{hash_type: 'md5', 'hsum': }' base
'''
if isinstance(source, list):
mfiles = __salt__['cp.list_master'](env)
mdirs = __salt__['cp.list_master_dirs'](env)
for s in source:
try:
sname, senv = s.split('?env=')
except ValueError:
continue
else:
mfiles += ["{0}?env={1}".format(f, senv) for f in __salt__['cp.list_master'](senv)]
mdirs += ["{0}?env={1}".format(d, senv) for d in __salt__['cp.list_master_dirs'](senv)]
```

I hope this all makes sense. Thanks for any feedback and thoughts.