mirror of
https://github.com/traefik/traefik.git
synced 2025-05-05 15:33:01 +00:00
Ability to enable unsafe in yaegi through plugin manifest
This commit is contained in:
parent
a092c4f535
commit
8f37c8f0c5
@ -348,6 +348,9 @@ Environment variables to forward to the wasm guest.
|
|||||||
`--experimental.localplugins.<name>.settings.mounts`:
|
`--experimental.localplugins.<name>.settings.mounts`:
|
||||||
Directory to mount to the wasm guest.
|
Directory to mount to the wasm guest.
|
||||||
|
|
||||||
|
`--experimental.localplugins.<name>.settings.useunsafe`:
|
||||||
|
Allow the plugin to use unsafe package. (Default: ```false```)
|
||||||
|
|
||||||
`--experimental.otlplogs`:
|
`--experimental.otlplogs`:
|
||||||
Enables the OpenTelemetry logs integration. (Default: ```false```)
|
Enables the OpenTelemetry logs integration. (Default: ```false```)
|
||||||
|
|
||||||
@ -363,6 +366,9 @@ Environment variables to forward to the wasm guest.
|
|||||||
`--experimental.plugins.<name>.settings.mounts`:
|
`--experimental.plugins.<name>.settings.mounts`:
|
||||||
Directory to mount to the wasm guest.
|
Directory to mount to the wasm guest.
|
||||||
|
|
||||||
|
`--experimental.plugins.<name>.settings.useunsafe`:
|
||||||
|
Allow the plugin to use unsafe package. (Default: ```false```)
|
||||||
|
|
||||||
`--experimental.plugins.<name>.version`:
|
`--experimental.plugins.<name>.version`:
|
||||||
plugin's version.
|
plugin's version.
|
||||||
|
|
||||||
|
@ -348,6 +348,9 @@ Environment variables to forward to the wasm guest.
|
|||||||
`TRAEFIK_EXPERIMENTAL_LOCALPLUGINS_<NAME>_SETTINGS_MOUNTS`:
|
`TRAEFIK_EXPERIMENTAL_LOCALPLUGINS_<NAME>_SETTINGS_MOUNTS`:
|
||||||
Directory to mount to the wasm guest.
|
Directory to mount to the wasm guest.
|
||||||
|
|
||||||
|
`TRAEFIK_EXPERIMENTAL_LOCALPLUGINS_<NAME>_SETTINGS_USEUNSAFE`:
|
||||||
|
Allow the plugin to use unsafe package. (Default: ```false```)
|
||||||
|
|
||||||
`TRAEFIK_EXPERIMENTAL_OTLPLOGS`:
|
`TRAEFIK_EXPERIMENTAL_OTLPLOGS`:
|
||||||
Enables the OpenTelemetry logs integration. (Default: ```false```)
|
Enables the OpenTelemetry logs integration. (Default: ```false```)
|
||||||
|
|
||||||
@ -363,6 +366,9 @@ Environment variables to forward to the wasm guest.
|
|||||||
`TRAEFIK_EXPERIMENTAL_PLUGINS_<NAME>_SETTINGS_MOUNTS`:
|
`TRAEFIK_EXPERIMENTAL_PLUGINS_<NAME>_SETTINGS_MOUNTS`:
|
||||||
Directory to mount to the wasm guest.
|
Directory to mount to the wasm guest.
|
||||||
|
|
||||||
|
`TRAEFIK_EXPERIMENTAL_PLUGINS_<NAME>_SETTINGS_USEUNSAFE`:
|
||||||
|
Allow the plugin to use unsafe package. (Default: ```false```)
|
||||||
|
|
||||||
`TRAEFIK_EXPERIMENTAL_PLUGINS_<NAME>_VERSION`:
|
`TRAEFIK_EXPERIMENTAL_PLUGINS_<NAME>_VERSION`:
|
||||||
plugin's version.
|
plugin's version.
|
||||||
|
|
||||||
|
@ -575,23 +575,27 @@
|
|||||||
[experimental.plugins.Descriptor0.settings]
|
[experimental.plugins.Descriptor0.settings]
|
||||||
envs = ["foobar", "foobar"]
|
envs = ["foobar", "foobar"]
|
||||||
mounts = ["foobar", "foobar"]
|
mounts = ["foobar", "foobar"]
|
||||||
|
useUnsafe = true
|
||||||
[experimental.plugins.Descriptor1]
|
[experimental.plugins.Descriptor1]
|
||||||
moduleName = "foobar"
|
moduleName = "foobar"
|
||||||
version = "foobar"
|
version = "foobar"
|
||||||
[experimental.plugins.Descriptor1.settings]
|
[experimental.plugins.Descriptor1.settings]
|
||||||
envs = ["foobar", "foobar"]
|
envs = ["foobar", "foobar"]
|
||||||
mounts = ["foobar", "foobar"]
|
mounts = ["foobar", "foobar"]
|
||||||
|
useUnsafe = true
|
||||||
[experimental.localPlugins]
|
[experimental.localPlugins]
|
||||||
[experimental.localPlugins.LocalDescriptor0]
|
[experimental.localPlugins.LocalDescriptor0]
|
||||||
moduleName = "foobar"
|
moduleName = "foobar"
|
||||||
[experimental.localPlugins.LocalDescriptor0.settings]
|
[experimental.localPlugins.LocalDescriptor0.settings]
|
||||||
envs = ["foobar", "foobar"]
|
envs = ["foobar", "foobar"]
|
||||||
mounts = ["foobar", "foobar"]
|
mounts = ["foobar", "foobar"]
|
||||||
|
useUnsafe = true
|
||||||
[experimental.localPlugins.LocalDescriptor1]
|
[experimental.localPlugins.LocalDescriptor1]
|
||||||
moduleName = "foobar"
|
moduleName = "foobar"
|
||||||
[experimental.localPlugins.LocalDescriptor1.settings]
|
[experimental.localPlugins.LocalDescriptor1.settings]
|
||||||
envs = ["foobar", "foobar"]
|
envs = ["foobar", "foobar"]
|
||||||
mounts = ["foobar", "foobar"]
|
mounts = ["foobar", "foobar"]
|
||||||
|
useUnsafe = true
|
||||||
[experimental.fastProxy]
|
[experimental.fastProxy]
|
||||||
debug = true
|
debug = true
|
||||||
|
|
||||||
|
@ -628,6 +628,7 @@ experimental:
|
|||||||
mounts:
|
mounts:
|
||||||
- foobar
|
- foobar
|
||||||
- foobar
|
- foobar
|
||||||
|
useUnsafe: true
|
||||||
Descriptor1:
|
Descriptor1:
|
||||||
moduleName: foobar
|
moduleName: foobar
|
||||||
version: foobar
|
version: foobar
|
||||||
@ -638,6 +639,7 @@ experimental:
|
|||||||
mounts:
|
mounts:
|
||||||
- foobar
|
- foobar
|
||||||
- foobar
|
- foobar
|
||||||
|
useUnsafe: true
|
||||||
localPlugins:
|
localPlugins:
|
||||||
LocalDescriptor0:
|
LocalDescriptor0:
|
||||||
moduleName: foobar
|
moduleName: foobar
|
||||||
@ -648,6 +650,7 @@ experimental:
|
|||||||
mounts:
|
mounts:
|
||||||
- foobar
|
- foobar
|
||||||
- foobar
|
- foobar
|
||||||
|
useUnsafe: true
|
||||||
LocalDescriptor1:
|
LocalDescriptor1:
|
||||||
moduleName: foobar
|
moduleName: foobar
|
||||||
settings:
|
settings:
|
||||||
@ -657,6 +660,7 @@ experimental:
|
|||||||
mounts:
|
mounts:
|
||||||
- foobar
|
- foobar
|
||||||
- foobar
|
- foobar
|
||||||
|
useUnsafe: true
|
||||||
abortOnPluginFailure: true
|
abortOnPluginFailure: true
|
||||||
fastProxy:
|
fastProxy:
|
||||||
debug: true
|
debug: true
|
||||||
|
@ -60,7 +60,7 @@ func NewBuilder(client *Client, plugins map[string]Descriptor, localPlugins map[
|
|||||||
pb.middlewareBuilders[pName] = middleware
|
pb.middlewareBuilders[pName] = middleware
|
||||||
|
|
||||||
case typeProvider:
|
case typeProvider:
|
||||||
pBuilder, err := newProviderBuilder(logCtx, manifest, client.GoPath())
|
pBuilder, err := newProviderBuilder(logCtx, manifest, client.GoPath(), desc.Settings)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("%s: %w", desc.ModuleName, err)
|
return nil, fmt.Errorf("%s: %w", desc.ModuleName, err)
|
||||||
}
|
}
|
||||||
@ -95,7 +95,7 @@ func NewBuilder(client *Client, plugins map[string]Descriptor, localPlugins map[
|
|||||||
pb.middlewareBuilders[pName] = middleware
|
pb.middlewareBuilders[pName] = middleware
|
||||||
|
|
||||||
case typeProvider:
|
case typeProvider:
|
||||||
builder, err := newProviderBuilder(logCtx, manifest, localGoPath)
|
builder, err := newProviderBuilder(logCtx, manifest, localGoPath, desc.Settings)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("%s: %w", desc.ModuleName, err)
|
return nil, fmt.Errorf("%s: %w", desc.ModuleName, err)
|
||||||
}
|
}
|
||||||
@ -139,7 +139,7 @@ func newMiddlewareBuilder(ctx context.Context, goPath string, manifest *Manifest
|
|||||||
return newWasmMiddlewareBuilder(goPath, moduleName, wasmPath, settings)
|
return newWasmMiddlewareBuilder(goPath, moduleName, wasmPath, settings)
|
||||||
|
|
||||||
case runtimeYaegi, "":
|
case runtimeYaegi, "":
|
||||||
i, err := newInterpreter(ctx, goPath, manifest.Import)
|
i, err := newInterpreter(ctx, goPath, manifest, settings)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to create Yaegi interpreter: %w", err)
|
return nil, fmt.Errorf("failed to create Yaegi interpreter: %w", err)
|
||||||
}
|
}
|
||||||
@ -151,10 +151,10 @@ func newMiddlewareBuilder(ctx context.Context, goPath string, manifest *Manifest
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newProviderBuilder(ctx context.Context, manifest *Manifest, goPath string) (providerBuilder, error) {
|
func newProviderBuilder(ctx context.Context, manifest *Manifest, goPath string, settings Settings) (providerBuilder, error) {
|
||||||
switch manifest.Runtime {
|
switch manifest.Runtime {
|
||||||
case runtimeYaegi, "":
|
case runtimeYaegi, "":
|
||||||
i, err := newInterpreter(ctx, goPath, manifest.Import)
|
i, err := newInterpreter(ctx, goPath, manifest, settings)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return providerBuilder{}, err
|
return providerBuilder{}, err
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package plugins
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
@ -15,6 +16,7 @@ import (
|
|||||||
"github.com/traefik/traefik/v3/pkg/logs"
|
"github.com/traefik/traefik/v3/pkg/logs"
|
||||||
"github.com/traefik/yaegi/interp"
|
"github.com/traefik/yaegi/interp"
|
||||||
"github.com/traefik/yaegi/stdlib"
|
"github.com/traefik/yaegi/stdlib"
|
||||||
|
"github.com/traefik/yaegi/stdlib/unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
type yaegiMiddlewareBuilder struct {
|
type yaegiMiddlewareBuilder struct {
|
||||||
@ -119,7 +121,7 @@ func (m *YaegiMiddleware) NewHandler(ctx context.Context, next http.Handler) (ht
|
|||||||
return m.builder.newHandler(ctx, next, m.config, m.middlewareName)
|
return m.builder.newHandler(ctx, next, m.config, m.middlewareName)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newInterpreter(ctx context.Context, goPath string, manifestImport string) (*interp.Interpreter, error) {
|
func newInterpreter(ctx context.Context, goPath string, manifest *Manifest, settings Settings) (*interp.Interpreter, error) {
|
||||||
i := interp.New(interp.Options{
|
i := interp.New(interp.Options{
|
||||||
GoPath: goPath,
|
GoPath: goPath,
|
||||||
Env: os.Environ(),
|
Env: os.Environ(),
|
||||||
@ -132,14 +134,25 @@ func newInterpreter(ctx context.Context, goPath string, manifestImport string) (
|
|||||||
return nil, fmt.Errorf("failed to load symbols: %w", err)
|
return nil, fmt.Errorf("failed to load symbols: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if manifest.UseUnsafe && !settings.UseUnsafe {
|
||||||
|
return nil, errors.New("this plugin uses unsafe import. If you want to use it, you need to allow useUnsafe in the settings")
|
||||||
|
}
|
||||||
|
|
||||||
|
if settings.UseUnsafe && manifest.UseUnsafe {
|
||||||
|
err := i.Use(unsafe.Symbols)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to load unsafe symbols: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
err = i.Use(ppSymbols())
|
err = i.Use(ppSymbols())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to load provider symbols: %w", err)
|
return nil, fmt.Errorf("failed to load provider symbols: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = i.Eval(fmt.Sprintf(`import "%s"`, manifestImport))
|
_, err = i.Eval(fmt.Sprintf(`import "%s"`, manifest.Import))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to import plugin code %q: %w", manifestImport, err)
|
return nil, fmt.Errorf("failed to import plugin code %q: %w", manifest.Import, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return i, nil
|
return i, nil
|
||||||
|
@ -11,8 +11,9 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Settings struct {
|
type Settings struct {
|
||||||
Envs []string `description:"Environment variables to forward to the wasm guest." json:"envs,omitempty" toml:"envs,omitempty" yaml:"envs,omitempty"`
|
Envs []string `description:"Environment variables to forward to the wasm guest." json:"envs,omitempty" toml:"envs,omitempty" yaml:"envs,omitempty"`
|
||||||
Mounts []string `description:"Directory to mount to the wasm guest." json:"mounts,omitempty" toml:"mounts,omitempty" yaml:"mounts,omitempty"`
|
Mounts []string `description:"Directory to mount to the wasm guest." json:"mounts,omitempty" toml:"mounts,omitempty" yaml:"mounts,omitempty"`
|
||||||
|
UseUnsafe bool `description:"Allow the plugin to use unsafe package." json:"useUnsafe,omitempty" toml:"useUnsafe,omitempty" yaml:"useUnsafe,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Descriptor The static part of a plugin configuration.
|
// Descriptor The static part of a plugin configuration.
|
||||||
@ -46,6 +47,7 @@ type Manifest struct {
|
|||||||
BasePkg string `yaml:"basePkg"`
|
BasePkg string `yaml:"basePkg"`
|
||||||
Compatibility string `yaml:"compatibility"`
|
Compatibility string `yaml:"compatibility"`
|
||||||
Summary string `yaml:"summary"`
|
Summary string `yaml:"summary"`
|
||||||
|
UseUnsafe bool `yaml:"useUnsafe"`
|
||||||
TestData map[string]interface{} `yaml:"testData"`
|
TestData map[string]interface{} `yaml:"testData"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user