Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VSCode Evaluate Selection Fails #1505

Closed
goffinf opened this issue Jun 20, 2019 · 7 comments
Closed

VSCode Evaluate Selection Fails #1505

goffinf opened this issue Jun 20, 2019 · 7 comments
Assignees

Comments

@goffinf
Copy link

goffinf commented Jun 20, 2019

Expected Behavior

Actual Behavior

Steps to Reproduce the Problem

  1. Use this YAML as the data file

nginx_demo_deploy.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-demo
  labels:
    app: nginx-demo
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx-demo
  template:
    metadata:
      labels:
        app: nginx-demo
    spec:
      containers:
      - name: nginx-demo
        image: nginx:latest
        ports:
        - containerPort: 80
  1. Use this simple policy file:

validate_labels_policy.rego

package kubernetes.labels

default allow = false

allow = true {
  data.kind == "Deployment"
  data.metadata.labels.app
}
  1. This simple unit test file:
package kubernetes.test_labels

import data.kubernetes.labels

test_allow {
    labels.allow
}
  1. Inside a VSCode terminal (wsl):
> opa test . -v
data.kubernetes.test_labels.test_allow: PASS (799.6µs)
--------------------------------------------------------------------------------

Unit tests work successfully. I can toggle PASS and FAIL by altering either the input YAML or the policy, so it would appear that the policy can find data.kind and metadata.labels.app

  1. Highlight 'data' on the first line of the allow policy, and evaluate the selection:
allow = true {
  data.kind == "Deployment"
  data.metadata.labels.app
}

The output.json pane shows the following (why the outer "c" level ??)

// Found 1 result in 0µs.
[
  [
    {
      "c": {
        "apiVersion": "apps/v1",
        "kind": "Deployment",
        "metadata": {
          "labels": {
            "app": "nginx-demo"
          },
          "name": "nginx-demo"
        },
        ...
  1. Now highlight 'data.kind' and evaluate the selection:

// No results found.

  1. If I change the line in the allow policy to:

allow = true {
data.c.kind == "Deployment"

The highlight and evaulate that selection the correct data is returned in output.json, but then the test FAILs:

// Found 1 result in 0µs.
[
  [
    "Deployment"
  ]
]

Why does the extra "c" level appear within data, and how can I get rid of it so that evaluate selection works correctly ?

Additional Info

OPA Extension version: 0.2.4
OPA version:

goffinf@myhostname:/c/Data/opa$ opa version
Version: 0.12.0
Build Commit: 64052c1c
Build Timestamp: 2019-06-11T22:03:36Z
Build Hostname: 74e59ffe492b

Platform: Windows 10 Prof : 1809

@tsandall
Copy link
Member

The VS Code plugin uses opa eval to evaluate queries. opa eval uses directory hierarchy to root JSON/YAML values under data. I'm guessing that you have your VS Code workspace opened / the YAML file on disk at /c/data.yaml. As a result, the content of /c/data.yaml gets rooted at data.c.

See opa eval --help for a similar description of how data is loaded.

@goffinf
Copy link
Author

goffinf commented Jun 21, 2019

Hey Torin, thx for the response. That makes perfect sense ... except the behaviour of opa eval in a terminal within VSCode is different to that when using evaluate selection within the editor. Let me explain, I'll cut everything down to a bare minimum....

The POLICY file:

C:\Data\opa\validate_labels_policy.rego

package kubernetes.labels

default allow = false

allow = true {
  data.kind == "Deployment"
  data.c.kind == "Deployment"
}

The policy TEST file:

C:\Data\opa\validate_labels_test.rego

package kubernetes.test_labels

import data.kubernetes.labels

test_allow {
    labels.allow
}

The data file:

C:\Data\opa\nginx_demo_deploy.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-demo
  labels:
    app: nginx-demo
    ...

Using opa eval from a TERMINAL within VSCode (in this case a cmd terminal - but its the same if I choose wsl).

First I ask for an eval of everything in 'data' ... and sure enough the whole of the nginx_demo_deploy.yaml file has been loaded, and no reference to 'c'

C:\Data\opa>opa eval data --data "nginx_demo_deploy.yaml"
{
  "result": [
    {
      "expressions": [
        {
          "value": {
            "apiVersion": "apps/v1",
            "kind": "Deployment",
            "metadata": {
              "labels": {
                "app": "nginx-demo"
              },
              "name": "nginx-demo"
            },
            "spec": {
              "replicas": 2,
              "selector": {
                "matchLabels": {
                  "app": "nginx-demo"
                }
              },
              "template": {
                "metadata": {
                  "labels": {
                    "app": "nginx-demo"
                  }
                },
                "spec": {
                  "containers": [
                    {
                      "image": "nginx:latest",
                      "name": "nginx-demo",
                      "ports": [
                        {
                          "containerPort": 80
                        }
                      ]
                    }
                  ]
                }
              }
            }
          },
          "text": "data",
          "location": {
            "row": 1,
            "col": 1
          }
        }
      ]
    }
  ]
}

If I then ask for an eval of data.kind ... it should return 'Deployment' ... and sure enough it does

C:\Data\opa>opa eval data.kind --data "nginx_demo_deploy.yaml"
{
  "result": [
    {
      "expressions": [
        {
          "value": "Deployment",
          "text": "data.kind",
          "location": {
            "row": 1,
            "col": 1
          }
        }
      ]
    }
  ]
}

Now switch to the VSCode editor pane with the POLICY file validate_labels_policy.rego open. Again this file on the file-system is in C:\Data\opa\validate_labels_policy.rego and C:\Data\opa is my current directory. As above, I will highlight 'data' on the first line of the allow block:

allow = true {
data.kind == "Deployment"
...
}

In the output.json pane I see (straight-away we see the 'c' ....

// Found 1 result in 0µs.
[
  [
    {
      "c": {
        "apiVersion": "apps/v1",
        "kind": "Deployment",
        "metadata": {
          "labels": {
            "app": "nginx-demo"
          }

... and if I then highlight data.kind, I get No results

// No results found.

Drop down a line, and highlight data.c.kind ...

// Found 1 result in 0µs.
[
  [
    "Deployment"
  ]
]

So, I still don't understand the difference between opa eval at the terminal and opa eval being called via the VSCode extension ?

It makes sense that specifying the policy rule WITHOUT the 'c' works because that is using the opa executable like the terminal.

What am I missing. How can I configure the extension in VSCode to behave in the same way as running opa at the command-line ?

Regards

Fraser.

@tsandall
Copy link
Member

Hrmmm. That's odd.

When you select data and evaluate it, the opa eval command run by VS Code is something like...

opa eval -d $ROOT_OF_WORKSPACE 'data'

This returns the value of all the JSON/YAML on disk as well as all values generated by rules in .rego files on disk. For some reason, the nginx_demo_deploy.yaml file is being rooted under "c". I'm wondering if this is a Windows filepath issue. If you have another drive that you could open VS Code in, it would be interesting to know if it gets rooted under the drive letter (e.g., "d").

Is your VS Code workspace opened inside C:\Data\opa or something else?

@tsandall
Copy link
Member

OK. I was able to easily reproduce the problem inside a Windows VM.

If you run the following command, it will output the same value you see in VS Code.

opa eval -d C:\Data\opa 'data'

The problem appears to be with how the file loader in OPA deals with Windows paths.

@tsandall tsandall added the bug label Jun 21, 2019
@goffinf
Copy link
Author

goffinf commented Jun 21, 2019

Ok, a bit more info ...

In the terminal I was actually running from the directory where the data file is located, so I didn't provide the full path. If I do provide the full path, the data is located under 'c' like it is in the editor. So presumably the extension is resolving the absolute path and that is why it also put the data under 'c'.

C:\Data\opa>opa eval data --data "c:\Data\opa\nginx_demo_deploy.yaml"
{
  "result": [
    {
      "expressions": [
        {
          "value": {
            "c": {
              "apiVersion": "apps/v1",
              "kind": "Deployment",
              "metadata": {
                "labels": {
                  "app": "nginx-demo"
                }

@goffinf
Copy link
Author

goffinf commented Jun 21, 2019

Ah, looks like our updates crossed and we both found the same explanation.

I see that you have changed this to type ‘bug’, so I’ll wait for the patched version, but workaround it for now.

Thanks for the swift response.

Fraser.

@tsandall tsandall self-assigned this Aug 21, 2019
tsandall added a commit to tsandall/opa that referenced this issue Aug 22, 2019
The file loader splits paths on the first colon character and uses the
left-hand side for the prefix to root the document at under data. On
windows this is problematic because of drive lettesr (e.g., C:\X\Y\Z
is interpreted as load file at \X\Y\Z under data.C.

This change updates the loader to accept file:// URLs. This way
callers can unambiguously specify filenames that contain colon
characters. For now this will mainly be used by VS Code and other
programmatic callers. In future we can support other schemes (e.g., http).

Fixes open-policy-agent#1505

Signed-off-by: Torin Sandall <torinsandall@gmail.com>
@tsandall
Copy link
Member

tsandall commented Aug 22, 2019

The OPA extension for VS code has been updated to use file:// URLs instead of just passing file paths. This should resolve the issue on Windows. The next OPA release will contain this fix. Until then you can build from source or download the edge binary from https://opa-releases.s3.amazonaws.com/edge/opa_windows_amd64.exe shortly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Archived in project
Development

No branches or pull requests

2 participants