mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-24 08:36:46 +00:00
Cel HTTP Lib (#12241)
* Implement HTTP CEL lib for external API calls Signed-off-by: Frank Jogeleit <frank.jogeleit@web.de> * fix lint errors Signed-off-by: Frank Jogeleit <frank.jogeleit@web.de> --------- Signed-off-by: Frank Jogeleit <frank.jogeleit@web.de>
This commit is contained in:
parent
1cc5b7a3ab
commit
da1fbd9475
5 changed files with 483 additions and 1 deletions
111
pkg/cel/libs/http/http.go
Normal file
111
pkg/cel/libs/http/http.go
Normal file
|
@ -0,0 +1,111 @@
|
|||
package http
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/kyverno/kyverno/pkg/tracing"
|
||||
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
|
||||
)
|
||||
|
||||
type HttpInterface interface {
|
||||
Get(url string, headers map[string]string) (map[string]any, error)
|
||||
Post(url string, data map[string]any, headers map[string]string) (map[string]any, error)
|
||||
Client(caBundle string) (HttpInterface, error)
|
||||
}
|
||||
|
||||
type ClientInterface interface {
|
||||
Do(*http.Request) (*http.Response, error)
|
||||
}
|
||||
|
||||
type HTTP struct {
|
||||
HttpInterface
|
||||
}
|
||||
|
||||
type HttpProvider struct {
|
||||
client ClientInterface
|
||||
}
|
||||
|
||||
func (r *HttpProvider) Get(url string, headers map[string]string) (map[string]any, error) {
|
||||
req, err := http.NewRequestWithContext(context.TODO(), "GET", url, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create request: %v", err)
|
||||
}
|
||||
for h, v := range headers {
|
||||
req.Header.Add(h, v)
|
||||
}
|
||||
return r.executeRequest(r.client, req)
|
||||
}
|
||||
|
||||
func (r *HttpProvider) Post(url string, data map[string]any, headers map[string]string) (map[string]any, error) {
|
||||
body, err := buildRequestData(data)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to encode request data: %v", err)
|
||||
}
|
||||
|
||||
req, err := http.NewRequestWithContext(context.TODO(), "POST", url, body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create request: %v", err)
|
||||
}
|
||||
for h, v := range headers {
|
||||
req.Header.Add(h, v)
|
||||
}
|
||||
return r.executeRequest(r.client, req)
|
||||
}
|
||||
|
||||
func (r *HttpProvider) executeRequest(client ClientInterface, req *http.Request) (map[string]any, error) {
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("request failed: %v", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
|
||||
return nil, fmt.Errorf("HTTP %s", resp.Status)
|
||||
}
|
||||
|
||||
body := make(map[string]any)
|
||||
|
||||
if err := json.NewDecoder(resp.Body).Decode(&body); err != nil {
|
||||
return nil, fmt.Errorf("Unable to decode JSON body %v", err)
|
||||
}
|
||||
|
||||
return body, nil
|
||||
}
|
||||
|
||||
func (r *HttpProvider) Client(caBundle string) (HttpInterface, error) {
|
||||
if caBundle == "" {
|
||||
return r, nil
|
||||
}
|
||||
|
||||
caCertPool := x509.NewCertPool()
|
||||
if ok := caCertPool.AppendCertsFromPEM([]byte(caBundle)); !ok {
|
||||
return nil, fmt.Errorf("failed to parse PEM CA bundle for APICall")
|
||||
}
|
||||
transport := &http.Transport{
|
||||
TLSClientConfig: &tls.Config{
|
||||
RootCAs: caCertPool,
|
||||
MinVersion: tls.VersionTLS12,
|
||||
},
|
||||
}
|
||||
return &HttpProvider{
|
||||
client: &http.Client{
|
||||
Transport: tracing.Transport(transport, otelhttp.WithFilter(tracing.RequestFilterIsInSpan)),
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func buildRequestData(data map[string]any) (io.Reader, error) {
|
||||
buffer := new(bytes.Buffer)
|
||||
if err := json.NewEncoder(buffer).Encode(data); err != nil {
|
||||
return nil, fmt.Errorf("failed to encode HTTP POST data %v: %w", data, err)
|
||||
}
|
||||
|
||||
return buffer, nil
|
||||
}
|
84
pkg/cel/libs/http/impl.go
Normal file
84
pkg/cel/libs/http/impl.go
Normal file
|
@ -0,0 +1,84 @@
|
|||
package http
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/google/cel-go/common/types"
|
||||
"github.com/google/cel-go/common/types/ref"
|
||||
"github.com/kyverno/kyverno/pkg/cel/utils"
|
||||
)
|
||||
|
||||
type impl struct {
|
||||
types.Adapter
|
||||
}
|
||||
|
||||
func (c *impl) get_request_with_client_string(args ...ref.Val) ref.Val {
|
||||
if request, err := utils.ConvertToNative[HTTP](args[0]); err != nil {
|
||||
return types.WrapErr(err)
|
||||
} else if url, err := utils.ConvertToNative[string](args[1]); err != nil {
|
||||
return types.WrapErr(err)
|
||||
} else if header, err := utils.ConvertToNative[map[string]string](args[2]); err != nil {
|
||||
return types.WrapErr(err)
|
||||
} else {
|
||||
data, err := request.Get(url, header)
|
||||
if err != nil {
|
||||
return types.NewErr("request failed: %v", err)
|
||||
}
|
||||
|
||||
return c.NativeToValue(data)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *impl) get_request_string(request, url ref.Val) ref.Val {
|
||||
return c.get_request_with_client_string(request, url, c.NativeToValue(make(map[string]string, 0)))
|
||||
}
|
||||
|
||||
func (c *impl) get_request_with_headers_string(args ...ref.Val) ref.Val {
|
||||
return c.get_request_with_client_string(args...)
|
||||
}
|
||||
|
||||
func (c *impl) post_request_string_with_client(args ...ref.Val) ref.Val {
|
||||
if request, err := utils.ConvertToNative[HTTP](args[0]); err != nil {
|
||||
return types.WrapErr(err)
|
||||
} else if url, err := utils.ConvertToNative[string](args[1]); err != nil {
|
||||
return types.WrapErr(err)
|
||||
} else if data, err := utils.ConvertToNative[map[string]any](args[2]); err != nil {
|
||||
return types.WrapErr(err)
|
||||
} else if header, err := utils.ConvertToNative[map[string]string](args[3]); err != nil {
|
||||
return types.WrapErr(err)
|
||||
} else {
|
||||
data, err := request.Post(url, data, header)
|
||||
if err != nil {
|
||||
return types.NewErr("request failed: %v", err)
|
||||
}
|
||||
|
||||
return c.NativeToValue(data)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *impl) http_client_string(request, caBundle ref.Val) ref.Val {
|
||||
fmt.Println("http_client_string")
|
||||
if request, err := utils.ConvertToNative[HTTP](request); err != nil {
|
||||
fmt.Println("conv request")
|
||||
return types.WrapErr(err)
|
||||
} else if caBundle, err := utils.ConvertToNative[string](caBundle); err != nil {
|
||||
fmt.Println("conv ca bundle")
|
||||
return types.WrapErr(err)
|
||||
} else {
|
||||
fmt.Println("call client")
|
||||
caRequest, err := request.Client(caBundle)
|
||||
if err != nil {
|
||||
return types.NewErr("request failed: %v", err)
|
||||
}
|
||||
|
||||
return c.NativeToValue(caRequest)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *impl) post_request_string(args ...ref.Val) ref.Val {
|
||||
return c.post_request_string_with_client(args[0], args[1], args[2], c.NativeToValue(make(map[string]string, 0)))
|
||||
}
|
||||
|
||||
func (c *impl) post_request_with_headers_string(args ...ref.Val) ref.Val {
|
||||
return c.post_request_string_with_client(args...)
|
||||
}
|
215
pkg/cel/libs/http/impl_test.go
Normal file
215
pkg/cel/libs/http/impl_test.go
Normal file
|
@ -0,0 +1,215 @@
|
|||
package http
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/google/cel-go/cel"
|
||||
"github.com/google/cel-go/common/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
var pemExample = `-----BEGIN CERTIFICATE-----
|
||||
MIICMzCCAZygAwIBAgIJALiPnVsvq8dsMA0GCSqGSIb3DQEBBQUAMFMxCzAJBgNV
|
||||
BAYTAlVTMQwwCgYDVQQIEwNmb28xDDAKBgNVBAcTA2ZvbzEMMAoGA1UEChMDZm9v
|
||||
MQwwCgYDVQQLEwNmb28xDDAKBgNVBAMTA2ZvbzAeFw0xMzAzMTkxNTQwMTlaFw0x
|
||||
ODAzMTgxNTQwMTlaMFMxCzAJBgNVBAYTAlVTMQwwCgYDVQQIEwNmb28xDDAKBgNV
|
||||
BAcTA2ZvbzEMMAoGA1UEChMDZm9vMQwwCgYDVQQLEwNmb28xDDAKBgNVBAMTA2Zv
|
||||
bzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAzdGfxi9CNbMf1UUcvDQh7MYB
|
||||
OveIHyc0E0KIbhjK5FkCBU4CiZrbfHagaW7ZEcN0tt3EvpbOMxxc/ZQU2WN/s/wP
|
||||
xph0pSfsfFsTKM4RhTWD2v4fgk+xZiKd1p0+L4hTtpwnEw0uXRVd0ki6muwV5y/P
|
||||
+5FHUeldq+pgTcgzuK8CAwEAAaMPMA0wCwYDVR0PBAQDAgLkMA0GCSqGSIb3DQEB
|
||||
BQUAA4GBAJiDAAtY0mQQeuxWdzLRzXmjvdSuL9GoyT3BF/jSnpxz5/58dba8pWen
|
||||
v3pj4P3w5DoOso0rzkZy2jEsEitlVM2mLSbQpMM+MUVQCQoiG6W9xuCFuxSrwPIS
|
||||
pAqEAuV4DNoxQKKWmhVv+J0ptMWD25Pnpxeq5sXzghfJnslJlQND
|
||||
-----END CERTIFICATE-----`
|
||||
|
||||
type testClient struct {
|
||||
doFunc func(req *http.Request) (*http.Response, error)
|
||||
}
|
||||
|
||||
func (t testClient) Do(req *http.Request) (*http.Response, error) {
|
||||
return t.doFunc(req)
|
||||
}
|
||||
|
||||
func Test_impl_get_request(t *testing.T) {
|
||||
opts := Lib()
|
||||
base, err := cel.NewEnv(opts)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, base)
|
||||
options := []cel.EnvOption{
|
||||
cel.Variable("http", HTTPType),
|
||||
}
|
||||
env, err := base.Extend(options...)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, env)
|
||||
ast, issues := env.Compile(`http.Get("http://localhost:8080")`)
|
||||
fmt.Println(issues.String())
|
||||
assert.Nil(t, issues)
|
||||
assert.NotNil(t, ast)
|
||||
prog, err := env.Program(ast)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, prog)
|
||||
out, _, err := prog.Eval(map[string]any{
|
||||
"http": HTTP{&HttpProvider{
|
||||
client: testClient{
|
||||
doFunc: func(req *http.Request) (*http.Response, error) {
|
||||
assert.Equal(t, req.URL.String(), "http://localhost:8080")
|
||||
assert.Equal(t, req.Method, "GET")
|
||||
|
||||
return &http.Response{StatusCode: http.StatusOK, Body: io.NopCloser(strings.NewReader(`{"body": "ok"}`))}, nil
|
||||
},
|
||||
},
|
||||
}},
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
body := out.Value().(map[string]any)
|
||||
assert.Equal(t, body["body"], "ok")
|
||||
}
|
||||
|
||||
func Test_impl_get_request_with_headers(t *testing.T) {
|
||||
opts := Lib()
|
||||
base, err := cel.NewEnv(opts)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, base)
|
||||
options := []cel.EnvOption{
|
||||
cel.Variable("http", HTTPType),
|
||||
}
|
||||
env, err := base.Extend(options...)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, env)
|
||||
ast, issues := env.Compile(`http.Get("http://localhost:8080", {"Authorization": "Bearer token"})`)
|
||||
fmt.Println(issues.String())
|
||||
assert.Nil(t, issues)
|
||||
assert.NotNil(t, ast)
|
||||
prog, err := env.Program(ast)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, prog)
|
||||
out, _, err := prog.Eval(map[string]any{
|
||||
"http": HTTP{&HttpProvider{
|
||||
client: testClient{
|
||||
doFunc: func(req *http.Request) (*http.Response, error) {
|
||||
assert.Equal(t, req.URL.String(), "http://localhost:8080")
|
||||
assert.Equal(t, req.Method, "GET")
|
||||
assert.Equal(t, req.Header.Get("Authorization"), "Bearer token")
|
||||
|
||||
return &http.Response{StatusCode: http.StatusOK, Body: io.NopCloser(strings.NewReader(`{"body": "ok"}`))}, nil
|
||||
},
|
||||
},
|
||||
}},
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
body := out.Value().(map[string]any)
|
||||
assert.Equal(t, body["body"], "ok")
|
||||
}
|
||||
|
||||
func Test_impl_post_request(t *testing.T) {
|
||||
opts := Lib()
|
||||
base, err := cel.NewEnv(opts)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, base)
|
||||
options := []cel.EnvOption{
|
||||
cel.Variable("http", HTTPType),
|
||||
}
|
||||
env, err := base.Extend(options...)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, env)
|
||||
ast, issues := env.Compile(`http.Post("http://localhost:8080", {"key": "value"})`)
|
||||
fmt.Println(issues.String())
|
||||
assert.Nil(t, issues)
|
||||
assert.NotNil(t, ast)
|
||||
prog, err := env.Program(ast)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, prog)
|
||||
out, _, err := prog.Eval(map[string]any{
|
||||
"http": HTTP{&HttpProvider{
|
||||
client: testClient{
|
||||
doFunc: func(req *http.Request) (*http.Response, error) {
|
||||
assert.Equal(t, req.URL.String(), "http://localhost:8080")
|
||||
assert.Equal(t, req.Method, "POST")
|
||||
|
||||
data := make(map[string]string, 0)
|
||||
json.NewDecoder(req.Body).Decode(&data)
|
||||
assert.Equal(t, data["key"], "value")
|
||||
|
||||
return &http.Response{StatusCode: http.StatusOK, Body: io.NopCloser(strings.NewReader(`{"body": "ok"}`))}, nil
|
||||
},
|
||||
},
|
||||
}},
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
body := out.Value().(map[string]any)
|
||||
assert.Equal(t, body["body"], "ok")
|
||||
}
|
||||
|
||||
func Test_impl_post_request_with_headers(t *testing.T) {
|
||||
opts := Lib()
|
||||
base, err := cel.NewEnv(opts)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, base)
|
||||
options := []cel.EnvOption{
|
||||
cel.Variable("http", HTTPType),
|
||||
}
|
||||
env, err := base.Extend(options...)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, env)
|
||||
ast, issues := env.Compile(`http.Post("http://localhost:8080", {"key": "value"}, {"Authorization": "Bearer token"})`)
|
||||
fmt.Println(issues.String())
|
||||
assert.Nil(t, issues)
|
||||
assert.NotNil(t, ast)
|
||||
prog, err := env.Program(ast)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, prog)
|
||||
out, _, err := prog.Eval(map[string]any{
|
||||
"http": HTTP{&HttpProvider{
|
||||
client: testClient{
|
||||
doFunc: func(req *http.Request) (*http.Response, error) {
|
||||
assert.Equal(t, req.URL.String(), "http://localhost:8080")
|
||||
assert.Equal(t, req.Method, "POST")
|
||||
assert.Equal(t, req.Header.Get("Authorization"), "Bearer token")
|
||||
|
||||
data := make(map[string]string, 0)
|
||||
json.NewDecoder(req.Body).Decode(&data)
|
||||
assert.Equal(t, data["key"], "value")
|
||||
|
||||
return &http.Response{StatusCode: http.StatusOK, Body: io.NopCloser(strings.NewReader(`{"body": "ok"}`))}, nil
|
||||
},
|
||||
},
|
||||
}},
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
body := out.Value().(map[string]any)
|
||||
assert.Equal(t, body["body"], "ok")
|
||||
}
|
||||
|
||||
func Test_impl_http_client_string(t *testing.T) {
|
||||
opts := Lib()
|
||||
base, err := cel.NewEnv(opts)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, base)
|
||||
options := []cel.EnvOption{
|
||||
cel.Variable("pem", types.StringType),
|
||||
cel.Variable("http", HTTPType),
|
||||
}
|
||||
env, err := base.Extend(options...)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, env)
|
||||
ast, issues := env.Compile(`http.Client(pem)`)
|
||||
fmt.Println(issues.String())
|
||||
assert.Nil(t, issues)
|
||||
assert.NotNil(t, ast)
|
||||
prog, err := env.Program(ast)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, prog)
|
||||
out, _, err := prog.Eval(map[string]any{
|
||||
"pem": pemExample,
|
||||
"http": HTTP{&HttpProvider{}},
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
reqProvider := out.Value().(*HttpProvider)
|
||||
assert.NotNil(t, reqProvider)
|
||||
}
|
69
pkg/cel/libs/http/lib.go
Normal file
69
pkg/cel/libs/http/lib.go
Normal file
|
@ -0,0 +1,69 @@
|
|||
package http
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"reflect"
|
||||
|
||||
"github.com/google/cel-go/cel"
|
||||
"github.com/google/cel-go/common/types"
|
||||
"github.com/google/cel-go/ext"
|
||||
apiservercel "k8s.io/apiserver/pkg/cel"
|
||||
)
|
||||
|
||||
const libraryName = "kyverno.http"
|
||||
|
||||
var HTTPType = types.DynType
|
||||
|
||||
type lib struct{}
|
||||
|
||||
func Lib() cel.EnvOption {
|
||||
// create the cel lib env option
|
||||
return cel.Lib(&lib{})
|
||||
}
|
||||
|
||||
func Types() []*apiservercel.DeclType {
|
||||
return []*apiservercel.DeclType{}
|
||||
}
|
||||
|
||||
func (*lib) LibraryName() string {
|
||||
return libraryName
|
||||
}
|
||||
|
||||
func (c *lib) CompileOptions() []cel.EnvOption {
|
||||
return []cel.EnvOption{
|
||||
ext.NativeTypes(reflect.TypeFor[http.Request]()),
|
||||
c.extendEnv,
|
||||
}
|
||||
}
|
||||
|
||||
func (*lib) ProgramOptions() []cel.ProgramOption {
|
||||
return []cel.ProgramOption{}
|
||||
}
|
||||
|
||||
func (c *lib) extendEnv(env *cel.Env) (*cel.Env, error) {
|
||||
// create implementation, recording the envoy types aware adapter
|
||||
impl := impl{
|
||||
Adapter: env.CELTypeAdapter(),
|
||||
}
|
||||
// build our function overloads
|
||||
libraryDecls := map[string][]cel.FunctionOpt{
|
||||
"Get": {
|
||||
cel.MemberOverload("get_request_string", []*cel.Type{HTTPType, types.StringType}, types.NewMapType(types.StringType, types.AnyType), cel.BinaryBinding(impl.get_request_string)),
|
||||
cel.MemberOverload("get_request_with_headers_string", []*cel.Type{HTTPType, types.StringType, types.NewMapType(types.StringType, types.StringType)}, types.NewMapType(types.StringType, types.AnyType), cel.FunctionBinding(impl.get_request_with_headers_string)),
|
||||
},
|
||||
"Post": {
|
||||
cel.MemberOverload("post_request_string", []*cel.Type{HTTPType, types.StringType, types.NewMapType(types.StringType, types.AnyType)}, types.NewMapType(types.StringType, types.AnyType), cel.FunctionBinding(impl.post_request_string)),
|
||||
cel.MemberOverload("post_request__with_headers_string", []*cel.Type{HTTPType, types.StringType, types.NewMapType(types.StringType, types.AnyType), types.NewMapType(types.StringType, types.StringType)}, types.NewMapType(types.StringType, types.AnyType), cel.FunctionBinding(impl.post_request_with_headers_string)),
|
||||
},
|
||||
"Client": {
|
||||
cel.MemberOverload("http_client_string", []*cel.Type{HTTPType, types.StringType}, HTTPType, cel.BinaryBinding(impl.http_client_string)),
|
||||
},
|
||||
}
|
||||
// create env options corresponding to our function overloads
|
||||
options := []cel.EnvOption{}
|
||||
for name, overloads := range libraryDecls {
|
||||
options = append(options, cel.Function(name, overloads...))
|
||||
}
|
||||
// extend environment with our function overloads
|
||||
return env.Extend(options...)
|
||||
}
|
|
@ -9,6 +9,7 @@ import (
|
|||
engine "github.com/kyverno/kyverno/pkg/cel"
|
||||
vpolautogen "github.com/kyverno/kyverno/pkg/cel/autogen"
|
||||
"github.com/kyverno/kyverno/pkg/cel/libs/context"
|
||||
"github.com/kyverno/kyverno/pkg/cel/libs/http"
|
||||
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
apiservercel "k8s.io/apiserver/pkg/cel"
|
||||
|
@ -16,6 +17,7 @@ import (
|
|||
|
||||
const (
|
||||
ContextKey = "context"
|
||||
HttpKey = "http"
|
||||
NamespaceObjectKey = "namespaceObject"
|
||||
ObjectKey = "object"
|
||||
OldObjectKey = "oldObject"
|
||||
|
@ -108,6 +110,7 @@ func (c *compiler) compileForKubernetes(policy *policiesv1alpha1.ValidatingPolic
|
|||
declTypes = append(declTypes, context.Types()...)
|
||||
options := []cel.EnvOption{
|
||||
cel.Variable(ContextKey, context.ContextType),
|
||||
cel.Variable(HttpKey, http.HTTPType),
|
||||
cel.Variable(NamespaceObjectKey, NamespaceType.CelType()),
|
||||
cel.Variable(ObjectKey, cel.DynType),
|
||||
cel.Variable(OldObjectKey, cel.DynType),
|
||||
|
@ -125,7 +128,7 @@ func (c *compiler) compileForKubernetes(policy *policiesv1alpha1.ValidatingPolic
|
|||
panic(err)
|
||||
}
|
||||
options = append(options, declOptions...)
|
||||
options = append(options, context.Lib())
|
||||
options = append(options, context.Lib(), http.Lib())
|
||||
// TODO: params, authorizer, authorizer.requestResource ?
|
||||
env, err := base.Extend(options...)
|
||||
if err != nil {
|
||||
|
|
Loading…
Add table
Reference in a new issue