Documentation
¶
Index ¶
- Constants
- Variables
- func CapabilityList() []string
- func CapabilityRisk(cap string) (string, bool)
- func DigestSHA256(artifact []byte) string
- func SigningPayload(m Manifest) []byte
- func ValidateManifest(m Manifest) error
- func VerifyManifest(m Manifest, artifact []byte, policy TrustPolicy) error
- type Broker
- func (b *Broker) CanExposeRPC() bool
- func (b *Broker) HTTPDo(ctx context.Context, req HostHTTPRequest) (HostHTTPResponse, error)
- func (b *Broker) HasCapability(cap string) bool
- func (b *Broker) KVGet(ctx context.Context, key string) ([]byte, bool, error)
- func (b *Broker) KVPut(ctx context.Context, key string, value []byte) error
- func (b *Broker) Log(ctx context.Context, level, message string, fields map[string]string) error
- func (b *Broker) Notify(ctx context.Context, title, body string) error
- func (b *Broker) PluginID() string
- func (b *Broker) RPCCall(ctx context.Context, service, method string, request []byte) ([]byte, error)
- type CapabilityError
- type HTTPHost
- type HostAudit
- type HostCallEvent
- type HostHTTPRequest
- type HostHTTPResponse
- type HostLogEntry
- type HostServices
- type InterfaceContract
- type InvokeRequest
- type InvokeResponse
- type Invoker
- type KVHost
- type LoadOutcome
- type Loaded
- type Loader
- type LogHost
- type Manifest
- type ManifestUI
- type NavContribution
- type NotifyHost
- type RPCHandler
- type RPCHost
- type RPCRegistry
- func (r *RPCRegistry) Allow(callerPluginID, service string)
- func (r *RPCRegistry) Call(ctx context.Context, caller, service, method string, request []byte) ([]byte, error)
- func (r *RPCRegistry) CallOperator(ctx context.Context, service, method string, request []byte) ([]byte, error)
- func (r *RPCRegistry) Register(ownerPluginID, service, version string, methods []string, handler RPCHandler) error
- func (r *RPCRegistry) Revoke(callerPluginID, service string)
- func (r *RPCRegistry) Services() []RPCServiceDescriptor
- func (r *RPCRegistry) Unregister(service string)
- type RPCServiceDescriptor
- type Runner
- type RunnerStartRequest
- type RunnerStartResult
- type RunnerStopRequest
- type RuntimeManager
- func (m *RuntimeManager) Invoke(ctx context.Context, pluginID, action string, payload json.RawMessage) (InvokeResponse, error)
- func (m *RuntimeManager) IsArmed(pluginID string) bool
- func (m *RuntimeManager) Snapshot() map[string]RuntimeStatus
- func (m *RuntimeManager) Start(ctx context.Context, loaded Loaded) (RuntimeStatus, error)
- func (m *RuntimeManager) Status(pluginID string) (RuntimeStatus, bool)
- func (m *RuntimeManager) Stop(pluginID, message string) (RuntimeStatus, error)
- type RuntimeManagerOptions
- type RuntimeStatus
- type SystemRunner
- func (r *SystemRunner) Invoke(ctx context.Context, req InvokeRequest) (InvokeResponse, error)
- func (r *SystemRunner) Name() string
- func (r *SystemRunner) Start(ctx context.Context, req RunnerStartRequest) (RunnerStartResult, error)
- func (r *SystemRunner) Stop(ctx context.Context, req RunnerStopRequest) error
- type SystemRunnerOptions
- type TrustPolicy
- type ViewAction
- type ViewColumn
- type ViewContribution
- type ViewFormField
- type ViewSource
Constants ¶
const ( TypeSystem = "system" TypeWasm = "wasm" TypeWorker = "worker" RiskRead = "read" RiskWrite = "write" RiskHost = "host" )
const ( RuntimeStateArmed = "armed" RuntimeStateStopped = "stopped" RuntimeStateFailed = "failed" )
Variables ¶
var ( // ErrCapabilityDenied is returned when a plugin calls a host API without // declaring the matching capability in its verified manifest. ErrCapabilityDenied = errors.New("plugin capability denied") // the server did not wire the corresponding host service into the broker. ErrHostServiceUnavailable = errors.New("plugin host service unavailable") )
var ( // ErrRPCNoService is returned when no plugin has registered the target service. ErrRPCNoService = errors.New("rpc service not found") // ErrRPCNoMethod is returned when the target service does not expose the method. ErrRPCNoMethod = errors.New("rpc method not found") // ErrRPCDenied is returned when the caller is not on the service's directed // allow-list (and is not the service owner). Distinct from "not found" so the // broker can record it as a security deny event. ErrRPCDenied = errors.New("rpc call denied") // ErrRPCInvalid is returned for a malformed service registration. ErrRPCInvalid = errors.New("invalid rpc registration") )
Inter-plugin RPC (design-09 §F). The registry is the server-owned bus that makes one first-party plugin's logic callable from another without exposing raw handles: a plugin with rpc:expose registers a service; a plugin with rpc:call invokes it through the broker. Every call is capability-gated at the broker, authorized here by a directed caller->callee allow-list, and audited.
var ErrCircuitOpen = errors.New("plugin circuit breaker open")
ErrCircuitOpen is returned once a plugin has failed CrashThreshold times in a row. The operator must disable+re-enable (restart) the plugin to reset it; a flapping plugin cannot keep consuming resources.
Functions ¶
func CapabilityList ¶
func CapabilityList() []string
func CapabilityRisk ¶ added in v0.2.0
func DigestSHA256 ¶ added in v0.2.0
func SigningPayload ¶ added in v0.2.0
func ValidateManifest ¶
func VerifyManifest ¶ added in v0.2.0
func VerifyManifest(m Manifest, artifact []byte, policy TrustPolicy) error
Types ¶
type Broker ¶ added in v0.2.0
type Broker struct {
// contains filtered or unexported fields
}
Broker is the capability-scoped facade a verified plugin uses to call back into server-owned host services.
func NewBroker ¶ added in v0.2.0
func NewBroker(loaded Loaded, services HostServices) (*Broker, error)
NewBroker binds a verified plugin registry entry to server-owned host services.
func (*Broker) CanExposeRPC ¶ added in v0.2.0
CanExposeRPC reports whether the verified plugin declared rpc:expose, i.e. may register a callable service in the inter-plugin RPC registry. The server checks this before registering a plugin's handlers (design-09 §F).
func (*Broker) HTTPDo ¶ added in v0.2.0
func (b *Broker) HTTPDo(ctx context.Context, req HostHTTPRequest) (HostHTTPResponse, error)
HTTPDo performs guarded outbound HTTP and requires http:egress. The broker itself runs the SSRF/egress guard on req.URL BEFORE delegating to the HTTPHost, so egress filtering is structural at this boundary and every HTTPHost (including future ones) is guarded regardless of its own behavior.
func (*Broker) HasCapability ¶ added in v0.2.0
HasCapability reports whether the verified plugin declared cap.
func (*Broker) KVGet ¶ added in v0.2.0
KVGet reads a KV value and requires kv:read. The plugin-supplied key names only the entry within the plugin's own namespace; the broker pins the bucket so a plugin can never read another plugin's or the operator's keys.
func (*Broker) KVPut ¶ added in v0.2.0
KVPut writes a KV value and requires kv:write. As with KVGet, the bucket is fixed to the plugin's own namespace; the plugin only chooses the entry key.
func (*Broker) Log ¶ added in v0.2.0
Log writes a plugin-authored log entry and requires log:write. The plugin controls the level/message/fields, so the broker bounds them before they reach the sink: the level is mapped to a known set, an oversize message is truncated, and the field count is capped. This prevents a plugin from flooding or poisoning the operator log through unbounded input.
func (*Broker) Notify ¶ added in v0.2.0
Notify sends an operator notification and requires notify:send.
func (*Broker) PluginID ¶ added in v0.2.0
PluginID returns the verified plugin id attached to this broker.
func (*Broker) RPCCall ¶ added in v0.2.0
func (b *Broker) RPCCall(ctx context.Context, service, method string, request []byte) ([]byte, error)
RPCCall invokes method on another plugin's exposed service and requires rpc:call. The broker stamps the VERIFIED caller id (b.pluginID) so the registry can authorize the directed edge; a plugin cannot impersonate another caller. Registry-level denials (ErrRPCDenied) are additionally recorded as a deny event for audit visibility (the capability check itself already recorded an allow). Service/method-not-found are client errors, not security denials, so they are returned without an extra deny event.
type CapabilityError ¶ added in v0.2.0
CapabilityError describes the exact capability a plugin lacked.
func (*CapabilityError) Error ¶ added in v0.2.0
func (e *CapabilityError) Error() string
func (*CapabilityError) Unwrap ¶ added in v0.2.0
func (e *CapabilityError) Unwrap() error
type HTTPHost ¶ added in v0.2.0
type HTTPHost interface {
Do(ctx context.Context, req HostHTTPRequest) (HostHTTPResponse, error)
}
HTTPHost performs guarded outbound HTTP. Implementations must enforce the server's SSRF/egress policy before dialing.
type HostAudit ¶ added in v0.2.0
type HostAudit interface {
RecordHostCall(ctx context.Context, event HostCallEvent)
}
HostAudit records broker allow/deny decisions for host API calls.
type HostCallEvent ¶ added in v0.2.0
type HostCallEvent struct {
PluginID string
Action string
Capability string
Decision string
Reason string
}
HostCallEvent records one broker authorization decision.
type HostHTTPRequest ¶ added in v0.2.0
HostHTTPRequest is the broker's stable outbound HTTP request shape.
type HostHTTPResponse ¶ added in v0.2.0
HostHTTPResponse is the broker's stable outbound HTTP response shape.
type HostLogEntry ¶ added in v0.2.0
HostLogEntry is a plugin-authored structured log entry.
type HostServices ¶ added in v0.2.0
type HostServices struct {
KV KVHost
Notify NotifyHost
HTTP HTTPHost
Log LogHost
Audit HostAudit
// RPC dispatches inter-plugin calls (design-09 §F). When nil, a plugin with
// rpc:call gets ErrHostServiceUnavailable rather than a panic.
RPC RPCHost
// GuardURL, when set, validates an outbound HTTP target's URL/host BEFORE the
// broker delegates to HTTP.Do. It makes SSRF/egress guarding structural at the
// broker boundary rather than relying on every HTTPHost implementation to
// remember to guard. A non-nil error rejects the request before any dial. When
// nil, the broker falls back to a built-in guard (see defaultGuardURL) so an
// HTTPHost is never trusted by convention alone.
GuardURL func(url string) error
}
HostServices are the real server-owned handles exposed through the broker. The broker keeps these handles behind per-call capability checks.
type InterfaceContract ¶ added in v0.2.0
type InterfaceContract struct {
Service string `json:"service"`
Methods []string `json:"methods"`
Scopes []string `json:"scopes,omitempty"`
}
InterfaceContract declares an interface the plugin exposes (service + methods), callable through the dashboard->plugin gateway under the given scopes.
type InvokeRequest ¶ added in v0.2.0
type InvokeRequest struct {
PluginID string
Action string
Payload json.RawMessage
}
InvokeRequest asks an armed plugin to perform one action. Payload is the raw JSON body handed to the plugin; the runner frames {action,payload} as a single stdin line and reads the reply from stdout.
type InvokeResponse ¶ added in v0.2.0
type InvokeResponse struct {
OK bool
Message string
Result json.RawMessage
}
InvokeResponse is the decoded plugin reply. Result carries the plugin's body (e.g. a rendered plan) for the host to act on under its own privileges.
type Invoker ¶ added in v0.2.0
type Invoker interface {
Invoke(ctx context.Context, req InvokeRequest) (InvokeResponse, error)
}
Invoker is an optional runner capability: a request/response action protocol with the plugin. The system runner implements it; the noop runner does not.
type KVHost ¶ added in v0.2.0
type KVHost interface {
Get(ctx context.Context, key string) ([]byte, bool, error)
Put(ctx context.Context, key string, value []byte) error
}
KVHost is the plugin-facing KV subset. The implementation remains server-owned.
type LoadOutcome ¶ added in v0.2.0
type LoadOutcome struct {
BundlePath string
PluginID string
Loaded bool
Reason string // failure reason when Loaded is false
}
LoadOutcome records the result of attempting to load one bundle so the caller can audit every accept and reject.
type Loaded ¶ added in v0.2.0
Loaded is a verified, registered plugin: the decoded manifest plus the capabilities the trust policy granted at load time. Execution (host-API binding and invocation) is a later milestone; loading establishes the verified registry and is the point at which signature/digest/capability trust is enforced.
type Loader ¶ added in v0.2.0
type Loader struct {
Dir string
Policy TrustPolicy
}
Loader discovers and verifies plugin bundles under Dir against an operator TrustPolicy. It never executes anything; it only decides what is trusted enough to register.
func (Loader) Load ¶ added in v0.2.0
func (l Loader) Load() ([]Loaded, []LoadOutcome, error)
Load scans the plugin directory and verifies each bundle. It returns the verified plugins (sorted by id) and a per-bundle outcome log. A bundle that fails verification is skipped and recorded as a failure — one bad bundle never aborts the scan or blocks startup. A missing/empty directory loads nothing.
type LogHost ¶ added in v0.2.0
type LogHost interface {
Write(ctx context.Context, entry HostLogEntry) error
}
LogHost records a plugin-authored log entry after the broker stamps plugin id.
type Manifest ¶
type Manifest struct {
ID string `json:"id"`
Name string `json:"name"`
Type string `json:"type"`
Capabilities []string `json:"capabilities"`
Version string `json:"version,omitempty"`
Entrypoint string `json:"entrypoint,omitempty"`
Publisher string `json:"publisher,omitempty"`
DigestSHA256 string `json:"digest_sha256,omitempty"`
SignatureEd25519 string `json:"signature_ed25519,omitempty"`
// UI + Interfaces are the design-10 dashboard contributions: declarative data
// (nav/views) + the interfaces the plugin exposes. They are covered by the
// signature (see SigningPayload) so a tampered contribution fails verification.
UI *ManifestUI `json:"ui,omitempty"`
Interfaces []InterfaceContract `json:"interfaces,omitempty"`
}
func VerifyInstallManifest ¶ added in v0.2.0
func VerifyInstallManifest(manifestBytes, artifact []byte, policy TrustPolicy) (Manifest, error)
type ManifestUI ¶ added in v0.2.0
type ManifestUI struct {
Views []ViewContribution `json:"views,omitempty"`
}
ManifestUI is a plugin's dashboard contribution set.
type NavContribution ¶ added in v0.2.0
type NavContribution struct {
}
NavContribution is a sidebar entry a plugin adds. Route is plugin-relative and mounted at /plugins/<id>/<route>.
type NotifyHost ¶ added in v0.2.0
NotifyHost sends an operator notification through server-owned channels.
type RPCHandler ¶ added in v0.2.0
RPCHandler serves one inter-plugin RPC method: it receives the method name and raw request bytes and returns raw response bytes. Implementations must be safe for concurrent use; the registry invokes them WITHOUT holding its lock.
type RPCHost ¶ added in v0.2.0
type RPCHost interface {
Call(ctx context.Context, caller, service, method string, request []byte) ([]byte, error)
}
RPCHost dispatches an inter-plugin RPC call to a server-owned registry that resolves the target service, enforces the directed caller->callee allow-list, and invokes the callee's handler. caller is the VERIFIED id of the calling plugin, supplied by the broker; a plugin cannot spoof it.
type RPCRegistry ¶ added in v0.2.0
type RPCRegistry struct {
// contains filtered or unexported fields
}
RPCRegistry is the server-owned inter-plugin RPC bus. It is safe for concurrent use and implements the broker's RPCHost interface.
func NewRPCRegistry ¶ added in v0.2.0
func NewRPCRegistry() *RPCRegistry
NewRPCRegistry returns an empty registry.
func (*RPCRegistry) Allow ¶ added in v0.2.0
func (r *RPCRegistry) Allow(callerPluginID, service string)
Allow grants callerPluginID permission to call service. Grants are directed and additive; a service owner can always call its own service.
func (*RPCRegistry) Call ¶ added in v0.2.0
func (r *RPCRegistry) Call(ctx context.Context, caller, service, method string, request []byte) ([]byte, error)
Call implements RPCHost: resolve the service, enforce the directed allow-list (the owner may always self-call), check the method, then dispatch to the handler OUTSIDE the lock so a slow or re-entrant handler cannot block the bus.
func (*RPCRegistry) CallOperator ¶ added in v0.2.0
func (r *RPCRegistry) CallOperator(ctx context.Context, service, method string, request []byte) ([]byte, error)
CallOperator dispatches a service method on behalf of the OPERATOR (the dashboard gateway), bypassing the plugin->plugin directed allow-list — the HTTP layer has already enforced the interface's declared RBAC scopes + audit. Service/method-not-found are still errors. The handler runs OUTSIDE the lock.
func (*RPCRegistry) Register ¶ added in v0.2.0
func (r *RPCRegistry) Register(ownerPluginID, service, version string, methods []string, handler RPCHandler) error
Register adds (or replaces) a service exposed by ownerPluginID. service is the fully-qualified id (e.g. "latticenet.vpn-core/nodes"); it must carry >=1 non-empty method and a non-nil handler. Re-registering the same id replaces it (used on plugin restart). The caller (server) is responsible for verifying the owner declared rpc:expose before registering.
func (*RPCRegistry) Revoke ¶ added in v0.2.0
func (r *RPCRegistry) Revoke(callerPluginID, service string)
Revoke removes a previously granted directed edge.
func (*RPCRegistry) Services ¶ added in v0.2.0
func (r *RPCRegistry) Services() []RPCServiceDescriptor
Services returns descriptors for every registered service, sorted by id, for discovery (e.g. an rpc.List host call). Handlers are not exposed.
func (*RPCRegistry) Unregister ¶ added in v0.2.0
func (r *RPCRegistry) Unregister(service string)
Unregister removes a service and any grants targeting it (e.g. on disable).
type RPCServiceDescriptor ¶ added in v0.2.0
type RPCServiceDescriptor struct {
Service string `json:"service"`
Owner string `json:"owner"`
Version string `json:"version"`
Methods []string `json:"methods"`
}
RPCServiceDescriptor is the discovery shape returned by RPCRegistry.Services. Handlers are never exposed.
type Runner ¶ added in v0.2.0
type Runner interface {
Name() string
Start(ctx context.Context, req RunnerStartRequest) (RunnerStartResult, error)
Stop(ctx context.Context, req RunnerStopRequest) error
}
Runner is the narrow runtime contract concrete plugin runtimes must satisfy. It receives a verified plugin and a capability-scoped broker, never raw server handles. Implementations must honor ctx cancellation and deadlines.
type RunnerStartRequest ¶ added in v0.2.0
type RunnerStartResult ¶ added in v0.2.0
type RunnerStartResult struct {
Message string
}
type RunnerStopRequest ¶ added in v0.2.0
type RuntimeManager ¶ added in v0.2.0
type RuntimeManager struct {
// contains filtered or unexported fields
}
RuntimeManager binds verified plugins to capability-scoped brokers and tracks runtime health. The current implementation is an execution-safe skeleton: it arms host-API access for a verified plugin but does not spawn processes, load wasm, or invoke artifact code.
func NewRuntimeManager ¶ added in v0.2.0
func NewRuntimeManager(services HostServices) *RuntimeManager
func NewRuntimeManagerWithOptions ¶ added in v0.2.0
func NewRuntimeManagerWithOptions(opts RuntimeManagerOptions) *RuntimeManager
func (*RuntimeManager) Invoke ¶ added in v0.2.0
func (m *RuntimeManager) Invoke(ctx context.Context, pluginID, action string, payload json.RawMessage) (InvokeResponse, error)
Invoke dispatches one action to an armed plugin whose runner supports the request/response protocol. It fails closed if the plugin is not armed or its runner is not an Invoker (e.g. the noop runner), so a disabled or execution-disabled plugin can never be invoked.
func (*RuntimeManager) IsArmed ¶ added in v0.2.0
func (m *RuntimeManager) IsArmed(pluginID string) bool
func (*RuntimeManager) Snapshot ¶ added in v0.2.0
func (m *RuntimeManager) Snapshot() map[string]RuntimeStatus
func (*RuntimeManager) Start ¶ added in v0.2.0
func (m *RuntimeManager) Start(ctx context.Context, loaded Loaded) (RuntimeStatus, error)
Start validates the loaded plugin, creates its broker, and marks it armed. The context is accepted now so future runners can honor cancellation without changing the call site.
func (*RuntimeManager) Status ¶ added in v0.2.0
func (m *RuntimeManager) Status(pluginID string) (RuntimeStatus, bool)
func (*RuntimeManager) Stop ¶ added in v0.2.0
func (m *RuntimeManager) Stop(pluginID, message string) (RuntimeStatus, error)
type RuntimeManagerOptions ¶ added in v0.2.0
type RuntimeManagerOptions struct {
Services HostServices
Runners map[string]Runner
StartTimeout time.Duration
}
type RuntimeStatus ¶ added in v0.2.0
type RuntimeStatus struct {
PluginID string `json:"plugin_id"`
State string `json:"state"`
Runner string `json:"runner,omitempty"`
Message string `json:"message,omitempty"`
StartedAt time.Time `json:"started_at,omitempty"`
StoppedAt time.Time `json:"stopped_at,omitempty"`
UpdatedAt time.Time `json:"updated_at"`
}
RuntimeStatus is the public, non-secret health view for one plugin runtime. It deliberately excludes local bundle paths and the broker itself.
type SystemRunner ¶ added in v0.2.0
type SystemRunner struct {
// contains filtered or unexported fields
}
SystemRunner implements Runner and Invoker.
func NewSystemRunner ¶ added in v0.2.0
func NewSystemRunner(opts SystemRunnerOptions) *SystemRunner
NewSystemRunner returns a system runner with the given options and safe defaults for any zero-valued bound.
func (*SystemRunner) Invoke ¶ added in v0.2.0
func (r *SystemRunner) Invoke(ctx context.Context, req InvokeRequest) (InvokeResponse, error)
Invoke runs the plugin for one action and returns its decoded reply. The process is spawned with arg-vector exec (NO shell, so payload content can never be interpreted as a command), a confined working directory, an allowlisted environment, capped output, and a deadline that escalates SIGTERM->SIGKILL. Repeated failures trip the circuit breaker. A crashing plugin yields an error, never a host crash.
func (*SystemRunner) Name ¶ added in v0.2.0
func (r *SystemRunner) Name() string
func (*SystemRunner) Start ¶ added in v0.2.0
func (r *SystemRunner) Start(ctx context.Context, req RunnerStartRequest) (RunnerStartResult, error)
Start re-verifies the manifest-pinned digest of the artifact at the FIXED bundle path (TOCTOU defense in case the bundle changed after load), copies the bytes into a confined per-plugin 0700 working dir, and arms the runner. It always executes the staged 0700 copy, never the (possibly read-only or swapped) bundle file, and never resolves a manifest-controlled path.
func (*SystemRunner) Stop ¶ added in v0.2.0
func (r *SystemRunner) Stop(ctx context.Context, req RunnerStopRequest) error
Stop clears the plugin's staged state and removes its runtime dir. In-flight invocations are bound to their own context and terminate independently.
type SystemRunnerOptions ¶ added in v0.2.0
type SystemRunnerOptions struct {
// RuntimeDir is the root under which each plugin gets a confined 0700 working
// directory (RuntimeDir/<pluginID>) holding a 0700 copy of its verified
// artifact. Required.
RuntimeDir string
// EnvAllowlist names the environment variables forwarded to the plugin. Every
// other variable is stripped; a fixed safe PATH is always provided.
EnvAllowlist []string
// InvokeTimeout bounds one invocation (default 10s).
InvokeTimeout time.Duration
// StopGrace is the SIGTERM->SIGKILL window for a timed-out/cancelled process
// (default 3s).
StopGrace time.Duration
// MaxOutputBytes caps captured stdout and (separately) stderr per invocation
// (default 1 MiB), so a plugin cannot exhaust host memory by flooding output.
MaxOutputBytes int
// CrashThreshold trips the circuit breaker after this many consecutive failed
// invocations (default 5).
CrashThreshold int
// MaxHostCalls caps broker calls during one invocation (default 64).
MaxHostCalls int
}
SystemRunnerOptions configures the trusted-subprocess runner.
type TrustPolicy ¶ added in v0.2.0
type TrustPolicy struct {
TrustedPublishers map[string]ed25519.PublicKey
// AllowUnsignedHostRisk opts OUT of signature enforcement for host-risk
// plugins. The zero value is fail-closed: host-risk plugins require a trusted
// publisher signature unless an operator explicitly sets this true (dev only).
AllowUnsignedHostRisk bool
}
func ParseTrustPolicyJSON ¶ added in v0.2.0
func ParseTrustPolicyJSON(data []byte) (TrustPolicy, error)
type ViewAction ¶ added in v0.2.0
type ViewAction struct {
Label string `json:"label"`
Interface string `json:"interface"`
Method string `json:"method"`
Form []ViewFormField `json:"form,omitempty"`
Scopes []string `json:"scopes,omitempty"`
}
ViewAction is a button that calls an interface method (optionally with a form).
type ViewColumn ¶ added in v0.2.0
type ViewColumn struct {
Key string `json:"key"`
Label string `json:"label"`
Render string `json:"render,omitempty"`
}
ViewColumn is one table column. Render selects a safe dashboard formatter.
type ViewContribution ¶ added in v0.2.0
type ViewContribution struct {
Route string `json:"route"`
Title string `json:"title"`
Kind string `json:"kind"`
ComponentKey string `json:"component_key,omitempty"`
Source *ViewSource `json:"source,omitempty"`
Columns []ViewColumn `json:"columns,omitempty"`
Actions []ViewAction `json:"actions,omitempty"`
}
ViewContribution is one declarative view rendered by a fixed dashboard primitive.
type ViewFormField ¶ added in v0.2.0
type ViewFormField struct {
Key string `json:"key"`
Label string `json:"label,omitempty"`
Kind string `json:"kind"`
Options []string `json:"options,omitempty"`
}
ViewFormField is one input in an action form.
type ViewSource ¶ added in v0.2.0
ViewSource binds a view's data to a plugin interface method.