redhat-developer / vscode-yaml

YAML support for VS Code with built-in kubernetes syntax support
MIT License
665 stars 222 forks source link

Ansible incorrect type errors when using Jinja #298

Open shadowzen1978 opened 4 years ago

shadowzen1978 commented 4 years ago

I know that the vscode-yaml extension is using schemastore to determine validation syntax but I hoping a solution can occur at this level.

I have been getting really annoying "incorrect type" errors in my Ansible roles when using Jinja placeholders. Here's an example:

---
# Adds an additional disk to a linux system
# Requires the disk to exist first

- name: Create a filesystem
  filesystem:
    dev: "{{add_disk_device_id}}"
    fstype: "{{add_disk_filesystem}}"
    force: "{{add_disk_force}}"
    opts: "{{add_disk_create_opts}}"
    resizefs: "{{add_disk_resize}}"
  become: yes
  when: linux_add_disk == true

- name: Mount disk
  mount:
    backup: yes
    src: "{{add_disk_device_id}}"
    path: "{{add_disk_mount_path}}"
    fstype: "{{add_disk_filesystem}}"
    opts: "{{add_disk_mount_opts}}"
    state: "{{add_disk_mount_state}}"
  become: yes
  when: linux_add_disk == true

That file throws the following errors: { "resource": "/Users/shadow/dev/repos/linux-mac-base/ansible/roles/fileshare/tasks/add_disk.yml", "owner": "_generated_diagnostic_collectionname#0", "code": "1", "severity": 8, "message": "Value is not accepted. Valid values: \"btrfs\", \"ext2\", \"ext3\", \"ext4\", \"ext4dev\", \"f2fs\", \"lvm\", \"ocfs2\", \"reiserfs\", \"xfs\", \"vfat\", \"swap\".", "startLineNumber": 8, "startColumn": 13, "endLineNumber": 8, "endColumn": 38 } { "resource": "/Users/shadow/dev/repos/linux-mac-base/ansible/roles/fileshare/tasks/add_disk.yml", "owner": "_generated_diagnostic_collectionname#0", "severity": 8, "message": "Incorrect type. Expected \"boolean\".", "startLineNumber": 9, "startColumn": 12, "endLineNumber": 9, "endColumn": 32 } { "resource": "/Users/shadow/dev/repos/linux-mac-base/ansible/roles/fileshare/tasks/add_disk.yml", "owner": "_generated_diagnostic_collectionname#0", "severity": 8, "message": "Incorrect type. Expected \"array\".", "startLineNumber": 10, "startColumn": 11, "endLineNumber": 10, "endColumn": 37 } { "resource": "/Users/shadow/dev/repos/linux-mac-base/ansible/roles/fileshare/tasks/add_disk.yml", "owner": "_generated_diagnostic_collectionname#0", "severity": 8, "message": "Incorrect type. Expected \"boolean\".", "startLineNumber": 11, "startColumn": 15, "endLineNumber": 11, "endColumn": 36 } { "resource": "/Users/shadow/dev/repos/linux-mac-base/ansible/roles/fileshare/tasks/add_disk.yml", "owner": "_generated_diagnostic_collectionname#0", "code": "1", "severity": 8, "message": "Value is not accepted. Valid values: \"absent\", \"mounted\", \"present\", \"unmounted\", \"remounted\".", "startLineNumber": 23, "startColumn": 12, "endLineNumber": 23, "endColumn": 38 }


So the easy way to handle this is to ignore an incorrect type error if Jinja syntax is used. Or another possible way is to override specific type errors (but that seems too complicated here, esp. with an autogenerated schema). In all these cases, the Jinja placeholders refer to variables that do contain the correct type or values but the validation occurs without those Jinja expressions being evaluated.

The only way to get around this seems to be disabling YAML validation completely but that seems a bit extreme. Since schemastore is an upstream dependency, I'm hoping a config can be added to vscode-yaml to ignore type errors of the value contains jinja expressions.

JPinkney commented 4 years ago

Hmm, I don't know what the best solution is here. Technically we could disable the error if Jinja syntax is used and it's probably not hard but then we will more then likely get requests from other users asking them to support their template engines as well

shadowzen1978 commented 4 years ago

Unfortunately, I don't see this as solvable upstream, given that, from the vscode plugin, we have no control over schemastore or the ansible schema generator it uses. Other linters can provide filtering of rules via hooks into a rule "index" but that's not present in this context.

Maybe a general solution would be an ignore filter that works off of regex that we could use. Then a user could add a list of regex filters based either on the value or the message string.

That gives the user power on how filter regardless of which templating engine is being used. That means I could just add a value match string like \{{2}.*\}{2} to ignore jinja expressions. Or, if ignoring by the message string returned is a better approach, I could filter any messages for ^Incorrect type or ^Value not accepted

Since I'm not clear on how exectly the vscode-yaml plugin integrates with schemastore, if there's a better way to implement an ignore filter directly within schemastore, let me know and I can make a feature request ticket on that repo instead.

JPinkney commented 4 years ago

I actually like the idea of using a regex to specify which values shouldn't be validated, I didn't think of that. That way we can technically support all the formats like jinja without having to write in extra code for each specific format.

I'm guessing it would probably be best if a user could set an array of regex's through a setting rather then one regex because it could be messy if they want to not validate multiple different formats in the same project

ewels commented 3 years ago

Is it possible to disable YAML validation completely for specific file pattern matches? That's a more brute-force approach but is what I came here to look for. I have 40 odd validation errors for my Jinja2 template so don't really fancy having to go through excluding each rule. I'd prefer to just ignore the relevant files in the project for the YAML / schema validation.

JPinkney commented 3 years ago

There's not currently a way to disable YAML validation for a specific file pattern, would you like to take a look into implementing it?

ewels commented 3 years ago

I would love to, but realistically I'm not sure it's going to happen sorry - I've never touched a VSCode plugin before (actually only switched to VSCode a couple of weeks ago) and it looks like it's all TypeScript? Which I've never used. So I think it'll probably take me an upsettingly long time to do even a simple implementation.

If you can point me in the direction of some code for an existing feature which is working in a similar way then I can try to fudge my way around it though.

joshuawilson commented 3 years ago

@ewels