From 7663100ef51d1a0e29b65197c4376534fff9435f Mon Sep 17 00:00:00 2001 From: Claire Gaestel <213631+nyobe@users.noreply.github.com> Date: Fri, 14 Feb 2025 15:46:47 -0800 Subject: [PATCH] treat symbols starting with dot as accessing the document root, which contains all reserved keys --- ast/property.go | 6 + eval/eval.go | 60 +- eval/testdata/eval/access-root/env.yaml | 13 + eval/testdata/eval/access-root/expected.json | 2875 +++++++++++++++++ eval/testdata/eval/access-root/foo/bar.yaml | 2 + eval/testdata/eval/reserved-keys/env.yaml | 1 + .../testdata/eval/reserved-keys/expected.json | 46 + 7 files changed, 2986 insertions(+), 17 deletions(-) create mode 100644 eval/testdata/eval/access-root/env.yaml create mode 100644 eval/testdata/eval/access-root/expected.json create mode 100644 eval/testdata/eval/access-root/foo/bar.yaml diff --git a/ast/property.go b/ast/property.go index 788c7f076..f1bcf02cb 100644 --- a/ast/property.go +++ b/ast/property.go @@ -143,6 +143,12 @@ func (p *propertyAccessParser) peek() (byte, bool) { // Parses a property access. See the comment on parsePropertyAccess for the grammar and examples. func (p *propertyAccessParser) parse() (int, string, *PropertyAccess, syntax.Diagnostics) { + if c, ok := p.peek(); ok && c == '.' { + // treating an empty initial property name (which is otherwise illegal) as access to the document root + // (conceptually the first property for `.foo` is empty) + p.append(&PropertyName{Name: "", AccessorRange: p.rangeFrom(p.offset)}) + } + for { c, ok := p.peek() if !ok { diff --git a/eval/eval.go b/eval/eval.go index bc548dbdd..504dc1ccd 100644 --- a/eval/eval.go +++ b/eval/eval.go @@ -719,27 +719,18 @@ func (e *evalContext) evaluatePropertyAccess(x *expr, accessors []*propertyAcces // is any other type of expression, it is evaluated and the result is passed to evaluateValueAccess. Once all accessors // have been processed, the resolved expression is evaluated. func (e *evalContext) evaluateExprAccess(x *expr, accessors []*propertyAccessor, accept *schema.Schema) *value { - receiver := e.root - k, ok := e.objectKey(x.repr.syntax(), accessors[0].accessor, false) - // Check for an imports access. - if ok && k == "imports" { - accessors[0].value = e.myImports - return e.evaluateValueAccess(x.repr.syntax(), e.myImports, accessors[1:]) + // root access + if ok && k == "" { + return e.evaluateRootAccess(x, accessors[1:], accept) } - - // Check for context interpolation. - if ok && k == "context" { - accessors[0].value = e.myContext - return e.evaluateValueAccess(x.repr.syntax(), e.myContext, accessors[1:]) - } - - // Check for inline reference - if ok && k == "environments" { - return e.evaluateEnvironmentReferenceAccess(x, accessors, accept) + // reserved top-level key access -- these keys are reserved within the context of `values` + if ok && e.isReserveTopLevelKey(k) { + return e.evaluateRootAccess(x, accessors, accept) } + receiver := e.root for len(accessors) > 0 { accessor := accessors[0] if receiver == nil { @@ -792,9 +783,44 @@ func (e *evalContext) evaluateExprAccess(x *expr, accessors []*propertyAccessor, return e.evaluateExpr(receiver, schema.Always()) } +// evaluateRootAccess evaluates access to the reserved keys "mounted" at document root +func (e *evalContext) evaluateRootAccess(x *expr, accessors []*propertyAccessor, accept *schema.Schema) *value { + k, ok := e.objectKey(x.repr.syntax(), accessors[0].accessor, false) + + // Check for an imports access. + if ok && k == "imports" { + accessors[0].value = e.myImports + return e.evaluateValueAccess(x.repr.syntax(), e.myImports, accessors[1:]) + } + + // Check for context interpolation. + if ok && k == "context" { + accessors[0].value = e.myContext + return e.evaluateValueAccess(x.repr.syntax(), e.myContext, accessors[1:]) + } + + // Check for environment reference + if ok && k == "environments" { + return e.evaluateEnvironmentReferenceAccess(x, accessors) + } + + // Check for values access. + // There isn't really any reason for a user to do this, because ${.values.foo} === ${foo}, it's just for consistency + if ok && k == "values" { + if len(accessors) == 1 { + // referencing ${.values} is inherently cyclical + e.errorf(x.repr.syntax(), "cyclic reference to values") + return &value{def: x, schema: schema.Always().Schema(), unknown: true} + } + return e.evaluateExprAccess(x, accessors[1:], accept) + } + + return e.invalidPropertyAccess(x.repr.syntax(), accessors) +} + // evaluateEnvironmentReferenceAccess performs an inline import of an environment. // The accessor is of the form ["environments", $project, $env, ...], which is transformed into an import name in the form "$project/$env" -func (e *evalContext) evaluateEnvironmentReferenceAccess(x *expr, accessors []*propertyAccessor, accept *schema.Schema) *value { +func (e *evalContext) evaluateEnvironmentReferenceAccess(x *expr, accessors []*propertyAccessor) *value { // desugar accessor path into import name if len(accessors) < 3 { // need at least the first three elements to create an import name diff --git a/eval/testdata/eval/access-root/env.yaml b/eval/testdata/eval/access-root/env.yaml new file mode 100644 index 000000000..415b7e6cd --- /dev/null +++ b/eval/testdata/eval/access-root/env.yaml @@ -0,0 +1,13 @@ +imports: + - foo/bar + +values: + foo: "hello!" + + imp: ${.imports} + ctx: ${.context} + env: ${.environments} + env2: ${.environments.foo.bar.some_value} + values: ${.values} + values2: ${.values.foo} + invalid: ${.invalid} diff --git a/eval/testdata/eval/access-root/expected.json b/eval/testdata/eval/access-root/expected.json new file mode 100644 index 000000000..b61e88675 --- /dev/null +++ b/eval/testdata/eval/access-root/expected.json @@ -0,0 +1,2875 @@ +{ + "checkDiags": [ + { + "Severity": 1, + "Summary": "cyclic reference to values", + "Detail": "", + "Subject": { + "Filename": "access-root", + "Start": { + "Line": 11, + "Column": 11, + "Byte": 163 + }, + "End": { + "Line": 11, + "Column": 21, + "Byte": 173 + } + }, + "Context": null, + "Expression": null, + "EvalContext": null, + "Extra": null, + "Path": "values.values" + } + ], + "check": { + "exprs": { + "ctx": { + "range": { + "environment": "access-root", + "begin": { + "line": 8, + "column": 8, + "byte": 73 + }, + "end": { + "line": 8, + "column": 19, + "byte": 84 + } + }, + "schema": { + "properties": { + "currentEnvironment": { + "properties": { + "name": { + "type": "string", + "const": "access-root" + } + }, + "type": "object", + "required": [ + "name" + ] + }, + "pulumi": { + "properties": { + "user": { + "properties": { + "id": { + "type": "string", + "const": "USER_123" + } + }, + "type": "object", + "required": [ + "id" + ] + } + }, + "type": "object", + "required": [ + "user" + ] + }, + "rootEnvironment": { + "properties": { + "name": { + "type": "string", + "const": "access-root" + } + }, + "type": "object", + "required": [ + "name" + ] + } + }, + "type": "object", + "required": [ + "currentEnvironment", + "pulumi", + "rootEnvironment" + ] + }, + "symbol": [ + { + "key": "", + "range": { + "environment": "access-root", + "begin": { + "line": 8, + "column": 10, + "byte": 75 + }, + "end": { + "line": 8, + "column": 10, + "byte": 75 + } + }, + "value": { + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + }, + { + "key": "context", + "range": { + "environment": "access-root", + "begin": { + "line": 8, + "column": 10, + "byte": 75 + }, + "end": { + "line": 8, + "column": 18, + "byte": 83 + } + }, + "value": { + "environment": "access-root", + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + } + ] + }, + "env": { + "range": { + "environment": "access-root", + "begin": { + "line": 9, + "column": 8, + "byte": 92 + }, + "end": { + "line": 9, + "column": 24, + "byte": 108 + } + }, + "schema": true, + "symbol": [ + { + "key": "", + "range": { + "environment": "access-root", + "begin": { + "line": 9, + "column": 10, + "byte": 94 + }, + "end": { + "line": 9, + "column": 10, + "byte": 94 + } + }, + "value": { + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + }, + { + "key": "environments", + "range": { + "environment": "access-root", + "begin": { + "line": 9, + "column": 10, + "byte": 94 + }, + "end": { + "line": 9, + "column": 23, + "byte": 107 + } + }, + "value": { + "environment": "access-root", + "begin": { + "line": 9, + "column": 8, + "byte": 92 + }, + "end": { + "line": 9, + "column": 24, + "byte": 108 + } + } + } + ] + }, + "env2": { + "range": { + "environment": "access-root", + "begin": { + "line": 10, + "column": 9, + "byte": 117 + }, + "end": { + "line": 10, + "column": 44, + "byte": 152 + } + }, + "schema": { + "type": "number", + "const": 42 + }, + "symbol": [ + { + "key": "", + "range": { + "environment": "access-root", + "begin": { + "line": 10, + "column": 11, + "byte": 119 + }, + "end": { + "line": 10, + "column": 11, + "byte": 119 + } + }, + "value": { + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + }, + { + "key": "environments", + "range": { + "environment": "access-root", + "begin": { + "line": 10, + "column": 11, + "byte": 119 + }, + "end": { + "line": 10, + "column": 24, + "byte": 132 + } + }, + "value": { + "environment": "access-root", + "begin": { + "line": 10, + "column": 9, + "byte": 117 + }, + "end": { + "line": 10, + "column": 44, + "byte": 152 + } + } + }, + { + "key": "foo", + "range": { + "environment": "access-root", + "begin": { + "line": 10, + "column": 24, + "byte": 132 + }, + "end": { + "line": 10, + "column": 28, + "byte": 136 + } + }, + "value": { + "environment": "access-root", + "begin": { + "line": 10, + "column": 9, + "byte": 117 + }, + "end": { + "line": 10, + "column": 44, + "byte": 152 + } + } + }, + { + "key": "bar", + "range": { + "environment": "access-root", + "begin": { + "line": 10, + "column": 28, + "byte": 136 + }, + "end": { + "line": 10, + "column": 32, + "byte": 140 + } + }, + "value": { + "environment": "access-root", + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + }, + { + "key": "some_value", + "range": { + "environment": "access-root", + "begin": { + "line": 10, + "column": 32, + "byte": 140 + }, + "end": { + "line": 10, + "column": 43, + "byte": 151 + } + }, + "value": { + "environment": "foo/bar", + "begin": { + "line": 2, + "column": 15, + "byte": 22 + }, + "end": { + "line": 2, + "column": 17, + "byte": 24 + } + } + } + ] + }, + "foo": { + "range": { + "environment": "access-root", + "begin": { + "line": 5, + "column": 8, + "byte": 37 + }, + "end": { + "line": 5, + "column": 14, + "byte": 43 + } + }, + "schema": { + "type": "string", + "const": "hello!" + }, + "literal": "hello!" + }, + "imp": { + "range": { + "environment": "access-root", + "begin": { + "line": 7, + "column": 8, + "byte": 54 + }, + "end": { + "line": 7, + "column": 19, + "byte": 65 + } + }, + "schema": { + "properties": { + "foo/bar": { + "properties": { + "some_value": { + "type": "number", + "const": 42 + } + }, + "type": "object", + "required": [ + "some_value" + ] + } + }, + "type": "object", + "required": [ + "foo/bar" + ] + }, + "symbol": [ + { + "key": "", + "range": { + "environment": "access-root", + "begin": { + "line": 7, + "column": 10, + "byte": 56 + }, + "end": { + "line": 7, + "column": 10, + "byte": 56 + } + }, + "value": { + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + }, + { + "key": "imports", + "range": { + "environment": "access-root", + "begin": { + "line": 7, + "column": 10, + "byte": 56 + }, + "end": { + "line": 7, + "column": 18, + "byte": 64 + } + }, + "value": { + "environment": "access-root", + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + } + ] + }, + "invalid": { + "range": { + "environment": "access-root", + "begin": { + "line": 13, + "column": 12, + "byte": 211 + }, + "end": { + "line": 13, + "column": 23, + "byte": 222 + } + }, + "schema": true, + "symbol": [ + { + "key": "", + "range": { + "environment": "access-root", + "begin": { + "line": 13, + "column": 14, + "byte": 213 + }, + "end": { + "line": 13, + "column": 14, + "byte": 213 + } + }, + "value": { + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + }, + { + "key": "invalid", + "range": { + "environment": "access-root", + "begin": { + "line": 13, + "column": 14, + "byte": 213 + }, + "end": { + "line": 13, + "column": 22, + "byte": 221 + } + }, + "value": { + "environment": "access-root", + "begin": { + "line": 13, + "column": 12, + "byte": 211 + }, + "end": { + "line": 13, + "column": 23, + "byte": 222 + } + } + } + ] + }, + "values": { + "range": { + "environment": "access-root", + "begin": { + "line": 11, + "column": 11, + "byte": 163 + }, + "end": { + "line": 11, + "column": 21, + "byte": 173 + } + }, + "schema": true, + "symbol": [ + { + "key": "", + "range": { + "environment": "access-root", + "begin": { + "line": 11, + "column": 13, + "byte": 165 + }, + "end": { + "line": 11, + "column": 13, + "byte": 165 + } + }, + "value": { + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + }, + { + "key": "values", + "range": { + "environment": "access-root", + "begin": { + "line": 11, + "column": 13, + "byte": 165 + }, + "end": { + "line": 11, + "column": 20, + "byte": 172 + } + }, + "value": { + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + } + ] + }, + "values2": { + "range": { + "environment": "access-root", + "begin": { + "line": 12, + "column": 12, + "byte": 185 + }, + "end": { + "line": 12, + "column": 26, + "byte": 199 + } + }, + "schema": { + "type": "string", + "const": "hello!" + }, + "symbol": [ + { + "key": "", + "range": { + "environment": "access-root", + "begin": { + "line": 12, + "column": 14, + "byte": 187 + }, + "end": { + "line": 12, + "column": 14, + "byte": 187 + } + }, + "value": { + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + }, + { + "key": "values", + "range": { + "environment": "access-root", + "begin": { + "line": 12, + "column": 14, + "byte": 187 + }, + "end": { + "line": 12, + "column": 21, + "byte": 194 + } + }, + "value": { + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + }, + { + "key": "foo", + "range": { + "environment": "access-root", + "begin": { + "line": 12, + "column": 21, + "byte": 194 + }, + "end": { + "line": 12, + "column": 25, + "byte": 198 + } + }, + "value": { + "environment": "access-root", + "begin": { + "line": 5, + "column": 8, + "byte": 37 + }, + "end": { + "line": 5, + "column": 14, + "byte": 43 + } + } + } + ] + } + }, + "properties": { + "ctx": { + "value": { + "currentEnvironment": { + "value": { + "name": { + "value": "access-root", + "trace": { + "def": { + "environment": "access-root", + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + } + } + }, + "trace": { + "def": { + "environment": "access-root", + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + } + }, + "pulumi": { + "value": { + "user": { + "value": { + "id": { + "value": "USER_123", + "trace": { + "def": { + "environment": "access-root", + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + } + } + }, + "trace": { + "def": { + "environment": "access-root", + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + } + } + }, + "trace": { + "def": { + "environment": "access-root", + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + } + }, + "rootEnvironment": { + "value": { + "name": { + "value": "access-root", + "trace": { + "def": { + "environment": "access-root", + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + } + } + }, + "trace": { + "def": { + "environment": "access-root", + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + } + } + }, + "trace": { + "def": { + "environment": "access-root", + "begin": { + "line": 8, + "column": 8, + "byte": 73 + }, + "end": { + "line": 8, + "column": 19, + "byte": 84 + } + } + } + }, + "env": { + "unknown": true, + "trace": { + "def": { + "environment": "access-root", + "begin": { + "line": 9, + "column": 8, + "byte": 92 + }, + "end": { + "line": 9, + "column": 24, + "byte": 108 + } + } + } + }, + "env2": { + "value": 42, + "trace": { + "def": { + "environment": "access-root", + "begin": { + "line": 10, + "column": 9, + "byte": 117 + }, + "end": { + "line": 10, + "column": 44, + "byte": 152 + } + } + } + }, + "foo": { + "value": "hello!", + "trace": { + "def": { + "environment": "access-root", + "begin": { + "line": 5, + "column": 8, + "byte": 37 + }, + "end": { + "line": 5, + "column": 14, + "byte": 43 + } + } + } + }, + "imp": { + "value": { + "foo/bar": { + "value": { + "some_value": { + "value": 42, + "trace": { + "def": { + "environment": "foo/bar", + "begin": { + "line": 2, + "column": 15, + "byte": 22 + }, + "end": { + "line": 2, + "column": 17, + "byte": 24 + } + } + } + } + }, + "trace": { + "def": { + "environment": "access-root", + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + } + } + }, + "trace": { + "def": { + "environment": "access-root", + "begin": { + "line": 7, + "column": 8, + "byte": 54 + }, + "end": { + "line": 7, + "column": 19, + "byte": 65 + } + } + } + }, + "invalid": { + "unknown": true, + "trace": { + "def": { + "environment": "access-root", + "begin": { + "line": 13, + "column": 12, + "byte": 211 + }, + "end": { + "line": 13, + "column": 23, + "byte": 222 + } + } + } + }, + "some_value": { + "value": 42, + "trace": { + "def": { + "environment": "foo/bar", + "begin": { + "line": 2, + "column": 15, + "byte": 22 + }, + "end": { + "line": 2, + "column": 17, + "byte": 24 + } + } + } + }, + "values": { + "unknown": true, + "trace": { + "def": { + "environment": "access-root", + "begin": { + "line": 11, + "column": 11, + "byte": 163 + }, + "end": { + "line": 11, + "column": 21, + "byte": 173 + } + } + } + }, + "values2": { + "value": "hello!", + "trace": { + "def": { + "environment": "access-root", + "begin": { + "line": 12, + "column": 12, + "byte": 185 + }, + "end": { + "line": 12, + "column": 26, + "byte": 199 + } + } + } + } + }, + "schema": { + "properties": { + "ctx": { + "properties": { + "currentEnvironment": { + "properties": { + "name": { + "type": "string", + "const": "access-root" + } + }, + "type": "object", + "required": [ + "name" + ] + }, + "pulumi": { + "properties": { + "user": { + "properties": { + "id": { + "type": "string", + "const": "USER_123" + } + }, + "type": "object", + "required": [ + "id" + ] + } + }, + "type": "object", + "required": [ + "user" + ] + }, + "rootEnvironment": { + "properties": { + "name": { + "type": "string", + "const": "access-root" + } + }, + "type": "object", + "required": [ + "name" + ] + } + }, + "type": "object", + "required": [ + "currentEnvironment", + "pulumi", + "rootEnvironment" + ] + }, + "env": true, + "env2": { + "type": "number", + "const": 42 + }, + "foo": { + "type": "string", + "const": "hello!" + }, + "imp": { + "properties": { + "foo/bar": { + "properties": { + "some_value": { + "type": "number", + "const": 42 + } + }, + "type": "object", + "required": [ + "some_value" + ] + } + }, + "type": "object", + "required": [ + "foo/bar" + ] + }, + "invalid": true, + "some_value": { + "type": "number", + "const": 42 + }, + "values": true, + "values2": { + "type": "string", + "const": "hello!" + } + }, + "type": "object", + "required": [ + "ctx", + "env", + "env2", + "foo", + "imp", + "invalid", + "some_value", + "values", + "values2" + ] + }, + "executionContext": { + "properties": { + "currentEnvironment": { + "value": { + "name": { + "value": "access-root", + "trace": { + "def": { + "environment": "access-root", + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + } + } + }, + "trace": { + "def": { + "environment": "access-root", + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + } + }, + "pulumi": { + "value": { + "user": { + "value": { + "id": { + "value": "USER_123", + "trace": { + "def": { + "environment": "access-root", + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + } + } + }, + "trace": { + "def": { + "environment": "access-root", + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + } + } + }, + "trace": { + "def": { + "environment": "access-root", + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + } + }, + "rootEnvironment": { + "value": { + "name": { + "value": "access-root", + "trace": { + "def": { + "environment": "access-root", + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + } + } + }, + "trace": { + "def": { + "environment": "access-root", + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + } + } + }, + "schema": { + "properties": { + "currentEnvironment": { + "properties": { + "name": { + "type": "string", + "const": "access-root" + } + }, + "type": "object", + "required": [ + "name" + ] + }, + "pulumi": { + "properties": { + "user": { + "properties": { + "id": { + "type": "string", + "const": "USER_123" + } + }, + "type": "object", + "required": [ + "id" + ] + } + }, + "type": "object", + "required": [ + "user" + ] + }, + "rootEnvironment": { + "properties": { + "name": { + "type": "string", + "const": "access-root" + } + }, + "type": "object", + "required": [ + "name" + ] + } + }, + "type": "object", + "required": [ + "currentEnvironment", + "pulumi", + "rootEnvironment" + ] + } + } + }, + "checkJson": { + "ctx": { + "currentEnvironment": { + "name": "access-root" + }, + "pulumi": { + "user": { + "id": "USER_123" + } + }, + "rootEnvironment": { + "name": "access-root" + } + }, + "env": "[unknown]", + "env2": 42, + "foo": "hello!", + "imp": { + "foo/bar": { + "some_value": 42 + } + }, + "invalid": "[unknown]", + "some_value": 42, + "values": "[unknown]", + "values2": "hello!" + }, + "evalDiags": [ + { + "Severity": 1, + "Summary": "cyclic reference to values", + "Detail": "", + "Subject": { + "Filename": "access-root", + "Start": { + "Line": 11, + "Column": 11, + "Byte": 163 + }, + "End": { + "Line": 11, + "Column": 21, + "Byte": 173 + } + }, + "Context": null, + "Expression": null, + "EvalContext": null, + "Extra": null, + "Path": "values.values" + } + ], + "eval": { + "exprs": { + "ctx": { + "range": { + "environment": "access-root", + "begin": { + "line": 8, + "column": 8, + "byte": 73 + }, + "end": { + "line": 8, + "column": 19, + "byte": 84 + } + }, + "schema": { + "properties": { + "currentEnvironment": { + "properties": { + "name": { + "type": "string", + "const": "access-root" + } + }, + "type": "object", + "required": [ + "name" + ] + }, + "pulumi": { + "properties": { + "user": { + "properties": { + "id": { + "type": "string", + "const": "USER_123" + } + }, + "type": "object", + "required": [ + "id" + ] + } + }, + "type": "object", + "required": [ + "user" + ] + }, + "rootEnvironment": { + "properties": { + "name": { + "type": "string", + "const": "access-root" + } + }, + "type": "object", + "required": [ + "name" + ] + } + }, + "type": "object", + "required": [ + "currentEnvironment", + "pulumi", + "rootEnvironment" + ] + }, + "symbol": [ + { + "key": "", + "range": { + "environment": "access-root", + "begin": { + "line": 8, + "column": 10, + "byte": 75 + }, + "end": { + "line": 8, + "column": 10, + "byte": 75 + } + }, + "value": { + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + }, + { + "key": "context", + "range": { + "environment": "access-root", + "begin": { + "line": 8, + "column": 10, + "byte": 75 + }, + "end": { + "line": 8, + "column": 18, + "byte": 83 + } + }, + "value": { + "environment": "access-root", + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + } + ] + }, + "env": { + "range": { + "environment": "access-root", + "begin": { + "line": 9, + "column": 8, + "byte": 92 + }, + "end": { + "line": 9, + "column": 24, + "byte": 108 + } + }, + "schema": true, + "symbol": [ + { + "key": "", + "range": { + "environment": "access-root", + "begin": { + "line": 9, + "column": 10, + "byte": 94 + }, + "end": { + "line": 9, + "column": 10, + "byte": 94 + } + }, + "value": { + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + }, + { + "key": "environments", + "range": { + "environment": "access-root", + "begin": { + "line": 9, + "column": 10, + "byte": 94 + }, + "end": { + "line": 9, + "column": 23, + "byte": 107 + } + }, + "value": { + "environment": "access-root", + "begin": { + "line": 9, + "column": 8, + "byte": 92 + }, + "end": { + "line": 9, + "column": 24, + "byte": 108 + } + } + } + ] + }, + "env2": { + "range": { + "environment": "access-root", + "begin": { + "line": 10, + "column": 9, + "byte": 117 + }, + "end": { + "line": 10, + "column": 44, + "byte": 152 + } + }, + "schema": { + "type": "number", + "const": 42 + }, + "symbol": [ + { + "key": "", + "range": { + "environment": "access-root", + "begin": { + "line": 10, + "column": 11, + "byte": 119 + }, + "end": { + "line": 10, + "column": 11, + "byte": 119 + } + }, + "value": { + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + }, + { + "key": "environments", + "range": { + "environment": "access-root", + "begin": { + "line": 10, + "column": 11, + "byte": 119 + }, + "end": { + "line": 10, + "column": 24, + "byte": 132 + } + }, + "value": { + "environment": "access-root", + "begin": { + "line": 10, + "column": 9, + "byte": 117 + }, + "end": { + "line": 10, + "column": 44, + "byte": 152 + } + } + }, + { + "key": "foo", + "range": { + "environment": "access-root", + "begin": { + "line": 10, + "column": 24, + "byte": 132 + }, + "end": { + "line": 10, + "column": 28, + "byte": 136 + } + }, + "value": { + "environment": "access-root", + "begin": { + "line": 10, + "column": 9, + "byte": 117 + }, + "end": { + "line": 10, + "column": 44, + "byte": 152 + } + } + }, + { + "key": "bar", + "range": { + "environment": "access-root", + "begin": { + "line": 10, + "column": 28, + "byte": 136 + }, + "end": { + "line": 10, + "column": 32, + "byte": 140 + } + }, + "value": { + "environment": "access-root", + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + }, + { + "key": "some_value", + "range": { + "environment": "access-root", + "begin": { + "line": 10, + "column": 32, + "byte": 140 + }, + "end": { + "line": 10, + "column": 43, + "byte": 151 + } + }, + "value": { + "environment": "foo/bar", + "begin": { + "line": 2, + "column": 15, + "byte": 22 + }, + "end": { + "line": 2, + "column": 17, + "byte": 24 + } + } + } + ] + }, + "foo": { + "range": { + "environment": "access-root", + "begin": { + "line": 5, + "column": 8, + "byte": 37 + }, + "end": { + "line": 5, + "column": 14, + "byte": 43 + } + }, + "schema": { + "type": "string", + "const": "hello!" + }, + "literal": "hello!" + }, + "imp": { + "range": { + "environment": "access-root", + "begin": { + "line": 7, + "column": 8, + "byte": 54 + }, + "end": { + "line": 7, + "column": 19, + "byte": 65 + } + }, + "schema": { + "properties": { + "foo/bar": { + "properties": { + "some_value": { + "type": "number", + "const": 42 + } + }, + "type": "object", + "required": [ + "some_value" + ] + } + }, + "type": "object", + "required": [ + "foo/bar" + ] + }, + "symbol": [ + { + "key": "", + "range": { + "environment": "access-root", + "begin": { + "line": 7, + "column": 10, + "byte": 56 + }, + "end": { + "line": 7, + "column": 10, + "byte": 56 + } + }, + "value": { + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + }, + { + "key": "imports", + "range": { + "environment": "access-root", + "begin": { + "line": 7, + "column": 10, + "byte": 56 + }, + "end": { + "line": 7, + "column": 18, + "byte": 64 + } + }, + "value": { + "environment": "access-root", + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + } + ] + }, + "invalid": { + "range": { + "environment": "access-root", + "begin": { + "line": 13, + "column": 12, + "byte": 211 + }, + "end": { + "line": 13, + "column": 23, + "byte": 222 + } + }, + "schema": true, + "symbol": [ + { + "key": "", + "range": { + "environment": "access-root", + "begin": { + "line": 13, + "column": 14, + "byte": 213 + }, + "end": { + "line": 13, + "column": 14, + "byte": 213 + } + }, + "value": { + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + }, + { + "key": "invalid", + "range": { + "environment": "access-root", + "begin": { + "line": 13, + "column": 14, + "byte": 213 + }, + "end": { + "line": 13, + "column": 22, + "byte": 221 + } + }, + "value": { + "environment": "access-root", + "begin": { + "line": 13, + "column": 12, + "byte": 211 + }, + "end": { + "line": 13, + "column": 23, + "byte": 222 + } + } + } + ] + }, + "values": { + "range": { + "environment": "access-root", + "begin": { + "line": 11, + "column": 11, + "byte": 163 + }, + "end": { + "line": 11, + "column": 21, + "byte": 173 + } + }, + "schema": true, + "symbol": [ + { + "key": "", + "range": { + "environment": "access-root", + "begin": { + "line": 11, + "column": 13, + "byte": 165 + }, + "end": { + "line": 11, + "column": 13, + "byte": 165 + } + }, + "value": { + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + }, + { + "key": "values", + "range": { + "environment": "access-root", + "begin": { + "line": 11, + "column": 13, + "byte": 165 + }, + "end": { + "line": 11, + "column": 20, + "byte": 172 + } + }, + "value": { + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + } + ] + }, + "values2": { + "range": { + "environment": "access-root", + "begin": { + "line": 12, + "column": 12, + "byte": 185 + }, + "end": { + "line": 12, + "column": 26, + "byte": 199 + } + }, + "schema": { + "type": "string", + "const": "hello!" + }, + "symbol": [ + { + "key": "", + "range": { + "environment": "access-root", + "begin": { + "line": 12, + "column": 14, + "byte": 187 + }, + "end": { + "line": 12, + "column": 14, + "byte": 187 + } + }, + "value": { + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + }, + { + "key": "values", + "range": { + "environment": "access-root", + "begin": { + "line": 12, + "column": 14, + "byte": 187 + }, + "end": { + "line": 12, + "column": 21, + "byte": 194 + } + }, + "value": { + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + }, + { + "key": "foo", + "range": { + "environment": "access-root", + "begin": { + "line": 12, + "column": 21, + "byte": 194 + }, + "end": { + "line": 12, + "column": 25, + "byte": 198 + } + }, + "value": { + "environment": "access-root", + "begin": { + "line": 5, + "column": 8, + "byte": 37 + }, + "end": { + "line": 5, + "column": 14, + "byte": 43 + } + } + } + ] + } + }, + "properties": { + "ctx": { + "value": { + "currentEnvironment": { + "value": { + "name": { + "value": "access-root", + "trace": { + "def": { + "environment": "access-root", + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + } + } + }, + "trace": { + "def": { + "environment": "access-root", + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + } + }, + "pulumi": { + "value": { + "user": { + "value": { + "id": { + "value": "USER_123", + "trace": { + "def": { + "environment": "access-root", + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + } + } + }, + "trace": { + "def": { + "environment": "access-root", + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + } + } + }, + "trace": { + "def": { + "environment": "access-root", + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + } + }, + "rootEnvironment": { + "value": { + "name": { + "value": "access-root", + "trace": { + "def": { + "environment": "access-root", + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + } + } + }, + "trace": { + "def": { + "environment": "access-root", + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + } + } + }, + "trace": { + "def": { + "environment": "access-root", + "begin": { + "line": 8, + "column": 8, + "byte": 73 + }, + "end": { + "line": 8, + "column": 19, + "byte": 84 + } + } + } + }, + "env": { + "unknown": true, + "trace": { + "def": { + "environment": "access-root", + "begin": { + "line": 9, + "column": 8, + "byte": 92 + }, + "end": { + "line": 9, + "column": 24, + "byte": 108 + } + } + } + }, + "env2": { + "value": 42, + "trace": { + "def": { + "environment": "access-root", + "begin": { + "line": 10, + "column": 9, + "byte": 117 + }, + "end": { + "line": 10, + "column": 44, + "byte": 152 + } + } + } + }, + "foo": { + "value": "hello!", + "trace": { + "def": { + "environment": "access-root", + "begin": { + "line": 5, + "column": 8, + "byte": 37 + }, + "end": { + "line": 5, + "column": 14, + "byte": 43 + } + } + } + }, + "imp": { + "value": { + "foo/bar": { + "value": { + "some_value": { + "value": 42, + "trace": { + "def": { + "environment": "foo/bar", + "begin": { + "line": 2, + "column": 15, + "byte": 22 + }, + "end": { + "line": 2, + "column": 17, + "byte": 24 + } + } + } + } + }, + "trace": { + "def": { + "environment": "access-root", + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + } + } + }, + "trace": { + "def": { + "environment": "access-root", + "begin": { + "line": 7, + "column": 8, + "byte": 54 + }, + "end": { + "line": 7, + "column": 19, + "byte": 65 + } + } + } + }, + "invalid": { + "unknown": true, + "trace": { + "def": { + "environment": "access-root", + "begin": { + "line": 13, + "column": 12, + "byte": 211 + }, + "end": { + "line": 13, + "column": 23, + "byte": 222 + } + } + } + }, + "some_value": { + "value": 42, + "trace": { + "def": { + "environment": "foo/bar", + "begin": { + "line": 2, + "column": 15, + "byte": 22 + }, + "end": { + "line": 2, + "column": 17, + "byte": 24 + } + } + } + }, + "values": { + "unknown": true, + "trace": { + "def": { + "environment": "access-root", + "begin": { + "line": 11, + "column": 11, + "byte": 163 + }, + "end": { + "line": 11, + "column": 21, + "byte": 173 + } + } + } + }, + "values2": { + "value": "hello!", + "trace": { + "def": { + "environment": "access-root", + "begin": { + "line": 12, + "column": 12, + "byte": 185 + }, + "end": { + "line": 12, + "column": 26, + "byte": 199 + } + } + } + } + }, + "schema": { + "properties": { + "ctx": { + "properties": { + "currentEnvironment": { + "properties": { + "name": { + "type": "string", + "const": "access-root" + } + }, + "type": "object", + "required": [ + "name" + ] + }, + "pulumi": { + "properties": { + "user": { + "properties": { + "id": { + "type": "string", + "const": "USER_123" + } + }, + "type": "object", + "required": [ + "id" + ] + } + }, + "type": "object", + "required": [ + "user" + ] + }, + "rootEnvironment": { + "properties": { + "name": { + "type": "string", + "const": "access-root" + } + }, + "type": "object", + "required": [ + "name" + ] + } + }, + "type": "object", + "required": [ + "currentEnvironment", + "pulumi", + "rootEnvironment" + ] + }, + "env": true, + "env2": { + "type": "number", + "const": 42 + }, + "foo": { + "type": "string", + "const": "hello!" + }, + "imp": { + "properties": { + "foo/bar": { + "properties": { + "some_value": { + "type": "number", + "const": 42 + } + }, + "type": "object", + "required": [ + "some_value" + ] + } + }, + "type": "object", + "required": [ + "foo/bar" + ] + }, + "invalid": true, + "some_value": { + "type": "number", + "const": 42 + }, + "values": true, + "values2": { + "type": "string", + "const": "hello!" + } + }, + "type": "object", + "required": [ + "ctx", + "env", + "env2", + "foo", + "imp", + "invalid", + "some_value", + "values", + "values2" + ] + }, + "executionContext": { + "properties": { + "currentEnvironment": { + "value": { + "name": { + "value": "access-root", + "trace": { + "def": { + "environment": "access-root", + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + } + } + }, + "trace": { + "def": { + "environment": "access-root", + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + } + }, + "pulumi": { + "value": { + "user": { + "value": { + "id": { + "value": "USER_123", + "trace": { + "def": { + "environment": "access-root", + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + } + } + }, + "trace": { + "def": { + "environment": "access-root", + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + } + } + }, + "trace": { + "def": { + "environment": "access-root", + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + } + }, + "rootEnvironment": { + "value": { + "name": { + "value": "access-root", + "trace": { + "def": { + "environment": "access-root", + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + } + } + }, + "trace": { + "def": { + "environment": "access-root", + "begin": { + "line": 0, + "column": 0, + "byte": 0 + }, + "end": { + "line": 0, + "column": 0, + "byte": 0 + } + } + } + } + }, + "schema": { + "properties": { + "currentEnvironment": { + "properties": { + "name": { + "type": "string", + "const": "access-root" + } + }, + "type": "object", + "required": [ + "name" + ] + }, + "pulumi": { + "properties": { + "user": { + "properties": { + "id": { + "type": "string", + "const": "USER_123" + } + }, + "type": "object", + "required": [ + "id" + ] + } + }, + "type": "object", + "required": [ + "user" + ] + }, + "rootEnvironment": { + "properties": { + "name": { + "type": "string", + "const": "access-root" + } + }, + "type": "object", + "required": [ + "name" + ] + } + }, + "type": "object", + "required": [ + "currentEnvironment", + "pulumi", + "rootEnvironment" + ] + } + } + }, + "evalJsonRedacted": { + "ctx": { + "currentEnvironment": { + "name": "access-root" + }, + "pulumi": { + "user": { + "id": "USER_123" + } + }, + "rootEnvironment": { + "name": "access-root" + } + }, + "env": "[unknown]", + "env2": 42, + "foo": "hello!", + "imp": { + "foo/bar": { + "some_value": 42 + } + }, + "invalid": "[unknown]", + "some_value": 42, + "values": "[unknown]", + "values2": "hello!" + }, + "evalJSONRevealed": { + "ctx": { + "currentEnvironment": { + "name": "access-root" + }, + "pulumi": { + "user": { + "id": "USER_123" + } + }, + "rootEnvironment": { + "name": "access-root" + } + }, + "env": "[unknown]", + "env2": 42, + "foo": "hello!", + "imp": { + "foo/bar": { + "some_value": 42 + } + }, + "invalid": "[unknown]", + "some_value": 42, + "values": "[unknown]", + "values2": "hello!" + } +} diff --git a/eval/testdata/eval/access-root/foo/bar.yaml b/eval/testdata/eval/access-root/foo/bar.yaml new file mode 100644 index 000000000..5ab415478 --- /dev/null +++ b/eval/testdata/eval/access-root/foo/bar.yaml @@ -0,0 +1,2 @@ +values: + some_value: 42 diff --git a/eval/testdata/eval/reserved-keys/env.yaml b/eval/testdata/eval/reserved-keys/env.yaml index 282c78324..97b1df1b0 100644 --- a/eval/testdata/eval/reserved-keys/env.yaml +++ b/eval/testdata/eval/reserved-keys/env.yaml @@ -1,3 +1,4 @@ values: imports: foo context: bar + environments: baz diff --git a/eval/testdata/eval/reserved-keys/expected.json b/eval/testdata/eval/reserved-keys/expected.json index 132e495f2..13b9a7c39 100644 --- a/eval/testdata/eval/reserved-keys/expected.json +++ b/eval/testdata/eval/reserved-keys/expected.json @@ -45,6 +45,29 @@ "EvalContext": null, "Extra": null, "Path": "values.context" + }, + { + "Severity": 1, + "Summary": "\"environments\" is a reserved key", + "Detail": "", + "Subject": { + "Filename": "reserved-keys", + "Start": { + "Line": 4, + "Column": 3, + "Byte": 40 + }, + "End": { + "Line": 4, + "Column": 15, + "Byte": 52 + } + }, + "Context": null, + "Expression": null, + "EvalContext": null, + "Extra": null, + "Path": "values.environments" } ], "check": { @@ -287,6 +310,29 @@ "EvalContext": null, "Extra": null, "Path": "values.context" + }, + { + "Severity": 1, + "Summary": "\"environments\" is a reserved key", + "Detail": "", + "Subject": { + "Filename": "reserved-keys", + "Start": { + "Line": 4, + "Column": 3, + "Byte": 40 + }, + "End": { + "Line": 4, + "Column": 15, + "Byte": 52 + } + }, + "Context": null, + "Expression": null, + "EvalContext": null, + "Extra": null, + "Path": "values.environments" } ], "eval": {