Repository: ansible/ansible-lint

Issue:
Misreading of include containing playbook_dir
I just got the following traceback which can be reproduced as follows:

```
$ git clone https://github.com/CiscoCloud/mantl
$ find . -name "*.yml" -exec ansible-lint {} \; -exec echo "PLAYBOOK: " {} \;                                                                                 
Traceback (most recent call last):
  File "/home/siddharthist/.virtualenvs/mantl/bin/ansible-lint", line 116, in <module>
    sys.exit(main(sys.argv[1:]))
  File "/home/siddharthist/.virtualenvs/mantl/bin/ansible-lint", line 103, in main
    matches = runner.run()
  File "/home/siddharthist/.virtualenvs/mantl/lib/python2.7/site-packages/ansiblelint/__init__.py", line 211, in run
    skip_list=set(self.skip_list)))
  File "/home/siddharthist/.virtualenvs/mantl/lib/python2.7/site-packages/ansiblelint/__init__.py", line 115, in run
    with open(playbookfile['path'], 'Ur') as f:
IOError: [Errno 2] No such file or directory: u'/home/siddharthist/Dropbox/code/asteris/mantl/addons/playbooks/check-requirements.yml'
Traceback (most recent call last):
  File "/home/siddharthist/.virtualenvs/mantl/bin/ansible-lint", line 116, in <module>
    sys.exit(main(sys.argv[1:]))
  File "/home/siddharthist/.virtualenvs/mantl/bin/ansible-lint", line 103, in main
    matches = runner.run()
  File "/home/siddharthist/.virtualenvs/mantl/lib/python2.7/site-packages/ansiblelint/__init__.py", line 211, in run
    skip_list=set(self.skip_list)))
  File "/home/siddharthist/.virtualenvs/mantl/lib/python2.7/site-packages/ansiblelint/__init__.py", line 115, in run
    with open(playbookfile['path'], 'Ur') as f:
IOError: [Errno 2] No such file or directory: u'/home/siddharthist/Dropbox/code/asteris/mantl/addons/playbooks/check-requirements.yml'
PLAYBOOK  ./addons/iptables.yml
```

Looks like there's a problem with parsing [the include line in that playbook](https://github.com/CiscoCloud/mantl/blob/da44f77a50ba1908b8e84eb190e78a3ffb496824/addons/elk.yml#L7).



Discussion:
It's definitely a bug as we should never throw a stack trace.

However, at the moment, ansible-lint does no templating of playbooks/roles at all - so dynamic includes don't really work (this is because ansible-lint doesn't really know what variables will expand to at runtime - we could special case playbook_dir but that might be a lot of work for one use case)

I should be able to remove the stack trace easily enough if that is acceptable.

That would be great! In my opinion, ansible-lint should simply ignore include lines with variables, (or do that for anything except `playbook_dir`, which is unambiguous). 

Hmm, this gets stranger. Looking again at the file being opened, `playbook_dir` must be being expanded, but incorrectly. I'll need to dig into this further once I have some time.

@willthames Have you been able to make any progress on this? 


Resolving patch:
diff --git a/lib/ansiblelint/utils.py b/lib/ansiblelint/utils.py
--- a/lib/ansiblelint/utils.py
+++ b/lib/ansiblelint/utils.py
@@ -32,8 +32,10 @@
 try:
     from ansible.utils import parse_yaml_from_file
     from ansible.utils import path_dwim
+    from ansible.utils.template import template
 except ImportError:
     from ansible.parsing.dataloader import DataLoader
+    from ansible.template import Templar
 
     def parse_yaml_from_file(filepath):
         dl = DataLoader()
@@ -44,6 +46,12 @@ def path_dwim(basedir, given):
         dl.set_basedir(basedir)
         return dl.path_dwim(given)
 
+    def template(basedir, varname, templatevars, **kwargs):
+        dl = DataLoader()
+        dl.set_basedir(basedir)
+        templar = Templar(dl, variables=templatevars)
+        return templar.template(varname, **kwargs)
+
 LINE_NUMBER_KEY = '__line__'
 
 VALID_KEYS = [
@@ -140,6 +148,7 @@ def play_children(basedir, item, parent_type):
     (k, v) = item
     if k in delegate_map:
         if v:
+            v = template(basedir, v, dict(playbook_dir=os.path.abspath(basedir)), fail_on_undefined=False)
             return delegate_map[k](basedir, k, v, parent_type)
     return []
 
diff --git a/lib/ansiblelint/version.py b/lib/ansiblelint/version.py
--- a/lib/ansiblelint/version.py
+++ b/lib/ansiblelint/version.py
@@ -1 +1 @@
-__version__ = '2.3.8'
+__version__ = '2.4.0'


Test patch: