mirror of
https://github.com/netbirdio/netbird.git
synced 2026-08-04 14:51:27 +02:00
Compare commits
5 Commits
main
...
agent-netw
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e193e59c6a | ||
|
|
ba3db38932 | ||
|
|
9169a36658 | ||
|
|
74b2f5cf4f | ||
|
|
5d4c7f32f4 |
336
client/cmd/agentnetwork.go
Normal file
336
client/cmd/agentnetwork.go
Normal file
@@ -0,0 +1,336 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
"google.golang.org/protobuf/encoding/protojson"
|
||||
|
||||
"github.com/netbirdio/netbird/client/proto"
|
||||
)
|
||||
|
||||
// agentNetworkAuthToken is the placeholder credential exported for
|
||||
// AI-tool CLIs: the Agent Network proxy authenticates callers by tunnel
|
||||
// peer and injects the real upstream credentials itself, so the
|
||||
// client-side token only needs to satisfy the tool's non-empty check.
|
||||
const agentNetworkAuthToken = "netbird"
|
||||
|
||||
var (
|
||||
agentNetworkProviderFlag string
|
||||
agentNetworkModelFlag string
|
||||
agentNetworkJSONFlag bool
|
||||
)
|
||||
|
||||
var agentNetworkCmd = &cobra.Command{
|
||||
Use: "agent-network",
|
||||
Short: "Show the Agent Network setup available to this peer",
|
||||
Long: `Commands to inspect the Agent Network (AI provider proxy) setup this peer's groups authorize:
|
||||
the proxy endpoint, the reachable providers, and the allowed models.`,
|
||||
}
|
||||
|
||||
var agentNetworkLsCmd = &cobra.Command{
|
||||
Use: "ls",
|
||||
Aliases: []string{"list"},
|
||||
Short: "List the Agent Network endpoint, providers, and allowed models",
|
||||
Example: " netbird agent-network ls",
|
||||
RunE: agentNetworkLs,
|
||||
}
|
||||
|
||||
var agentNetworkEnvCmd = &cobra.Command{
|
||||
Use: "env",
|
||||
Short: "Print shell export lines that point AI tools at the Agent Network",
|
||||
Long: `Print POSIX shell export lines that configure AI tools to use the Agent Network proxy.
|
||||
The variables depend on the provider's API shape — Anthropic API, AWS Bedrock, Google Vertex AI,
|
||||
and OpenAI-compatible providers each get the environment their tools expect (for Claude Code,
|
||||
following its LLM-gateway configuration). Apply them to the current shell with:
|
||||
|
||||
eval "$(netbird agent-network env)"
|
||||
|
||||
When several providers are authorized, pass --provider to pick one; when several models are
|
||||
allowed, pass --model to pin one — nothing is ever guessed.`,
|
||||
Example: " eval \"$(netbird agent-network env)\"\n eval \"$(netbird agent-network env --provider 'Bedrock prod' --model anthropic.claude-sonnet-4-5)\"",
|
||||
RunE: agentNetworkEnv,
|
||||
}
|
||||
|
||||
func init() {
|
||||
agentNetworkLsCmd.PersistentFlags().BoolVar(&agentNetworkJSONFlag, "json", false, "output the setup as JSON")
|
||||
agentNetworkEnvCmd.PersistentFlags().StringVar(&agentNetworkProviderFlag, "provider", "", "provider to configure, by name or catalog id (required when several are authorized)")
|
||||
agentNetworkEnvCmd.PersistentFlags().StringVar(&agentNetworkModelFlag, "model", "", "model to export (required when several models are allowed)")
|
||||
}
|
||||
|
||||
// fetchAgentNetworkSetup asks the daemon for the caller-scoped Agent
|
||||
// Network setup. The daemon relays the request to management over its
|
||||
// existing peer connection, so no elevated permissions are needed.
|
||||
func fetchAgentNetworkSetup(cmd *cobra.Command) (*proto.GetAgentNetworkSetupResponse, error) {
|
||||
conn, err := getClient(cmd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
client := proto.NewDaemonServiceClient(conn)
|
||||
setup, err := client.GetAgentNetworkSetup(cmd.Context(), &proto.GetAgentNetworkSetupRequest{})
|
||||
if err != nil {
|
||||
if s, ok := status.FromError(err); ok && s.Code() == codes.Unimplemented {
|
||||
return nil, fmt.Errorf("the running daemon does not support agent-network commands — update the NetBird daemon and restart the service")
|
||||
}
|
||||
return nil, fmt.Errorf("get agent network setup: %v", status.Convert(err).Message())
|
||||
}
|
||||
return setup, nil
|
||||
}
|
||||
|
||||
func agentNetworkLs(cmd *cobra.Command, _ []string) error {
|
||||
setup, err := fetchAgentNetworkSetup(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if agentNetworkJSONFlag {
|
||||
out, err := protojson.MarshalOptions{Multiline: true, Indent: " "}.Marshal(setup)
|
||||
if err != nil {
|
||||
return fmt.Errorf("marshal setup: %v", err)
|
||||
}
|
||||
cmd.Println(string(out))
|
||||
return nil
|
||||
}
|
||||
|
||||
if !setup.Configured {
|
||||
cmd.Println("Agent Network is not available for this peer. Ask your administrator.")
|
||||
return nil
|
||||
}
|
||||
|
||||
cmd.Printf("Agent Network endpoint: %s\n", setup.Endpoint)
|
||||
cmd.Println("(reachable while connected to NetBird)")
|
||||
for _, p := range setup.Providers {
|
||||
cmd.Println()
|
||||
cmd.Printf("%s (%s)\n", sanitizeOutput(p.Name), sanitizeOutput(providerFlavorLabel(p)))
|
||||
switch {
|
||||
case p.AllModelsAllowed && len(p.Models) == 0:
|
||||
cmd.Println(" All models allowed")
|
||||
case p.AllModelsAllowed:
|
||||
cmd.Println(" All models allowed, including:")
|
||||
printModels(cmd, p.Models)
|
||||
default:
|
||||
cmd.Println(" Allowed models:")
|
||||
printModels(cmd, p.Models)
|
||||
}
|
||||
}
|
||||
cmd.Println()
|
||||
cmd.Println("To configure an AI tool in the current shell: eval \"$(netbird agent-network env)\"")
|
||||
return nil
|
||||
}
|
||||
|
||||
func printModels(cmd *cobra.Command, models []string) {
|
||||
if len(models) == 0 {
|
||||
cmd.Println(" (none)")
|
||||
return
|
||||
}
|
||||
for _, m := range models {
|
||||
cmd.Printf(" %s\n", sanitizeOutput(m))
|
||||
}
|
||||
}
|
||||
|
||||
func providerFlavorLabel(p *proto.AgentNetworkProvider) string {
|
||||
if p.ApiFlavor == "" {
|
||||
return p.CatalogId
|
||||
}
|
||||
return fmt.Sprintf("%s · %s-flavor API", p.CatalogId, p.ApiFlavor)
|
||||
}
|
||||
|
||||
func agentNetworkEnv(cmd *cobra.Command, _ []string) error {
|
||||
setup, err := fetchAgentNetworkSetup(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !setup.Configured {
|
||||
// An answer, not an error: print nothing eval-able and say why on
|
||||
// stderr so `eval "$(...)"` stays a harmless no-op.
|
||||
cmd.PrintErrln("Agent Network is not available for this peer. Ask your administrator.")
|
||||
return nil
|
||||
}
|
||||
|
||||
lines, err := buildAgentNetworkEnv(setup, agentNetworkProviderFlag, agentNetworkModelFlag)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, line := range lines {
|
||||
cmd.Println(line)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// buildAgentNetworkEnv renders the export lines for one selected
|
||||
// provider. Nothing is guessed: an ambiguous provider or model choice
|
||||
// comes back as comment lines instead of exports, and an invalid
|
||||
// --provider/--model is an error.
|
||||
func buildAgentNetworkEnv(setup *proto.GetAgentNetworkSetupResponse, providerFlag, modelFlag string) ([]string, error) {
|
||||
provider, choiceLines, err := selectAgentNetworkProvider(setup.Providers, providerFlag)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if provider == nil {
|
||||
return choiceLines, nil
|
||||
}
|
||||
|
||||
model, modelNotes, err := resolveAgentNetworkModel(provider, modelFlag)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var lines []string
|
||||
switch {
|
||||
case provider.CatalogId == "bedrock_api":
|
||||
// Claude Code's Bedrock-format gateway configuration: the proxy
|
||||
// routes native Bedrock paths and injects the AWS credentials, so
|
||||
// client-side signing is skipped.
|
||||
lines = append(lines,
|
||||
exportLine("CLAUDE_CODE_USE_BEDROCK", "1"),
|
||||
exportLine("ANTHROPIC_BEDROCK_BASE_URL", setup.Endpoint),
|
||||
exportLine("CLAUDE_CODE_SKIP_BEDROCK_AUTH", "1"),
|
||||
)
|
||||
if model != "" {
|
||||
lines = append(lines, exportLine("ANTHROPIC_MODEL", model))
|
||||
}
|
||||
case provider.CatalogId == "vertex_ai_api":
|
||||
// Claude Code's Vertex-format gateway configuration. Vertex
|
||||
// requests carry the GCP project and region in the URL path, which
|
||||
// the proxy forwards to the upstream — those two values belong to
|
||||
// the operator's GCP setup and must come from the administrator.
|
||||
lines = append(lines,
|
||||
exportLine("CLAUDE_CODE_USE_VERTEX", "1"),
|
||||
exportLine("ANTHROPIC_VERTEX_BASE_URL", setup.Endpoint),
|
||||
exportLine("CLAUDE_CODE_SKIP_VERTEX_AUTH", "1"),
|
||||
)
|
||||
if model != "" {
|
||||
lines = append(lines, exportLine("ANTHROPIC_MODEL", model))
|
||||
}
|
||||
lines = append(lines,
|
||||
comment("Vertex requests carry your operator's GCP project and region in the URL."),
|
||||
comment("Ask your administrator for the values, then export:"),
|
||||
comment(" export ANTHROPIC_VERTEX_PROJECT_ID=<project>"),
|
||||
comment(" export CLOUD_ML_REGION=<region>"),
|
||||
)
|
||||
case provider.ApiFlavor == "anthropic":
|
||||
lines = append(lines,
|
||||
exportLine("ANTHROPIC_BASE_URL", setup.Endpoint),
|
||||
exportLine("ANTHROPIC_AUTH_TOKEN", agentNetworkAuthToken),
|
||||
)
|
||||
if model != "" {
|
||||
lines = append(lines, exportLine("ANTHROPIC_MODEL", model))
|
||||
}
|
||||
case provider.ApiFlavor == "openai":
|
||||
lines = append(lines,
|
||||
exportLine("OPENAI_BASE_URL", setup.Endpoint),
|
||||
exportLine("OPENAI_API_KEY", agentNetworkAuthToken),
|
||||
)
|
||||
if model != "" {
|
||||
lines = append(lines, comment(fmt.Sprintf("Configure your tool to use model %s.", model)))
|
||||
}
|
||||
default:
|
||||
lines = append(lines,
|
||||
comment(fmt.Sprintf("Provider %s (%s) is dispatched by URL path; no standard environment", provider.Name, provider.CatalogId)),
|
||||
comment("variables apply. Point your tool at the endpoint below (auth token: netbird):"),
|
||||
comment(" "+setup.Endpoint),
|
||||
)
|
||||
}
|
||||
|
||||
for _, note := range modelNotes {
|
||||
lines = append(lines, comment(note))
|
||||
}
|
||||
return lines, nil
|
||||
}
|
||||
|
||||
// selectAgentNetworkProvider picks the provider to configure. An
|
||||
// explicit --provider matches the operator label or catalog id
|
||||
// (case-insensitive); with no flag a single authorized provider is
|
||||
// used, and several come back as comment lines asking for the flag.
|
||||
func selectAgentNetworkProvider(providers []*proto.AgentNetworkProvider, providerFlag string) (*proto.AgentNetworkProvider, []string, error) {
|
||||
if providerFlag != "" {
|
||||
wanted := strings.ToLower(strings.TrimSpace(providerFlag))
|
||||
for _, p := range providers {
|
||||
if strings.ToLower(strings.TrimSpace(p.Name)) == wanted || strings.ToLower(p.CatalogId) == wanted {
|
||||
return p, nil, nil
|
||||
}
|
||||
}
|
||||
names := make([]string, 0, len(providers))
|
||||
for _, p := range providers {
|
||||
names = append(names, fmt.Sprintf("%s (%s)", p.Name, p.CatalogId))
|
||||
}
|
||||
return nil, nil, fmt.Errorf("provider %q is not authorized for this peer — available: %s", providerFlag, strings.Join(names, ", "))
|
||||
}
|
||||
|
||||
if len(providers) == 1 {
|
||||
return providers[0], nil, nil
|
||||
}
|
||||
|
||||
lines := []string{comment("Multiple providers are authorized — none configured. Re-run with --provider to pick one:")}
|
||||
for _, p := range providers {
|
||||
lines = append(lines, comment(fmt.Sprintf(" netbird agent-network env --provider %q (%s)", p.Name, providerFlavorLabel(p))))
|
||||
}
|
||||
return nil, lines, nil
|
||||
}
|
||||
|
||||
// resolveAgentNetworkModel picks the model for the selected provider. A
|
||||
// model is never guessed: --model wins (validated against the allowed
|
||||
// set), a single allowed model is used, and anything ambiguous is
|
||||
// returned as note lines instead.
|
||||
func resolveAgentNetworkModel(provider *proto.AgentNetworkProvider, modelFlag string) (string, []string, error) {
|
||||
if modelFlag != "" {
|
||||
if provider.AllModelsAllowed {
|
||||
return modelFlag, nil, nil
|
||||
}
|
||||
wanted := strings.ToLower(strings.TrimSpace(modelFlag))
|
||||
for _, m := range provider.Models {
|
||||
if strings.ToLower(strings.TrimSpace(m)) == wanted {
|
||||
return modelFlag, nil, nil
|
||||
}
|
||||
}
|
||||
return "", nil, fmt.Errorf("model %q is not allowed on provider %s — run 'netbird agent-network ls' to see the allowed models", modelFlag, provider.Name)
|
||||
}
|
||||
|
||||
if len(provider.Models) == 1 && !provider.AllModelsAllowed {
|
||||
return provider.Models[0], nil, nil
|
||||
}
|
||||
if len(provider.Models) == 0 && provider.AllModelsAllowed {
|
||||
return "", []string{"Any model is allowed; pass --model to pin one."}, nil
|
||||
}
|
||||
|
||||
notes := []string{"Multiple models are allowed — none exported. Re-run with --model to pin one:"}
|
||||
for _, m := range provider.Models {
|
||||
notes = append(notes, " "+m)
|
||||
}
|
||||
if provider.AllModelsAllowed {
|
||||
notes = append(notes, " (any other model the provider serves)")
|
||||
}
|
||||
return "", notes, nil
|
||||
}
|
||||
|
||||
func exportLine(name, value string) string {
|
||||
return fmt.Sprintf("export %s=%s", name, shellQuote(value))
|
||||
}
|
||||
|
||||
func comment(text string) string {
|
||||
return "# " + sanitizeOutput(text)
|
||||
}
|
||||
|
||||
// shellQuote single-quotes a value for safe use in an eval'd export
|
||||
// line, escaping embedded single quotes.
|
||||
func shellQuote(v string) string {
|
||||
return "'" + strings.ReplaceAll(v, "'", `'\''`) + "'"
|
||||
}
|
||||
|
||||
// sanitizeOutput strips control characters (including newlines) from
|
||||
// server-supplied strings so operator-typed values can't break the
|
||||
// line-oriented output or smuggle lines past a `# ` comment prefix.
|
||||
func sanitizeOutput(v string) string {
|
||||
return strings.Map(func(r rune) rune {
|
||||
if r < 0x20 || r == 0x7f {
|
||||
return -1
|
||||
}
|
||||
return r
|
||||
}, v)
|
||||
}
|
||||
165
client/cmd/agentnetwork_test.go
Normal file
165
client/cmd/agentnetwork_test.go
Normal file
@@ -0,0 +1,165 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/netbirdio/netbird/client/proto"
|
||||
)
|
||||
|
||||
func anTestSetup(providers ...*proto.AgentNetworkProvider) *proto.GetAgentNetworkSetupResponse {
|
||||
return &proto.GetAgentNetworkSetupResponse{
|
||||
Configured: true,
|
||||
Endpoint: "https://calm-otter.proxy.example.com",
|
||||
Providers: providers,
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildAgentNetworkEnv_AnthropicSingleModel(t *testing.T) {
|
||||
setup := anTestSetup(&proto.AgentNetworkProvider{
|
||||
Name: "Anthropic prod", CatalogId: "anthropic_api", ApiFlavor: "anthropic",
|
||||
Models: []string{"claude-sonnet-4-5"},
|
||||
})
|
||||
|
||||
lines, err := buildAgentNetworkEnv(setup, "", "")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, []string{
|
||||
"export ANTHROPIC_BASE_URL='https://calm-otter.proxy.example.com'",
|
||||
"export ANTHROPIC_AUTH_TOKEN='netbird'",
|
||||
"export ANTHROPIC_MODEL='claude-sonnet-4-5'",
|
||||
}, lines)
|
||||
}
|
||||
|
||||
func TestBuildAgentNetworkEnv_MultipleModelsBecomeComments(t *testing.T) {
|
||||
setup := anTestSetup(&proto.AgentNetworkProvider{
|
||||
Name: "Anthropic prod", CatalogId: "anthropic_api", ApiFlavor: "anthropic",
|
||||
Models: []string{"claude-sonnet-4-5", "claude-haiku-4-5"},
|
||||
})
|
||||
|
||||
lines, err := buildAgentNetworkEnv(setup, "", "")
|
||||
require.NoError(t, err)
|
||||
assert.Contains(t, lines, "export ANTHROPIC_BASE_URL='https://calm-otter.proxy.example.com'")
|
||||
assert.NotContains(t, strings.Join(lines, "\n"), "ANTHROPIC_MODEL=", "no model is ever guessed")
|
||||
assert.Contains(t, strings.Join(lines, "\n"), "# Multiple models are allowed")
|
||||
}
|
||||
|
||||
func TestBuildAgentNetworkEnv_ModelFlagValidated(t *testing.T) {
|
||||
setup := anTestSetup(&proto.AgentNetworkProvider{
|
||||
Name: "Anthropic prod", CatalogId: "anthropic_api", ApiFlavor: "anthropic",
|
||||
Models: []string{"claude-sonnet-4-5", "claude-haiku-4-5"},
|
||||
})
|
||||
|
||||
lines, err := buildAgentNetworkEnv(setup, "", "Claude-Haiku-4-5")
|
||||
require.NoError(t, err, "model match is case-insensitive")
|
||||
assert.Contains(t, lines, "export ANTHROPIC_MODEL='Claude-Haiku-4-5'")
|
||||
|
||||
_, err = buildAgentNetworkEnv(setup, "", "gpt-4o")
|
||||
require.Error(t, err, "a model outside the allowlist is rejected")
|
||||
}
|
||||
|
||||
func TestBuildAgentNetworkEnv_BedrockFlavor(t *testing.T) {
|
||||
setup := anTestSetup(&proto.AgentNetworkProvider{
|
||||
Name: "Bedrock prod", CatalogId: "bedrock_api", ApiFlavor: "",
|
||||
Models: []string{"anthropic.claude-sonnet-4-5"},
|
||||
})
|
||||
|
||||
lines, err := buildAgentNetworkEnv(setup, "", "")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, []string{
|
||||
"export CLAUDE_CODE_USE_BEDROCK='1'",
|
||||
"export ANTHROPIC_BEDROCK_BASE_URL='https://calm-otter.proxy.example.com'",
|
||||
"export CLAUDE_CODE_SKIP_BEDROCK_AUTH='1'",
|
||||
"export ANTHROPIC_MODEL='anthropic.claude-sonnet-4-5'",
|
||||
}, lines)
|
||||
}
|
||||
|
||||
func TestBuildAgentNetworkEnv_VertexFlavorNotesProjectAndRegion(t *testing.T) {
|
||||
setup := anTestSetup(&proto.AgentNetworkProvider{
|
||||
Name: "Vertex prod", CatalogId: "vertex_ai_api", ApiFlavor: "",
|
||||
Models: []string{"claude-sonnet-4-5"},
|
||||
})
|
||||
|
||||
lines, err := buildAgentNetworkEnv(setup, "", "")
|
||||
require.NoError(t, err)
|
||||
joined := strings.Join(lines, "\n")
|
||||
assert.Contains(t, lines, "export CLAUDE_CODE_USE_VERTEX='1'")
|
||||
assert.Contains(t, lines, "export ANTHROPIC_VERTEX_BASE_URL='https://calm-otter.proxy.example.com'")
|
||||
assert.Contains(t, lines, "export CLAUDE_CODE_SKIP_VERTEX_AUTH='1'")
|
||||
assert.Contains(t, lines, "export ANTHROPIC_MODEL='claude-sonnet-4-5'")
|
||||
assert.Contains(t, joined, "ANTHROPIC_VERTEX_PROJECT_ID", "project id must be called out as admin-supplied")
|
||||
assert.Contains(t, joined, "CLOUD_ML_REGION", "region must be called out as admin-supplied")
|
||||
}
|
||||
|
||||
func TestBuildAgentNetworkEnv_OpenAIFlavor(t *testing.T) {
|
||||
setup := anTestSetup(&proto.AgentNetworkProvider{
|
||||
Name: "OpenAI prod", CatalogId: "openai_api", ApiFlavor: "openai",
|
||||
Models: []string{"gpt-5.4"},
|
||||
})
|
||||
|
||||
lines, err := buildAgentNetworkEnv(setup, "", "")
|
||||
require.NoError(t, err)
|
||||
assert.Contains(t, lines, "export OPENAI_BASE_URL='https://calm-otter.proxy.example.com'")
|
||||
assert.Contains(t, lines, "export OPENAI_API_KEY='netbird'")
|
||||
assert.NotContains(t, strings.Join(lines, "\n"), "ANTHROPIC_", "openai flavor must not emit anthropic variables")
|
||||
}
|
||||
|
||||
func TestBuildAgentNetworkEnv_MultipleProvidersRequireFlag(t *testing.T) {
|
||||
anthropic := &proto.AgentNetworkProvider{Name: "Anthropic prod", CatalogId: "anthropic_api", ApiFlavor: "anthropic", Models: []string{"claude-sonnet-4-5"}}
|
||||
bedrock := &proto.AgentNetworkProvider{Name: "Bedrock prod", CatalogId: "bedrock_api", Models: []string{"anthropic.claude-sonnet-4-5"}}
|
||||
setup := anTestSetup(anthropic, bedrock)
|
||||
|
||||
lines, err := buildAgentNetworkEnv(setup, "", "")
|
||||
require.NoError(t, err)
|
||||
joined := strings.Join(lines, "\n")
|
||||
assert.NotContains(t, joined, "export ", "ambiguous provider choice must export nothing")
|
||||
assert.Contains(t, joined, "--provider")
|
||||
assert.Contains(t, joined, "Bedrock prod")
|
||||
|
||||
// Selection by operator label, case-insensitive.
|
||||
lines, err = buildAgentNetworkEnv(setup, "bedrock prod", "")
|
||||
require.NoError(t, err)
|
||||
assert.Contains(t, lines, "export CLAUDE_CODE_USE_BEDROCK='1'")
|
||||
|
||||
// Selection by catalog id.
|
||||
lines, err = buildAgentNetworkEnv(setup, "anthropic_api", "")
|
||||
require.NoError(t, err)
|
||||
assert.Contains(t, lines, "export ANTHROPIC_AUTH_TOKEN='netbird'")
|
||||
|
||||
// Unknown provider is an error naming the available ones.
|
||||
_, err = buildAgentNetworkEnv(setup, "vertex", "")
|
||||
require.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "Anthropic prod")
|
||||
}
|
||||
|
||||
func TestBuildAgentNetworkEnv_AllModelsAllowed(t *testing.T) {
|
||||
setup := anTestSetup(&proto.AgentNetworkProvider{
|
||||
Name: "Anthropic prod", CatalogId: "anthropic_api", ApiFlavor: "anthropic",
|
||||
AllModelsAllowed: true, Models: []string{"claude-sonnet-4-5"},
|
||||
})
|
||||
|
||||
// A courtesy-listed single model is still ambiguous when everything is allowed.
|
||||
lines, err := buildAgentNetworkEnv(setup, "", "")
|
||||
require.NoError(t, err)
|
||||
assert.NotContains(t, strings.Join(lines, "\n"), "ANTHROPIC_MODEL=")
|
||||
|
||||
// --model passes without allowlist validation.
|
||||
lines, err = buildAgentNetworkEnv(setup, "", "claude-opus-4-8")
|
||||
require.NoError(t, err)
|
||||
assert.Contains(t, lines, "export ANTHROPIC_MODEL='claude-opus-4-8'")
|
||||
}
|
||||
|
||||
func TestBuildAgentNetworkEnv_UnknownFlavorFallsBackToComments(t *testing.T) {
|
||||
setup := anTestSetup(&proto.AgentNetworkProvider{
|
||||
Name: "Kimi", CatalogId: "kimi_api", ApiFlavor: "",
|
||||
Models: []string{"kimi-k3"},
|
||||
})
|
||||
|
||||
lines, err := buildAgentNetworkEnv(setup, "", "")
|
||||
require.NoError(t, err)
|
||||
joined := strings.Join(lines, "\n")
|
||||
assert.NotContains(t, joined, "export ", "unknown API shape must not guess variables")
|
||||
assert.Contains(t, joined, "https://calm-otter.proxy.example.com")
|
||||
}
|
||||
@@ -171,6 +171,9 @@ func init() {
|
||||
rootCmd.AddCommand(debugCmd)
|
||||
rootCmd.AddCommand(profileCmd)
|
||||
rootCmd.AddCommand(exposeCmd)
|
||||
rootCmd.AddCommand(agentNetworkCmd)
|
||||
agentNetworkCmd.AddCommand(agentNetworkLsCmd)
|
||||
agentNetworkCmd.AddCommand(agentNetworkEnvCmd)
|
||||
|
||||
networksCMD.AddCommand(routesListCmd)
|
||||
networksCMD.AddCommand(routesSelectCmd, routesDeselectCmd)
|
||||
|
||||
@@ -2200,6 +2200,19 @@ func (e *Engine) GetExposeManager() *expose.Manager {
|
||||
return e.exposeManager
|
||||
}
|
||||
|
||||
// GetAgentNetworkSetup asks the management server for the Agent Network
|
||||
// connection info this peer's groups authorize, over the engine's
|
||||
// existing management connection.
|
||||
func (e *Engine) GetAgentNetworkSetup(ctx context.Context) (*mgmProto.AgentNetworkSetupResponse, error) {
|
||||
e.syncMsgMux.Lock()
|
||||
mgmClient := e.mgmClient
|
||||
e.syncMsgMux.Unlock()
|
||||
if mgmClient == nil {
|
||||
return nil, errors.New("management client not available")
|
||||
}
|
||||
return mgmClient.GetAgentNetworkSetup(ctx)
|
||||
}
|
||||
|
||||
// IsBlockInbound returns whether inbound connections are blocked.
|
||||
func (e *Engine) IsBlockInbound() bool {
|
||||
return e.config.BlockInbound
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.6
|
||||
// protoc v6.33.1
|
||||
// protoc v7.34.1
|
||||
// source: daemon.proto
|
||||
|
||||
package proto
|
||||
@@ -6941,6 +6941,190 @@ func (*StopBundleCaptureResponse) Descriptor() ([]byte, []int) {
|
||||
return file_daemon_proto_rawDescGZIP(), []int{106}
|
||||
}
|
||||
|
||||
type GetAgentNetworkSetupRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *GetAgentNetworkSetupRequest) Reset() {
|
||||
*x = GetAgentNetworkSetupRequest{}
|
||||
mi := &file_daemon_proto_msgTypes[107]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *GetAgentNetworkSetupRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*GetAgentNetworkSetupRequest) ProtoMessage() {}
|
||||
|
||||
func (x *GetAgentNetworkSetupRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_daemon_proto_msgTypes[107]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use GetAgentNetworkSetupRequest.ProtoReflect.Descriptor instead.
|
||||
func (*GetAgentNetworkSetupRequest) Descriptor() ([]byte, []int) {
|
||||
return file_daemon_proto_rawDescGZIP(), []int{107}
|
||||
}
|
||||
|
||||
type GetAgentNetworkSetupResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
// configured is false when the account has no Agent Network set up or
|
||||
// this peer's groups authorize none of it.
|
||||
Configured bool `protobuf:"varint,1,opt,name=configured,proto3" json:"configured,omitempty"`
|
||||
// endpoint is the account's proxy base URL, reachable over the NetBird
|
||||
// tunnel only. Empty when configured is false.
|
||||
Endpoint string `protobuf:"bytes,2,opt,name=endpoint,proto3" json:"endpoint,omitempty"`
|
||||
Providers []*AgentNetworkProvider `protobuf:"bytes,3,rep,name=providers,proto3" json:"providers,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *GetAgentNetworkSetupResponse) Reset() {
|
||||
*x = GetAgentNetworkSetupResponse{}
|
||||
mi := &file_daemon_proto_msgTypes[108]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *GetAgentNetworkSetupResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*GetAgentNetworkSetupResponse) ProtoMessage() {}
|
||||
|
||||
func (x *GetAgentNetworkSetupResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_daemon_proto_msgTypes[108]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use GetAgentNetworkSetupResponse.ProtoReflect.Descriptor instead.
|
||||
func (*GetAgentNetworkSetupResponse) Descriptor() ([]byte, []int) {
|
||||
return file_daemon_proto_rawDescGZIP(), []int{108}
|
||||
}
|
||||
|
||||
func (x *GetAgentNetworkSetupResponse) GetConfigured() bool {
|
||||
if x != nil {
|
||||
return x.Configured
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *GetAgentNetworkSetupResponse) GetEndpoint() string {
|
||||
if x != nil {
|
||||
return x.Endpoint
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *GetAgentNetworkSetupResponse) GetProviders() []*AgentNetworkProvider {
|
||||
if x != nil {
|
||||
return x.Providers
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type AgentNetworkProvider struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
// name is the operator-assigned provider label, e.g. "Bedrock prod".
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
// catalog_id names the provider type, e.g. "anthropic_api", "bedrock_api".
|
||||
CatalogId string `protobuf:"bytes,2,opt,name=catalog_id,json=catalogId,proto3" json:"catalog_id,omitempty"`
|
||||
// api_flavor is the request-body shape the provider speaks ("anthropic",
|
||||
// "openai"); empty when the proxy dispatches it by URL path instead.
|
||||
ApiFlavor string `protobuf:"bytes,3,opt,name=api_flavor,json=apiFlavor,proto3" json:"api_flavor,omitempty"`
|
||||
// all_models_allowed is true when no model allowlist restricts this
|
||||
// provider for the caller.
|
||||
AllModelsAllowed bool `protobuf:"varint,4,opt,name=all_models_allowed,json=allModelsAllowed,proto3" json:"all_models_allowed,omitempty"`
|
||||
// models is the effective model allowlist (or the declared/catalog models
|
||||
// when all_models_allowed is true).
|
||||
Models []string `protobuf:"bytes,5,rep,name=models,proto3" json:"models,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *AgentNetworkProvider) Reset() {
|
||||
*x = AgentNetworkProvider{}
|
||||
mi := &file_daemon_proto_msgTypes[109]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *AgentNetworkProvider) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*AgentNetworkProvider) ProtoMessage() {}
|
||||
|
||||
func (x *AgentNetworkProvider) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_daemon_proto_msgTypes[109]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use AgentNetworkProvider.ProtoReflect.Descriptor instead.
|
||||
func (*AgentNetworkProvider) Descriptor() ([]byte, []int) {
|
||||
return file_daemon_proto_rawDescGZIP(), []int{109}
|
||||
}
|
||||
|
||||
func (x *AgentNetworkProvider) GetName() string {
|
||||
if x != nil {
|
||||
return x.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *AgentNetworkProvider) GetCatalogId() string {
|
||||
if x != nil {
|
||||
return x.CatalogId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *AgentNetworkProvider) GetApiFlavor() string {
|
||||
if x != nil {
|
||||
return x.ApiFlavor
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *AgentNetworkProvider) GetAllModelsAllowed() bool {
|
||||
if x != nil {
|
||||
return x.AllModelsAllowed
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *AgentNetworkProvider) GetModels() []string {
|
||||
if x != nil {
|
||||
return x.Models
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type PortInfo_Range struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Start uint32 `protobuf:"varint,1,opt,name=start,proto3" json:"start,omitempty"`
|
||||
@@ -6951,7 +7135,7 @@ type PortInfo_Range struct {
|
||||
|
||||
func (x *PortInfo_Range) Reset() {
|
||||
*x = PortInfo_Range{}
|
||||
mi := &file_daemon_proto_msgTypes[108]
|
||||
mi := &file_daemon_proto_msgTypes[111]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -6963,7 +7147,7 @@ func (x *PortInfo_Range) String() string {
|
||||
func (*PortInfo_Range) ProtoMessage() {}
|
||||
|
||||
func (x *PortInfo_Range) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_daemon_proto_msgTypes[108]
|
||||
mi := &file_daemon_proto_msgTypes[111]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -7577,7 +7761,22 @@ const file_daemon_proto_rawDesc = "" +
|
||||
"\atimeout\x18\x01 \x01(\v2\x19.google.protobuf.DurationR\atimeout\"\x1c\n" +
|
||||
"\x1aStartBundleCaptureResponse\"\x1a\n" +
|
||||
"\x18StopBundleCaptureRequest\"\x1b\n" +
|
||||
"\x19StopBundleCaptureResponse*b\n" +
|
||||
"\x19StopBundleCaptureResponse\"\x1d\n" +
|
||||
"\x1bGetAgentNetworkSetupRequest\"\x96\x01\n" +
|
||||
"\x1cGetAgentNetworkSetupResponse\x12\x1e\n" +
|
||||
"\n" +
|
||||
"configured\x18\x01 \x01(\bR\n" +
|
||||
"configured\x12\x1a\n" +
|
||||
"\bendpoint\x18\x02 \x01(\tR\bendpoint\x12:\n" +
|
||||
"\tproviders\x18\x03 \x03(\v2\x1c.daemon.AgentNetworkProviderR\tproviders\"\xae\x01\n" +
|
||||
"\x14AgentNetworkProvider\x12\x12\n" +
|
||||
"\x04name\x18\x01 \x01(\tR\x04name\x12\x1d\n" +
|
||||
"\n" +
|
||||
"catalog_id\x18\x02 \x01(\tR\tcatalogId\x12\x1d\n" +
|
||||
"\n" +
|
||||
"api_flavor\x18\x03 \x01(\tR\tapiFlavor\x12,\n" +
|
||||
"\x12all_models_allowed\x18\x04 \x01(\bR\x10allModelsAllowed\x12\x16\n" +
|
||||
"\x06models\x18\x05 \x03(\tR\x06models*b\n" +
|
||||
"\bLogLevel\x12\v\n" +
|
||||
"\aUNKNOWN\x10\x00\x12\t\n" +
|
||||
"\x05PANIC\x10\x01\x12\t\n" +
|
||||
@@ -7595,7 +7794,7 @@ const file_daemon_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"EXPOSE_UDP\x10\x03\x12\x0e\n" +
|
||||
"\n" +
|
||||
"EXPOSE_TLS\x10\x042\xa3\x1c\n" +
|
||||
"EXPOSE_TLS\x10\x042\x88\x1d\n" +
|
||||
"\rDaemonService\x126\n" +
|
||||
"\x05Login\x12\x14.daemon.LoginRequest\x1a\x15.daemon.LoginResponse\"\x00\x12K\n" +
|
||||
"\fWaitSSOLogin\x12\x1b.daemon.WaitSSOLoginRequest\x1a\x1c.daemon.WaitSSOLoginResponse\"\x00\x12-\n" +
|
||||
@@ -7645,7 +7844,8 @@ const file_daemon_proto_rawDesc = "" +
|
||||
"\x0eStopCPUProfile\x12\x1d.daemon.StopCPUProfileRequest\x1a\x1e.daemon.StopCPUProfileResponse\"\x00\x12W\n" +
|
||||
"\x12GetInstallerResult\x12\x1e.daemon.InstallerResultRequest\x1a\x1f.daemon.InstallerResultResponse\"\x00\x12M\n" +
|
||||
"\rExposeService\x12\x1c.daemon.ExposeServiceRequest\x1a\x1a.daemon.ExposeServiceEvent\"\x000\x01\x12K\n" +
|
||||
"\fWailsUIReady\x12\x1b.daemon.WailsUIReadyRequest\x1a\x1c.daemon.WailsUIReadyResponse\"\x00B\bZ\x06/protob\x06proto3"
|
||||
"\fWailsUIReady\x12\x1b.daemon.WailsUIReadyRequest\x1a\x1c.daemon.WailsUIReadyResponse\"\x00\x12c\n" +
|
||||
"\x14GetAgentNetworkSetup\x12#.daemon.GetAgentNetworkSetupRequest\x1a$.daemon.GetAgentNetworkSetupResponse\"\x00B\bZ\x06/protob\x06proto3"
|
||||
|
||||
var (
|
||||
file_daemon_proto_rawDescOnce sync.Once
|
||||
@@ -7660,7 +7860,7 @@ func file_daemon_proto_rawDescGZIP() []byte {
|
||||
}
|
||||
|
||||
var file_daemon_proto_enumTypes = make([]protoimpl.EnumInfo, 4)
|
||||
var file_daemon_proto_msgTypes = make([]protoimpl.MessageInfo, 110)
|
||||
var file_daemon_proto_msgTypes = make([]protoimpl.MessageInfo, 113)
|
||||
var file_daemon_proto_goTypes = []any{
|
||||
(LogLevel)(0), // 0: daemon.LogLevel
|
||||
(ExposeProtocol)(0), // 1: daemon.ExposeProtocol
|
||||
@@ -7773,19 +7973,22 @@ var file_daemon_proto_goTypes = []any{
|
||||
(*StartBundleCaptureResponse)(nil), // 108: daemon.StartBundleCaptureResponse
|
||||
(*StopBundleCaptureRequest)(nil), // 109: daemon.StopBundleCaptureRequest
|
||||
(*StopBundleCaptureResponse)(nil), // 110: daemon.StopBundleCaptureResponse
|
||||
nil, // 111: daemon.Network.ResolvedIPsEntry
|
||||
(*PortInfo_Range)(nil), // 112: daemon.PortInfo.Range
|
||||
nil, // 113: daemon.SystemEvent.MetadataEntry
|
||||
(*durationpb.Duration)(nil), // 114: google.protobuf.Duration
|
||||
(*timestamppb.Timestamp)(nil), // 115: google.protobuf.Timestamp
|
||||
(*GetAgentNetworkSetupRequest)(nil), // 111: daemon.GetAgentNetworkSetupRequest
|
||||
(*GetAgentNetworkSetupResponse)(nil), // 112: daemon.GetAgentNetworkSetupResponse
|
||||
(*AgentNetworkProvider)(nil), // 113: daemon.AgentNetworkProvider
|
||||
nil, // 114: daemon.Network.ResolvedIPsEntry
|
||||
(*PortInfo_Range)(nil), // 115: daemon.PortInfo.Range
|
||||
nil, // 116: daemon.SystemEvent.MetadataEntry
|
||||
(*durationpb.Duration)(nil), // 117: google.protobuf.Duration
|
||||
(*timestamppb.Timestamp)(nil), // 118: google.protobuf.Timestamp
|
||||
}
|
||||
var file_daemon_proto_depIdxs = []int32{
|
||||
114, // 0: daemon.LoginRequest.dnsRouteInterval:type_name -> google.protobuf.Duration
|
||||
117, // 0: daemon.LoginRequest.dnsRouteInterval:type_name -> google.protobuf.Duration
|
||||
25, // 1: daemon.StatusResponse.fullStatus:type_name -> daemon.FullStatus
|
||||
115, // 2: daemon.StatusResponse.sessionExpiresAt:type_name -> google.protobuf.Timestamp
|
||||
115, // 3: daemon.PeerState.connStatusUpdate:type_name -> google.protobuf.Timestamp
|
||||
115, // 4: daemon.PeerState.lastWireguardHandshake:type_name -> google.protobuf.Timestamp
|
||||
114, // 5: daemon.PeerState.latency:type_name -> google.protobuf.Duration
|
||||
118, // 2: daemon.StatusResponse.sessionExpiresAt:type_name -> google.protobuf.Timestamp
|
||||
118, // 3: daemon.PeerState.connStatusUpdate:type_name -> google.protobuf.Timestamp
|
||||
118, // 4: daemon.PeerState.lastWireguardHandshake:type_name -> google.protobuf.Timestamp
|
||||
117, // 5: daemon.PeerState.latency:type_name -> google.protobuf.Duration
|
||||
23, // 6: daemon.SSHServerState.sessions:type_name -> daemon.SSHSessionInfo
|
||||
20, // 7: daemon.FullStatus.managementState:type_name -> daemon.ManagementState
|
||||
19, // 8: daemon.FullStatus.signalState:type_name -> daemon.SignalState
|
||||
@@ -7796,8 +7999,8 @@ var file_daemon_proto_depIdxs = []int32{
|
||||
57, // 13: daemon.FullStatus.events:type_name -> daemon.SystemEvent
|
||||
24, // 14: daemon.FullStatus.sshServerState:type_name -> daemon.SSHServerState
|
||||
31, // 15: daemon.ListNetworksResponse.routes:type_name -> daemon.Network
|
||||
111, // 16: daemon.Network.resolvedIPs:type_name -> daemon.Network.ResolvedIPsEntry
|
||||
112, // 17: daemon.PortInfo.range:type_name -> daemon.PortInfo.Range
|
||||
114, // 16: daemon.Network.resolvedIPs:type_name -> daemon.Network.ResolvedIPsEntry
|
||||
115, // 17: daemon.PortInfo.range:type_name -> daemon.PortInfo.Range
|
||||
32, // 18: daemon.ForwardingRule.destinationPort:type_name -> daemon.PortInfo
|
||||
32, // 19: daemon.ForwardingRule.translatedPort:type_name -> daemon.PortInfo
|
||||
33, // 20: daemon.ForwardingRulesResponse.rules:type_name -> daemon.ForwardingRule
|
||||
@@ -7808,114 +8011,117 @@ var file_daemon_proto_depIdxs = []int32{
|
||||
54, // 25: daemon.TracePacketResponse.stages:type_name -> daemon.TraceStage
|
||||
2, // 26: daemon.SystemEvent.severity:type_name -> daemon.SystemEvent.Severity
|
||||
3, // 27: daemon.SystemEvent.category:type_name -> daemon.SystemEvent.Category
|
||||
115, // 28: daemon.SystemEvent.timestamp:type_name -> google.protobuf.Timestamp
|
||||
113, // 29: daemon.SystemEvent.metadata:type_name -> daemon.SystemEvent.MetadataEntry
|
||||
118, // 28: daemon.SystemEvent.timestamp:type_name -> google.protobuf.Timestamp
|
||||
116, // 29: daemon.SystemEvent.metadata:type_name -> daemon.SystemEvent.MetadataEntry
|
||||
57, // 30: daemon.GetEventsResponse.events:type_name -> daemon.SystemEvent
|
||||
114, // 31: daemon.SetConfigRequest.dnsRouteInterval:type_name -> google.protobuf.Duration
|
||||
117, // 31: daemon.SetConfigRequest.dnsRouteInterval:type_name -> google.protobuf.Duration
|
||||
72, // 32: daemon.ListProfilesResponse.profiles:type_name -> daemon.Profile
|
||||
115, // 33: daemon.WaitExtendAuthSessionResponse.sessionExpiresAt:type_name -> google.protobuf.Timestamp
|
||||
118, // 33: daemon.WaitExtendAuthSessionResponse.sessionExpiresAt:type_name -> google.protobuf.Timestamp
|
||||
1, // 34: daemon.ExposeServiceRequest.protocol:type_name -> daemon.ExposeProtocol
|
||||
104, // 35: daemon.ExposeServiceEvent.ready:type_name -> daemon.ExposeServiceReady
|
||||
114, // 36: daemon.StartCaptureRequest.duration:type_name -> google.protobuf.Duration
|
||||
114, // 37: daemon.StartBundleCaptureRequest.timeout:type_name -> google.protobuf.Duration
|
||||
30, // 38: daemon.Network.ResolvedIPsEntry.value:type_name -> daemon.IPList
|
||||
5, // 39: daemon.DaemonService.Login:input_type -> daemon.LoginRequest
|
||||
7, // 40: daemon.DaemonService.WaitSSOLogin:input_type -> daemon.WaitSSOLoginRequest
|
||||
9, // 41: daemon.DaemonService.Up:input_type -> daemon.UpRequest
|
||||
11, // 42: daemon.DaemonService.Status:input_type -> daemon.StatusRequest
|
||||
11, // 43: daemon.DaemonService.SubscribeStatus:input_type -> daemon.StatusRequest
|
||||
13, // 44: daemon.DaemonService.Down:input_type -> daemon.DownRequest
|
||||
15, // 45: daemon.DaemonService.GetConfig:input_type -> daemon.GetConfigRequest
|
||||
26, // 46: daemon.DaemonService.ListNetworks:input_type -> daemon.ListNetworksRequest
|
||||
28, // 47: daemon.DaemonService.SelectNetworks:input_type -> daemon.SelectNetworksRequest
|
||||
28, // 48: daemon.DaemonService.DeselectNetworks:input_type -> daemon.SelectNetworksRequest
|
||||
4, // 49: daemon.DaemonService.ForwardingRules:input_type -> daemon.EmptyRequest
|
||||
35, // 50: daemon.DaemonService.DebugBundle:input_type -> daemon.DebugBundleRequest
|
||||
37, // 51: daemon.DaemonService.GetLogLevel:input_type -> daemon.GetLogLevelRequest
|
||||
39, // 52: daemon.DaemonService.SetLogLevel:input_type -> daemon.SetLogLevelRequest
|
||||
44, // 53: daemon.DaemonService.ListStates:input_type -> daemon.ListStatesRequest
|
||||
46, // 54: daemon.DaemonService.CleanState:input_type -> daemon.CleanStateRequest
|
||||
48, // 55: daemon.DaemonService.DeleteState:input_type -> daemon.DeleteStateRequest
|
||||
50, // 56: daemon.DaemonService.SetSyncResponsePersistence:input_type -> daemon.SetSyncResponsePersistenceRequest
|
||||
53, // 57: daemon.DaemonService.TracePacket:input_type -> daemon.TracePacketRequest
|
||||
105, // 58: daemon.DaemonService.StartCapture:input_type -> daemon.StartCaptureRequest
|
||||
107, // 59: daemon.DaemonService.StartBundleCapture:input_type -> daemon.StartBundleCaptureRequest
|
||||
109, // 60: daemon.DaemonService.StopBundleCapture:input_type -> daemon.StopBundleCaptureRequest
|
||||
56, // 61: daemon.DaemonService.SubscribeEvents:input_type -> daemon.SubscribeRequest
|
||||
58, // 62: daemon.DaemonService.GetEvents:input_type -> daemon.GetEventsRequest
|
||||
41, // 63: daemon.DaemonService.RegisterUILog:input_type -> daemon.RegisterUILogRequest
|
||||
60, // 64: daemon.DaemonService.SwitchProfile:input_type -> daemon.SwitchProfileRequest
|
||||
62, // 65: daemon.DaemonService.SetConfig:input_type -> daemon.SetConfigRequest
|
||||
64, // 66: daemon.DaemonService.AddProfile:input_type -> daemon.AddProfileRequest
|
||||
66, // 67: daemon.DaemonService.RenameProfile:input_type -> daemon.RenameProfileRequest
|
||||
68, // 68: daemon.DaemonService.RemoveProfile:input_type -> daemon.RemoveProfileRequest
|
||||
70, // 69: daemon.DaemonService.ListProfiles:input_type -> daemon.ListProfilesRequest
|
||||
73, // 70: daemon.DaemonService.GetActiveProfile:input_type -> daemon.GetActiveProfileRequest
|
||||
75, // 71: daemon.DaemonService.Logout:input_type -> daemon.LogoutRequest
|
||||
79, // 72: daemon.DaemonService.GetFeatures:input_type -> daemon.GetFeaturesRequest
|
||||
82, // 73: daemon.DaemonService.TriggerUpdate:input_type -> daemon.TriggerUpdateRequest
|
||||
84, // 74: daemon.DaemonService.GetPeerSSHHostKey:input_type -> daemon.GetPeerSSHHostKeyRequest
|
||||
86, // 75: daemon.DaemonService.RequestJWTAuth:input_type -> daemon.RequestJWTAuthRequest
|
||||
88, // 76: daemon.DaemonService.WaitJWTToken:input_type -> daemon.WaitJWTTokenRequest
|
||||
90, // 77: daemon.DaemonService.RequestExtendAuthSession:input_type -> daemon.RequestExtendAuthSessionRequest
|
||||
92, // 78: daemon.DaemonService.WaitExtendAuthSession:input_type -> daemon.WaitExtendAuthSessionRequest
|
||||
94, // 79: daemon.DaemonService.DismissSessionWarning:input_type -> daemon.DismissSessionWarningRequest
|
||||
96, // 80: daemon.DaemonService.StartCPUProfile:input_type -> daemon.StartCPUProfileRequest
|
||||
98, // 81: daemon.DaemonService.StopCPUProfile:input_type -> daemon.StopCPUProfileRequest
|
||||
100, // 82: daemon.DaemonService.GetInstallerResult:input_type -> daemon.InstallerResultRequest
|
||||
102, // 83: daemon.DaemonService.ExposeService:input_type -> daemon.ExposeServiceRequest
|
||||
77, // 84: daemon.DaemonService.WailsUIReady:input_type -> daemon.WailsUIReadyRequest
|
||||
6, // 85: daemon.DaemonService.Login:output_type -> daemon.LoginResponse
|
||||
8, // 86: daemon.DaemonService.WaitSSOLogin:output_type -> daemon.WaitSSOLoginResponse
|
||||
10, // 87: daemon.DaemonService.Up:output_type -> daemon.UpResponse
|
||||
12, // 88: daemon.DaemonService.Status:output_type -> daemon.StatusResponse
|
||||
12, // 89: daemon.DaemonService.SubscribeStatus:output_type -> daemon.StatusResponse
|
||||
14, // 90: daemon.DaemonService.Down:output_type -> daemon.DownResponse
|
||||
16, // 91: daemon.DaemonService.GetConfig:output_type -> daemon.GetConfigResponse
|
||||
27, // 92: daemon.DaemonService.ListNetworks:output_type -> daemon.ListNetworksResponse
|
||||
29, // 93: daemon.DaemonService.SelectNetworks:output_type -> daemon.SelectNetworksResponse
|
||||
29, // 94: daemon.DaemonService.DeselectNetworks:output_type -> daemon.SelectNetworksResponse
|
||||
34, // 95: daemon.DaemonService.ForwardingRules:output_type -> daemon.ForwardingRulesResponse
|
||||
36, // 96: daemon.DaemonService.DebugBundle:output_type -> daemon.DebugBundleResponse
|
||||
38, // 97: daemon.DaemonService.GetLogLevel:output_type -> daemon.GetLogLevelResponse
|
||||
40, // 98: daemon.DaemonService.SetLogLevel:output_type -> daemon.SetLogLevelResponse
|
||||
45, // 99: daemon.DaemonService.ListStates:output_type -> daemon.ListStatesResponse
|
||||
47, // 100: daemon.DaemonService.CleanState:output_type -> daemon.CleanStateResponse
|
||||
49, // 101: daemon.DaemonService.DeleteState:output_type -> daemon.DeleteStateResponse
|
||||
51, // 102: daemon.DaemonService.SetSyncResponsePersistence:output_type -> daemon.SetSyncResponsePersistenceResponse
|
||||
55, // 103: daemon.DaemonService.TracePacket:output_type -> daemon.TracePacketResponse
|
||||
106, // 104: daemon.DaemonService.StartCapture:output_type -> daemon.CapturePacket
|
||||
108, // 105: daemon.DaemonService.StartBundleCapture:output_type -> daemon.StartBundleCaptureResponse
|
||||
110, // 106: daemon.DaemonService.StopBundleCapture:output_type -> daemon.StopBundleCaptureResponse
|
||||
57, // 107: daemon.DaemonService.SubscribeEvents:output_type -> daemon.SystemEvent
|
||||
59, // 108: daemon.DaemonService.GetEvents:output_type -> daemon.GetEventsResponse
|
||||
42, // 109: daemon.DaemonService.RegisterUILog:output_type -> daemon.RegisterUILogResponse
|
||||
61, // 110: daemon.DaemonService.SwitchProfile:output_type -> daemon.SwitchProfileResponse
|
||||
63, // 111: daemon.DaemonService.SetConfig:output_type -> daemon.SetConfigResponse
|
||||
65, // 112: daemon.DaemonService.AddProfile:output_type -> daemon.AddProfileResponse
|
||||
67, // 113: daemon.DaemonService.RenameProfile:output_type -> daemon.RenameProfileResponse
|
||||
69, // 114: daemon.DaemonService.RemoveProfile:output_type -> daemon.RemoveProfileResponse
|
||||
71, // 115: daemon.DaemonService.ListProfiles:output_type -> daemon.ListProfilesResponse
|
||||
74, // 116: daemon.DaemonService.GetActiveProfile:output_type -> daemon.GetActiveProfileResponse
|
||||
76, // 117: daemon.DaemonService.Logout:output_type -> daemon.LogoutResponse
|
||||
80, // 118: daemon.DaemonService.GetFeatures:output_type -> daemon.GetFeaturesResponse
|
||||
83, // 119: daemon.DaemonService.TriggerUpdate:output_type -> daemon.TriggerUpdateResponse
|
||||
85, // 120: daemon.DaemonService.GetPeerSSHHostKey:output_type -> daemon.GetPeerSSHHostKeyResponse
|
||||
87, // 121: daemon.DaemonService.RequestJWTAuth:output_type -> daemon.RequestJWTAuthResponse
|
||||
89, // 122: daemon.DaemonService.WaitJWTToken:output_type -> daemon.WaitJWTTokenResponse
|
||||
91, // 123: daemon.DaemonService.RequestExtendAuthSession:output_type -> daemon.RequestExtendAuthSessionResponse
|
||||
93, // 124: daemon.DaemonService.WaitExtendAuthSession:output_type -> daemon.WaitExtendAuthSessionResponse
|
||||
95, // 125: daemon.DaemonService.DismissSessionWarning:output_type -> daemon.DismissSessionWarningResponse
|
||||
97, // 126: daemon.DaemonService.StartCPUProfile:output_type -> daemon.StartCPUProfileResponse
|
||||
99, // 127: daemon.DaemonService.StopCPUProfile:output_type -> daemon.StopCPUProfileResponse
|
||||
101, // 128: daemon.DaemonService.GetInstallerResult:output_type -> daemon.InstallerResultResponse
|
||||
103, // 129: daemon.DaemonService.ExposeService:output_type -> daemon.ExposeServiceEvent
|
||||
78, // 130: daemon.DaemonService.WailsUIReady:output_type -> daemon.WailsUIReadyResponse
|
||||
85, // [85:131] is the sub-list for method output_type
|
||||
39, // [39:85] is the sub-list for method input_type
|
||||
39, // [39:39] is the sub-list for extension type_name
|
||||
39, // [39:39] is the sub-list for extension extendee
|
||||
0, // [0:39] is the sub-list for field type_name
|
||||
117, // 36: daemon.StartCaptureRequest.duration:type_name -> google.protobuf.Duration
|
||||
117, // 37: daemon.StartBundleCaptureRequest.timeout:type_name -> google.protobuf.Duration
|
||||
113, // 38: daemon.GetAgentNetworkSetupResponse.providers:type_name -> daemon.AgentNetworkProvider
|
||||
30, // 39: daemon.Network.ResolvedIPsEntry.value:type_name -> daemon.IPList
|
||||
5, // 40: daemon.DaemonService.Login:input_type -> daemon.LoginRequest
|
||||
7, // 41: daemon.DaemonService.WaitSSOLogin:input_type -> daemon.WaitSSOLoginRequest
|
||||
9, // 42: daemon.DaemonService.Up:input_type -> daemon.UpRequest
|
||||
11, // 43: daemon.DaemonService.Status:input_type -> daemon.StatusRequest
|
||||
11, // 44: daemon.DaemonService.SubscribeStatus:input_type -> daemon.StatusRequest
|
||||
13, // 45: daemon.DaemonService.Down:input_type -> daemon.DownRequest
|
||||
15, // 46: daemon.DaemonService.GetConfig:input_type -> daemon.GetConfigRequest
|
||||
26, // 47: daemon.DaemonService.ListNetworks:input_type -> daemon.ListNetworksRequest
|
||||
28, // 48: daemon.DaemonService.SelectNetworks:input_type -> daemon.SelectNetworksRequest
|
||||
28, // 49: daemon.DaemonService.DeselectNetworks:input_type -> daemon.SelectNetworksRequest
|
||||
4, // 50: daemon.DaemonService.ForwardingRules:input_type -> daemon.EmptyRequest
|
||||
35, // 51: daemon.DaemonService.DebugBundle:input_type -> daemon.DebugBundleRequest
|
||||
37, // 52: daemon.DaemonService.GetLogLevel:input_type -> daemon.GetLogLevelRequest
|
||||
39, // 53: daemon.DaemonService.SetLogLevel:input_type -> daemon.SetLogLevelRequest
|
||||
44, // 54: daemon.DaemonService.ListStates:input_type -> daemon.ListStatesRequest
|
||||
46, // 55: daemon.DaemonService.CleanState:input_type -> daemon.CleanStateRequest
|
||||
48, // 56: daemon.DaemonService.DeleteState:input_type -> daemon.DeleteStateRequest
|
||||
50, // 57: daemon.DaemonService.SetSyncResponsePersistence:input_type -> daemon.SetSyncResponsePersistenceRequest
|
||||
53, // 58: daemon.DaemonService.TracePacket:input_type -> daemon.TracePacketRequest
|
||||
105, // 59: daemon.DaemonService.StartCapture:input_type -> daemon.StartCaptureRequest
|
||||
107, // 60: daemon.DaemonService.StartBundleCapture:input_type -> daemon.StartBundleCaptureRequest
|
||||
109, // 61: daemon.DaemonService.StopBundleCapture:input_type -> daemon.StopBundleCaptureRequest
|
||||
56, // 62: daemon.DaemonService.SubscribeEvents:input_type -> daemon.SubscribeRequest
|
||||
58, // 63: daemon.DaemonService.GetEvents:input_type -> daemon.GetEventsRequest
|
||||
41, // 64: daemon.DaemonService.RegisterUILog:input_type -> daemon.RegisterUILogRequest
|
||||
60, // 65: daemon.DaemonService.SwitchProfile:input_type -> daemon.SwitchProfileRequest
|
||||
62, // 66: daemon.DaemonService.SetConfig:input_type -> daemon.SetConfigRequest
|
||||
64, // 67: daemon.DaemonService.AddProfile:input_type -> daemon.AddProfileRequest
|
||||
66, // 68: daemon.DaemonService.RenameProfile:input_type -> daemon.RenameProfileRequest
|
||||
68, // 69: daemon.DaemonService.RemoveProfile:input_type -> daemon.RemoveProfileRequest
|
||||
70, // 70: daemon.DaemonService.ListProfiles:input_type -> daemon.ListProfilesRequest
|
||||
73, // 71: daemon.DaemonService.GetActiveProfile:input_type -> daemon.GetActiveProfileRequest
|
||||
75, // 72: daemon.DaemonService.Logout:input_type -> daemon.LogoutRequest
|
||||
79, // 73: daemon.DaemonService.GetFeatures:input_type -> daemon.GetFeaturesRequest
|
||||
82, // 74: daemon.DaemonService.TriggerUpdate:input_type -> daemon.TriggerUpdateRequest
|
||||
84, // 75: daemon.DaemonService.GetPeerSSHHostKey:input_type -> daemon.GetPeerSSHHostKeyRequest
|
||||
86, // 76: daemon.DaemonService.RequestJWTAuth:input_type -> daemon.RequestJWTAuthRequest
|
||||
88, // 77: daemon.DaemonService.WaitJWTToken:input_type -> daemon.WaitJWTTokenRequest
|
||||
90, // 78: daemon.DaemonService.RequestExtendAuthSession:input_type -> daemon.RequestExtendAuthSessionRequest
|
||||
92, // 79: daemon.DaemonService.WaitExtendAuthSession:input_type -> daemon.WaitExtendAuthSessionRequest
|
||||
94, // 80: daemon.DaemonService.DismissSessionWarning:input_type -> daemon.DismissSessionWarningRequest
|
||||
96, // 81: daemon.DaemonService.StartCPUProfile:input_type -> daemon.StartCPUProfileRequest
|
||||
98, // 82: daemon.DaemonService.StopCPUProfile:input_type -> daemon.StopCPUProfileRequest
|
||||
100, // 83: daemon.DaemonService.GetInstallerResult:input_type -> daemon.InstallerResultRequest
|
||||
102, // 84: daemon.DaemonService.ExposeService:input_type -> daemon.ExposeServiceRequest
|
||||
77, // 85: daemon.DaemonService.WailsUIReady:input_type -> daemon.WailsUIReadyRequest
|
||||
111, // 86: daemon.DaemonService.GetAgentNetworkSetup:input_type -> daemon.GetAgentNetworkSetupRequest
|
||||
6, // 87: daemon.DaemonService.Login:output_type -> daemon.LoginResponse
|
||||
8, // 88: daemon.DaemonService.WaitSSOLogin:output_type -> daemon.WaitSSOLoginResponse
|
||||
10, // 89: daemon.DaemonService.Up:output_type -> daemon.UpResponse
|
||||
12, // 90: daemon.DaemonService.Status:output_type -> daemon.StatusResponse
|
||||
12, // 91: daemon.DaemonService.SubscribeStatus:output_type -> daemon.StatusResponse
|
||||
14, // 92: daemon.DaemonService.Down:output_type -> daemon.DownResponse
|
||||
16, // 93: daemon.DaemonService.GetConfig:output_type -> daemon.GetConfigResponse
|
||||
27, // 94: daemon.DaemonService.ListNetworks:output_type -> daemon.ListNetworksResponse
|
||||
29, // 95: daemon.DaemonService.SelectNetworks:output_type -> daemon.SelectNetworksResponse
|
||||
29, // 96: daemon.DaemonService.DeselectNetworks:output_type -> daemon.SelectNetworksResponse
|
||||
34, // 97: daemon.DaemonService.ForwardingRules:output_type -> daemon.ForwardingRulesResponse
|
||||
36, // 98: daemon.DaemonService.DebugBundle:output_type -> daemon.DebugBundleResponse
|
||||
38, // 99: daemon.DaemonService.GetLogLevel:output_type -> daemon.GetLogLevelResponse
|
||||
40, // 100: daemon.DaemonService.SetLogLevel:output_type -> daemon.SetLogLevelResponse
|
||||
45, // 101: daemon.DaemonService.ListStates:output_type -> daemon.ListStatesResponse
|
||||
47, // 102: daemon.DaemonService.CleanState:output_type -> daemon.CleanStateResponse
|
||||
49, // 103: daemon.DaemonService.DeleteState:output_type -> daemon.DeleteStateResponse
|
||||
51, // 104: daemon.DaemonService.SetSyncResponsePersistence:output_type -> daemon.SetSyncResponsePersistenceResponse
|
||||
55, // 105: daemon.DaemonService.TracePacket:output_type -> daemon.TracePacketResponse
|
||||
106, // 106: daemon.DaemonService.StartCapture:output_type -> daemon.CapturePacket
|
||||
108, // 107: daemon.DaemonService.StartBundleCapture:output_type -> daemon.StartBundleCaptureResponse
|
||||
110, // 108: daemon.DaemonService.StopBundleCapture:output_type -> daemon.StopBundleCaptureResponse
|
||||
57, // 109: daemon.DaemonService.SubscribeEvents:output_type -> daemon.SystemEvent
|
||||
59, // 110: daemon.DaemonService.GetEvents:output_type -> daemon.GetEventsResponse
|
||||
42, // 111: daemon.DaemonService.RegisterUILog:output_type -> daemon.RegisterUILogResponse
|
||||
61, // 112: daemon.DaemonService.SwitchProfile:output_type -> daemon.SwitchProfileResponse
|
||||
63, // 113: daemon.DaemonService.SetConfig:output_type -> daemon.SetConfigResponse
|
||||
65, // 114: daemon.DaemonService.AddProfile:output_type -> daemon.AddProfileResponse
|
||||
67, // 115: daemon.DaemonService.RenameProfile:output_type -> daemon.RenameProfileResponse
|
||||
69, // 116: daemon.DaemonService.RemoveProfile:output_type -> daemon.RemoveProfileResponse
|
||||
71, // 117: daemon.DaemonService.ListProfiles:output_type -> daemon.ListProfilesResponse
|
||||
74, // 118: daemon.DaemonService.GetActiveProfile:output_type -> daemon.GetActiveProfileResponse
|
||||
76, // 119: daemon.DaemonService.Logout:output_type -> daemon.LogoutResponse
|
||||
80, // 120: daemon.DaemonService.GetFeatures:output_type -> daemon.GetFeaturesResponse
|
||||
83, // 121: daemon.DaemonService.TriggerUpdate:output_type -> daemon.TriggerUpdateResponse
|
||||
85, // 122: daemon.DaemonService.GetPeerSSHHostKey:output_type -> daemon.GetPeerSSHHostKeyResponse
|
||||
87, // 123: daemon.DaemonService.RequestJWTAuth:output_type -> daemon.RequestJWTAuthResponse
|
||||
89, // 124: daemon.DaemonService.WaitJWTToken:output_type -> daemon.WaitJWTTokenResponse
|
||||
91, // 125: daemon.DaemonService.RequestExtendAuthSession:output_type -> daemon.RequestExtendAuthSessionResponse
|
||||
93, // 126: daemon.DaemonService.WaitExtendAuthSession:output_type -> daemon.WaitExtendAuthSessionResponse
|
||||
95, // 127: daemon.DaemonService.DismissSessionWarning:output_type -> daemon.DismissSessionWarningResponse
|
||||
97, // 128: daemon.DaemonService.StartCPUProfile:output_type -> daemon.StartCPUProfileResponse
|
||||
99, // 129: daemon.DaemonService.StopCPUProfile:output_type -> daemon.StopCPUProfileResponse
|
||||
101, // 130: daemon.DaemonService.GetInstallerResult:output_type -> daemon.InstallerResultResponse
|
||||
103, // 131: daemon.DaemonService.ExposeService:output_type -> daemon.ExposeServiceEvent
|
||||
78, // 132: daemon.DaemonService.WailsUIReady:output_type -> daemon.WailsUIReadyResponse
|
||||
112, // 133: daemon.DaemonService.GetAgentNetworkSetup:output_type -> daemon.GetAgentNetworkSetupResponse
|
||||
87, // [87:134] is the sub-list for method output_type
|
||||
40, // [40:87] is the sub-list for method input_type
|
||||
40, // [40:40] is the sub-list for extension type_name
|
||||
40, // [40:40] is the sub-list for extension extendee
|
||||
0, // [0:40] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_daemon_proto_init() }
|
||||
@@ -7947,7 +8153,7 @@ func file_daemon_proto_init() {
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_daemon_proto_rawDesc), len(file_daemon_proto_rawDesc)),
|
||||
NumEnums: 4,
|
||||
NumMessages: 110,
|
||||
NumMessages: 113,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
|
||||
@@ -1123,6 +1123,30 @@ func local_request_DaemonService_WailsUIReady_0(ctx context.Context, marshaler r
|
||||
return msg, metadata, err
|
||||
}
|
||||
|
||||
func request_DaemonService_GetAgentNetworkSetup_0(ctx context.Context, marshaler runtime.Marshaler, client DaemonServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var (
|
||||
protoReq GetAgentNetworkSetupRequest
|
||||
metadata runtime.ServerMetadata
|
||||
)
|
||||
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
msg, err := client.GetAgentNetworkSetup(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
}
|
||||
|
||||
func local_request_DaemonService_GetAgentNetworkSetup_0(ctx context.Context, marshaler runtime.Marshaler, server DaemonServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var (
|
||||
protoReq GetAgentNetworkSetupRequest
|
||||
metadata runtime.ServerMetadata
|
||||
)
|
||||
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
msg, err := server.GetAgentNetworkSetup(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
}
|
||||
|
||||
// RegisterDaemonServiceHandlerServer registers the http handlers for service DaemonService to "mux".
|
||||
// UnaryRPC :call DaemonServiceServer directly.
|
||||
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
|
||||
@@ -1997,6 +2021,26 @@ func RegisterDaemonServiceHandlerServer(ctx context.Context, mux *runtime.ServeM
|
||||
}
|
||||
forward_DaemonService_WailsUIReady_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
})
|
||||
mux.Handle(http.MethodPost, pattern_DaemonService_GetAgentNetworkSetup_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
var stream runtime.ServerTransportStream
|
||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/daemon.DaemonService/GetAgentNetworkSetup", runtime.WithHTTPPathPattern("/daemon.DaemonService/GetAgentNetworkSetup"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_DaemonService_GetAgentNetworkSetup_0(annotatedContext, inboundMarshaler, server, req, pathParams)
|
||||
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
forward_DaemonService_GetAgentNetworkSetup_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -2819,6 +2863,23 @@ func RegisterDaemonServiceHandlerClient(ctx context.Context, mux *runtime.ServeM
|
||||
}
|
||||
forward_DaemonService_WailsUIReady_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
})
|
||||
mux.Handle(http.MethodPost, pattern_DaemonService_GetAgentNetworkSetup_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/daemon.DaemonService/GetAgentNetworkSetup", runtime.WithHTTPPathPattern("/daemon.DaemonService/GetAgentNetworkSetup"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_DaemonService_GetAgentNetworkSetup_0(annotatedContext, inboundMarshaler, client, req, pathParams)
|
||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
forward_DaemonService_GetAgentNetworkSetup_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -2869,6 +2930,7 @@ var (
|
||||
pattern_DaemonService_GetInstallerResult_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"daemon.DaemonService", "GetInstallerResult"}, ""))
|
||||
pattern_DaemonService_ExposeService_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"daemon.DaemonService", "ExposeService"}, ""))
|
||||
pattern_DaemonService_WailsUIReady_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"daemon.DaemonService", "WailsUIReady"}, ""))
|
||||
pattern_DaemonService_GetAgentNetworkSetup_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"daemon.DaemonService", "GetAgentNetworkSetup"}, ""))
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -2918,4 +2980,5 @@ var (
|
||||
forward_DaemonService_GetInstallerResult_0 = runtime.ForwardResponseMessage
|
||||
forward_DaemonService_ExposeService_0 = runtime.ForwardResponseStream
|
||||
forward_DaemonService_WailsUIReady_0 = runtime.ForwardResponseMessage
|
||||
forward_DaemonService_GetAgentNetworkSetup_0 = runtime.ForwardResponseMessage
|
||||
)
|
||||
|
||||
@@ -156,6 +156,12 @@ service DaemonService {
|
||||
// only cares whether the daemon implements it: an Unimplemented response
|
||||
// means the daemon predates this UI and is too old to drive it.
|
||||
rpc WailsUIReady(WailsUIReadyRequest) returns (WailsUIReadyResponse) {}
|
||||
|
||||
// GetAgentNetworkSetup returns the Agent Network connection info this
|
||||
// peer's groups authorize: proxy endpoint plus effective providers and
|
||||
// models. The daemon relays the request to management over its existing
|
||||
// peer connection, so unprivileged CLI callers get a caller-scoped answer.
|
||||
rpc GetAgentNetworkSetup(GetAgentNetworkSetupRequest) returns (GetAgentNetworkSetupResponse) {}
|
||||
}
|
||||
|
||||
|
||||
@@ -1050,3 +1056,31 @@ message StartBundleCaptureRequest {
|
||||
message StartBundleCaptureResponse {}
|
||||
message StopBundleCaptureRequest {}
|
||||
message StopBundleCaptureResponse {}
|
||||
|
||||
message GetAgentNetworkSetupRequest {}
|
||||
|
||||
message GetAgentNetworkSetupResponse {
|
||||
// configured is false when the account has no Agent Network set up or
|
||||
// this peer's groups authorize none of it.
|
||||
bool configured = 1;
|
||||
// endpoint is the account's proxy base URL, reachable over the NetBird
|
||||
// tunnel only. Empty when configured is false.
|
||||
string endpoint = 2;
|
||||
repeated AgentNetworkProvider providers = 3;
|
||||
}
|
||||
|
||||
message AgentNetworkProvider {
|
||||
// name is the operator-assigned provider label, e.g. "Bedrock prod".
|
||||
string name = 1;
|
||||
// catalog_id names the provider type, e.g. "anthropic_api", "bedrock_api".
|
||||
string catalog_id = 2;
|
||||
// api_flavor is the request-body shape the provider speaks ("anthropic",
|
||||
// "openai"); empty when the proxy dispatches it by URL path instead.
|
||||
string api_flavor = 3;
|
||||
// all_models_allowed is true when no model allowlist restricts this
|
||||
// provider for the caller.
|
||||
bool all_models_allowed = 4;
|
||||
// models is the effective model allowlist (or the declared/catalog models
|
||||
// when all_models_allowed is true).
|
||||
repeated string models = 5;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.6.1
|
||||
// - protoc v6.33.1
|
||||
// - protoc v7.34.1
|
||||
// source: daemon.proto
|
||||
|
||||
package proto
|
||||
@@ -65,6 +65,7 @@ const (
|
||||
DaemonService_GetInstallerResult_FullMethodName = "/daemon.DaemonService/GetInstallerResult"
|
||||
DaemonService_ExposeService_FullMethodName = "/daemon.DaemonService/ExposeService"
|
||||
DaemonService_WailsUIReady_FullMethodName = "/daemon.DaemonService/WailsUIReady"
|
||||
DaemonService_GetAgentNetworkSetup_FullMethodName = "/daemon.DaemonService/GetAgentNetworkSetup"
|
||||
)
|
||||
|
||||
// DaemonServiceClient is the client API for DaemonService service.
|
||||
@@ -171,6 +172,11 @@ type DaemonServiceClient interface {
|
||||
// only cares whether the daemon implements it: an Unimplemented response
|
||||
// means the daemon predates this UI and is too old to drive it.
|
||||
WailsUIReady(ctx context.Context, in *WailsUIReadyRequest, opts ...grpc.CallOption) (*WailsUIReadyResponse, error)
|
||||
// GetAgentNetworkSetup returns the Agent Network connection info this
|
||||
// peer's groups authorize: proxy endpoint plus effective providers and
|
||||
// models. The daemon relays the request to management over its existing
|
||||
// peer connection, so unprivileged CLI callers get a caller-scoped answer.
|
||||
GetAgentNetworkSetup(ctx context.Context, in *GetAgentNetworkSetupRequest, opts ...grpc.CallOption) (*GetAgentNetworkSetupResponse, error)
|
||||
}
|
||||
|
||||
type daemonServiceClient struct {
|
||||
@@ -677,6 +683,16 @@ func (c *daemonServiceClient) WailsUIReady(ctx context.Context, in *WailsUIReady
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *daemonServiceClient) GetAgentNetworkSetup(ctx context.Context, in *GetAgentNetworkSetupRequest, opts ...grpc.CallOption) (*GetAgentNetworkSetupResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(GetAgentNetworkSetupResponse)
|
||||
err := c.cc.Invoke(ctx, DaemonService_GetAgentNetworkSetup_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// DaemonServiceServer is the server API for DaemonService service.
|
||||
// All implementations must embed UnimplementedDaemonServiceServer
|
||||
// for forward compatibility.
|
||||
@@ -781,6 +797,11 @@ type DaemonServiceServer interface {
|
||||
// only cares whether the daemon implements it: an Unimplemented response
|
||||
// means the daemon predates this UI and is too old to drive it.
|
||||
WailsUIReady(context.Context, *WailsUIReadyRequest) (*WailsUIReadyResponse, error)
|
||||
// GetAgentNetworkSetup returns the Agent Network connection info this
|
||||
// peer's groups authorize: proxy endpoint plus effective providers and
|
||||
// models. The daemon relays the request to management over its existing
|
||||
// peer connection, so unprivileged CLI callers get a caller-scoped answer.
|
||||
GetAgentNetworkSetup(context.Context, *GetAgentNetworkSetupRequest) (*GetAgentNetworkSetupResponse, error)
|
||||
mustEmbedUnimplementedDaemonServiceServer()
|
||||
}
|
||||
|
||||
@@ -929,6 +950,9 @@ func (UnimplementedDaemonServiceServer) ExposeService(*ExposeServiceRequest, grp
|
||||
func (UnimplementedDaemonServiceServer) WailsUIReady(context.Context, *WailsUIReadyRequest) (*WailsUIReadyResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method WailsUIReady not implemented")
|
||||
}
|
||||
func (UnimplementedDaemonServiceServer) GetAgentNetworkSetup(context.Context, *GetAgentNetworkSetupRequest) (*GetAgentNetworkSetupResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method GetAgentNetworkSetup not implemented")
|
||||
}
|
||||
func (UnimplementedDaemonServiceServer) mustEmbedUnimplementedDaemonServiceServer() {}
|
||||
func (UnimplementedDaemonServiceServer) testEmbeddedByValue() {}
|
||||
|
||||
@@ -1750,6 +1774,24 @@ func _DaemonService_WailsUIReady_Handler(srv interface{}, ctx context.Context, d
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _DaemonService_GetAgentNetworkSetup_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetAgentNetworkSetupRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(DaemonServiceServer).GetAgentNetworkSetup(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: DaemonService_GetAgentNetworkSetup_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(DaemonServiceServer).GetAgentNetworkSetup(ctx, req.(*GetAgentNetworkSetupRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// DaemonService_ServiceDesc is the grpc.ServiceDesc for DaemonService service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
@@ -1925,6 +1967,10 @@ var DaemonService_ServiceDesc = grpc.ServiceDesc{
|
||||
MethodName: "WailsUIReady",
|
||||
Handler: _DaemonService_WailsUIReady_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetAgentNetworkSetup",
|
||||
Handler: _DaemonService_GetAgentNetworkSetup_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{
|
||||
{
|
||||
|
||||
59
client/server/agentnetwork.go
Normal file
59
client/server/agentnetwork.go
Normal file
@@ -0,0 +1,59 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"google.golang.org/grpc/codes"
|
||||
gstatus "google.golang.org/grpc/status"
|
||||
|
||||
"github.com/netbirdio/netbird/client/proto"
|
||||
mgmProto "github.com/netbirdio/netbird/shared/management/proto"
|
||||
)
|
||||
|
||||
// GetAgentNetworkSetup relays the peer's Agent Network setup request to the
|
||||
// management server over the engine's existing connection. Running through
|
||||
// the daemon keeps the WireGuard key inside the daemon — unprivileged CLI
|
||||
// callers get a caller-scoped answer without reading the profile config.
|
||||
func (s *Server) GetAgentNetworkSetup(ctx context.Context, _ *proto.GetAgentNetworkSetupRequest) (*proto.GetAgentNetworkSetupResponse, error) {
|
||||
s.mutex.Lock()
|
||||
clientRunning := s.clientRunning
|
||||
connectClient := s.connectClient
|
||||
s.mutex.Unlock()
|
||||
|
||||
if !clientRunning || connectClient == nil {
|
||||
return nil, gstatus.Errorf(codes.FailedPrecondition, "client is not running, run 'netbird up' first")
|
||||
}
|
||||
engine := connectClient.Engine()
|
||||
if engine == nil {
|
||||
return nil, gstatus.Errorf(codes.FailedPrecondition, "engine not initialized")
|
||||
}
|
||||
|
||||
setupCtx, cancel := context.WithTimeout(ctx, 30*time.Second)
|
||||
defer cancel()
|
||||
|
||||
setup, err := engine.GetAgentNetworkSetup(setupCtx)
|
||||
if err != nil {
|
||||
return nil, gstatus.Errorf(codes.Internal, "get agent network setup: %v", err)
|
||||
}
|
||||
|
||||
return toDaemonAgentNetworkSetup(setup), nil
|
||||
}
|
||||
|
||||
func toDaemonAgentNetworkSetup(setup *mgmProto.AgentNetworkSetupResponse) *proto.GetAgentNetworkSetupResponse {
|
||||
resp := &proto.GetAgentNetworkSetupResponse{
|
||||
Configured: setup.Configured,
|
||||
Endpoint: setup.Endpoint,
|
||||
Providers: make([]*proto.AgentNetworkProvider, 0, len(setup.Providers)),
|
||||
}
|
||||
for _, p := range setup.Providers {
|
||||
resp.Providers = append(resp.Providers, &proto.AgentNetworkProvider{
|
||||
Name: p.Name,
|
||||
CatalogId: p.CatalogId,
|
||||
ApiFlavor: p.ApiFlavor,
|
||||
AllModelsAllowed: p.AllModelsAllowed,
|
||||
Models: p.Models,
|
||||
})
|
||||
}
|
||||
return resp
|
||||
}
|
||||
@@ -82,6 +82,11 @@ type Manager interface {
|
||||
RecordAccountBudgetUsage(ctx context.Context, accountID, userID string, groupIDs []string, tokensIn, tokensOut int64, costUSD float64) error
|
||||
RecordUsage(ctx context.Context, in RecordUsageInput) error
|
||||
SelectPolicyForRequest(ctx context.Context, in PolicySelectionInput) (*PolicySelectionResult, error)
|
||||
|
||||
// GetSetupForPeer returns the Agent Network connection info the peer's
|
||||
// groups authorize (endpoint, providers, effective models). Caller-scoped
|
||||
// by design — no user permission gate; see the implementation.
|
||||
GetSetupForPeer(ctx context.Context, accountID, peerID string) (*types.EffectiveSetup, error)
|
||||
}
|
||||
|
||||
// PolicySelectionInput is the per-request selection envelope. The
|
||||
|
||||
240
management/internals/modules/agentnetwork/setup.go
Normal file
240
management/internals/modules/agentnetwork/setup.go
Normal file
@@ -0,0 +1,240 @@
|
||||
package agentnetwork
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
"github.com/netbirdio/netbird/management/internals/modules/agentnetwork/catalog"
|
||||
"github.com/netbirdio/netbird/management/internals/modules/agentnetwork/types"
|
||||
"github.com/netbirdio/netbird/management/server/store"
|
||||
)
|
||||
|
||||
// GetSetupForPeer returns the Agent Network setup the calling peer's
|
||||
// groups authorize. It deliberately performs no user-permission check:
|
||||
// peer RPCs carry no user identity — WireGuard key possession is the
|
||||
// credential (same trust model as SelectPolicyForRequest) — and the
|
||||
// result is caller-scoped, which is strictly tighter than any role gate.
|
||||
// Setup-key/machine peers (no user attached) are fully supported since
|
||||
// the computation runs on peer groups, which is what the proxy enforces.
|
||||
func (m *managerImpl) GetSetupForPeer(ctx context.Context, accountID, peerID string) (*types.EffectiveSetup, error) {
|
||||
groupIDs, err := m.store.GetPeerGroupIDs(ctx, store.LockingStrengthNone, accountID, peerID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get peer groups: %w", err)
|
||||
}
|
||||
return m.effectiveSetupForGroups(ctx, accountID, groupIDs)
|
||||
}
|
||||
|
||||
// effectiveSetupForGroups computes the effective Agent Network setup for
|
||||
// a set of caller groups: the account endpoint plus, per authorized
|
||||
// provider, the effective model set. It mirrors what the proxy enforces
|
||||
// at request time — the policy filter matches filterApplicablePolicies,
|
||||
// the model logic matches policyPermitsModel, and orphan providers
|
||||
// (enabled but referenced by no applicable policy) are omitted just like
|
||||
// the router synthesizer omits them — so the answer never advertises
|
||||
// anything the proxy would refuse.
|
||||
//
|
||||
// Every "nothing available" shape returns Configured=false rather than
|
||||
// an error, and "account not set up" is indistinguishable from "caller
|
||||
// has no access" by design: the response must not leak what exists for
|
||||
// others.
|
||||
func (m *managerImpl) effectiveSetupForGroups(ctx context.Context, accountID string, groupIDs []string) (*types.EffectiveSetup, error) {
|
||||
notConfigured := &types.EffectiveSetup{Providers: []types.EffectiveProvider{}}
|
||||
|
||||
settings, err := m.store.GetAgentNetworkSettings(ctx, store.LockingStrengthNone, accountID)
|
||||
switch {
|
||||
case err == nil:
|
||||
case isNotFound(err):
|
||||
return notConfigured, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("get agent network settings: %w", err)
|
||||
}
|
||||
if settings.Endpoint() == "" {
|
||||
return notConfigured, nil
|
||||
}
|
||||
|
||||
policies, err := m.store.GetAccountAgentNetworkPolicies(ctx, store.LockingStrengthNone, accountID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("list account policies: %w", err)
|
||||
}
|
||||
applicable := filterPoliciesByGroups(policies, groupIDs)
|
||||
if len(applicable) == 0 {
|
||||
return notConfigured, nil
|
||||
}
|
||||
|
||||
providers, err := m.store.GetAccountAgentNetworkProviders(ctx, store.LockingStrengthNone, accountID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("list account providers: %w", err)
|
||||
}
|
||||
|
||||
var guardrailsByID map[string]*types.Guardrail
|
||||
if anyPolicyHasGuardrails(applicable) {
|
||||
guardrailsByID, err = m.loadGuardrailsByID(ctx, accountID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
authorized := make([]*types.Provider, 0, len(providers))
|
||||
for _, p := range providers {
|
||||
if p == nil || !p.Enabled {
|
||||
continue
|
||||
}
|
||||
if len(policiesForProvider(applicable, p.ID)) == 0 {
|
||||
continue
|
||||
}
|
||||
authorized = append(authorized, p)
|
||||
}
|
||||
if len(authorized) == 0 {
|
||||
return notConfigured, nil
|
||||
}
|
||||
// created_at order, ID tiebreak — same deterministic order the router
|
||||
// synthesizer presents.
|
||||
sort.SliceStable(authorized, func(i, j int) bool {
|
||||
if !authorized[i].CreatedAt.Equal(authorized[j].CreatedAt) {
|
||||
return authorized[i].CreatedAt.Before(authorized[j].CreatedAt)
|
||||
}
|
||||
return authorized[i].ID < authorized[j].ID
|
||||
})
|
||||
|
||||
out := &types.EffectiveSetup{
|
||||
Configured: true,
|
||||
Endpoint: "https://" + settings.Endpoint(),
|
||||
Providers: make([]types.EffectiveProvider, 0, len(authorized)),
|
||||
}
|
||||
for _, p := range authorized {
|
||||
allAllowed, models := effectiveModelsForProvider(p, policiesForProvider(applicable, p.ID), guardrailsByID)
|
||||
flavor := ""
|
||||
if entry, ok := catalog.Lookup(p.ProviderID); ok {
|
||||
flavor = entry.ParserID
|
||||
}
|
||||
out.Providers = append(out.Providers, types.EffectiveProvider{
|
||||
Name: p.Name,
|
||||
CatalogID: p.ProviderID,
|
||||
APIFlavor: flavor,
|
||||
AllModelsAllowed: allAllowed,
|
||||
Models: models,
|
||||
})
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// filterPoliciesByGroups returns the enabled policies whose SourceGroups
|
||||
// intersect the caller's groups. Same group matching as
|
||||
// filterApplicablePolicies, without the per-provider filter — the setup
|
||||
// answer spans every provider the caller can reach.
|
||||
func filterPoliciesByGroups(policies []*types.Policy, groupIDs []string) []*types.Policy {
|
||||
groupSet := make(map[string]struct{}, len(groupIDs))
|
||||
for _, g := range groupIDs {
|
||||
if g != "" {
|
||||
groupSet[g] = struct{}{}
|
||||
}
|
||||
}
|
||||
out := make([]*types.Policy, 0, len(policies))
|
||||
for _, p := range policies {
|
||||
if p == nil || !p.Enabled {
|
||||
continue
|
||||
}
|
||||
if !anyGroupMatches(p.SourceGroups, groupSet) {
|
||||
continue
|
||||
}
|
||||
out = append(out, p)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// policiesForProvider returns the subset of policies targeting the
|
||||
// provider, order preserved.
|
||||
func policiesForProvider(policies []*types.Policy, providerID string) []*types.Policy {
|
||||
out := make([]*types.Policy, 0, len(policies))
|
||||
for _, p := range policies {
|
||||
if sliceContains(p.DestinationProviderIDs, providerID) {
|
||||
out = append(out, p)
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// effectiveModelsForProvider derives the caller's effective model set for
|
||||
// one provider from the applicable policies that target it, mirroring
|
||||
// policyPermitsModel: a policy with no allowlist-enabled guardrail is
|
||||
// unrestricted, and one unrestricted policy makes the whole provider
|
||||
// unrestricted (the proxy would admit any model through it). Otherwise
|
||||
// the union of the policies' allowlists applies, intersected with the
|
||||
// provider's declared models when the operator declared any — the router
|
||||
// only claims declared models, so an allowlisted-but-undeclared model is
|
||||
// unreachable and must not be advertised. With no declared models the
|
||||
// router claims every model, so the allowlist union stands alone.
|
||||
func effectiveModelsForProvider(provider *types.Provider, policies []*types.Policy, guardrailsByID map[string]*types.Guardrail) (bool, []string) {
|
||||
restricted := true
|
||||
union := make([]string, 0)
|
||||
seen := make(map[string]struct{})
|
||||
for _, p := range policies {
|
||||
policyRestricted := false
|
||||
for _, gID := range p.GuardrailIDs {
|
||||
g, ok := guardrailsByID[gID]
|
||||
if !ok || g == nil || !g.Checks.ModelAllowlist.Enabled {
|
||||
continue
|
||||
}
|
||||
policyRestricted = true
|
||||
for _, model := range g.Checks.ModelAllowlist.Models {
|
||||
key := normaliseModelID(model)
|
||||
if key == "" {
|
||||
continue
|
||||
}
|
||||
if _, dup := seen[key]; dup {
|
||||
continue
|
||||
}
|
||||
seen[key] = struct{}{}
|
||||
union = append(union, key)
|
||||
}
|
||||
}
|
||||
if !policyRestricted {
|
||||
restricted = false
|
||||
}
|
||||
}
|
||||
|
||||
declared := declaredModelIDs(provider)
|
||||
if !restricted {
|
||||
return true, declared
|
||||
}
|
||||
if len(provider.Models) == 0 {
|
||||
// No operator declaration: the router claims every model, so the
|
||||
// allowlist union is the effective set as-is.
|
||||
return false, union
|
||||
}
|
||||
out := make([]string, 0, len(declared))
|
||||
for _, id := range declared {
|
||||
if _, ok := seen[normaliseModelID(id)]; ok {
|
||||
out = append(out, id)
|
||||
}
|
||||
}
|
||||
return false, out
|
||||
}
|
||||
|
||||
// declaredModelIDs returns the models a provider exposes: the operator's
|
||||
// curated list when present, otherwise the catalog entry's models (an
|
||||
// empty operator list means "all catalog models"). Gateway/custom catalog
|
||||
// entries declare no models, so the result may be empty.
|
||||
func declaredModelIDs(provider *types.Provider) []string {
|
||||
if ids := providerModelIDs(provider); len(ids) > 0 {
|
||||
return ids
|
||||
}
|
||||
entry, ok := catalog.Lookup(provider.ProviderID)
|
||||
if !ok {
|
||||
return []string{}
|
||||
}
|
||||
out := make([]string, 0, len(entry.Models))
|
||||
for _, m := range entry.Models {
|
||||
if m.ID != "" {
|
||||
out = append(out, m.ID)
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// GetSetupForPeer on the mock manager reports "not configured" so tests
|
||||
// that don't care about setup still compile.
|
||||
func (*mockManager) GetSetupForPeer(_ context.Context, _, _ string) (*types.EffectiveSetup, error) {
|
||||
return &types.EffectiveSetup{Providers: []types.EffectiveProvider{}}, nil
|
||||
}
|
||||
@@ -0,0 +1,271 @@
|
||||
package agentnetwork
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/netbirdio/netbird/management/internals/modules/agentnetwork/types"
|
||||
"github.com/netbirdio/netbird/management/server/store"
|
||||
)
|
||||
|
||||
// These tests drive the effective-setup computation through the real
|
||||
// sqlite store, mirroring the policyselect realstore suite: assert on
|
||||
// observable answers (configured / providers / models), not on which
|
||||
// store methods get called. The computation must agree with what the
|
||||
// proxy enforces — policy filtering matches filterApplicablePolicies,
|
||||
// model logic matches policyPermitsModel, and orphan providers are
|
||||
// omitted like the router synthesizer omits them.
|
||||
|
||||
func newSetupTestMgr(t *testing.T) (*managerImpl, store.Store) {
|
||||
t.Helper()
|
||||
ctx := context.Background()
|
||||
s, cleanup, err := store.NewTestStoreFromSQL(ctx, "", t.TempDir())
|
||||
require.NoError(t, err, "real sqlite test store must come up")
|
||||
t.Cleanup(cleanup)
|
||||
return &managerImpl{store: s}, s
|
||||
}
|
||||
|
||||
// newSetupTestGuardrail returns an allowlist-enabled guardrail.
|
||||
func newSetupTestGuardrail(id string, models ...string) *types.Guardrail {
|
||||
return &types.Guardrail{
|
||||
ID: id,
|
||||
AccountID: testAccountID,
|
||||
Name: "allowlist " + id,
|
||||
Checks: types.GuardrailChecks{
|
||||
ModelAllowlist: types.GuardrailModelAllowlist{Enabled: true, Models: models},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestEffectiveSetup_RealStore_NoSettingsRow(t *testing.T) {
|
||||
mgr, _ := newSetupTestMgr(t)
|
||||
|
||||
setup, err := mgr.effectiveSetupForGroups(context.Background(), testAccountID, []string{"grp-eng"})
|
||||
require.NoError(t, err)
|
||||
assert.False(t, setup.Configured, "account without settings must read as not configured")
|
||||
assert.Empty(t, setup.Endpoint)
|
||||
assert.Empty(t, setup.Providers)
|
||||
}
|
||||
|
||||
func TestEffectiveSetup_RealStore_NoApplicablePolicy(t *testing.T) {
|
||||
mgr, s := newSetupTestMgr(t)
|
||||
ctx := context.Background()
|
||||
|
||||
require.NoError(t, s.SaveAgentNetworkSettings(ctx, newSynthTestSettings()))
|
||||
provider := newSynthTestProvider()
|
||||
require.NoError(t, s.SaveAgentNetworkProvider(ctx, provider))
|
||||
require.NoError(t, s.SaveAgentNetworkPolicy(ctx, newSynthTestPolicy(provider.ID, "grp-eng", "")))
|
||||
|
||||
setup, err := mgr.effectiveSetupForGroups(ctx, testAccountID, []string{"grp-other"})
|
||||
require.NoError(t, err)
|
||||
assert.False(t, setup.Configured, "caller outside every policy's source groups must read as not configured")
|
||||
assert.Empty(t, setup.Endpoint, "no-access answer must not leak the endpoint")
|
||||
assert.Empty(t, setup.Providers)
|
||||
}
|
||||
|
||||
func TestEffectiveSetup_RealStore_UnrestrictedPolicyListsDeclaredModels(t *testing.T) {
|
||||
mgr, s := newSetupTestMgr(t)
|
||||
ctx := context.Background()
|
||||
|
||||
require.NoError(t, s.SaveAgentNetworkSettings(ctx, newSynthTestSettings()))
|
||||
provider := newSynthTestProvider()
|
||||
require.NoError(t, s.SaveAgentNetworkProvider(ctx, provider))
|
||||
require.NoError(t, s.SaveAgentNetworkPolicy(ctx, newSynthTestPolicy(provider.ID, "grp-eng", "")))
|
||||
|
||||
setup, err := mgr.effectiveSetupForGroups(ctx, testAccountID, []string{"grp-eng"})
|
||||
require.NoError(t, err)
|
||||
assert.True(t, setup.Configured)
|
||||
assert.Equal(t, "https://"+testEndpoint, setup.Endpoint)
|
||||
require.Len(t, setup.Providers, 1)
|
||||
p := setup.Providers[0]
|
||||
assert.Equal(t, "OpenAI", p.Name)
|
||||
assert.Equal(t, "openai_api", p.CatalogID)
|
||||
assert.Equal(t, "openai", p.APIFlavor)
|
||||
assert.True(t, p.AllModelsAllowed, "policy without allowlist guardrail is unrestricted")
|
||||
assert.Equal(t, []string{"gpt-5.4"}, p.Models, "declared models listed as a courtesy")
|
||||
}
|
||||
|
||||
func TestEffectiveSetup_RealStore_AllowlistIntersectsDeclaredModels(t *testing.T) {
|
||||
mgr, s := newSetupTestMgr(t)
|
||||
ctx := context.Background()
|
||||
|
||||
require.NoError(t, s.SaveAgentNetworkSettings(ctx, newSynthTestSettings()))
|
||||
provider := newSynthTestProvider()
|
||||
provider.Models = []types.ProviderModel{{ID: "gpt-5.4"}, {ID: "gpt-4o"}}
|
||||
require.NoError(t, s.SaveAgentNetworkProvider(ctx, provider))
|
||||
// Allowlist admits gpt-5.4 (declared, odd casing/spacing) and gpt-4.1
|
||||
// (NOT declared — the router would never route it, so it must not be
|
||||
// advertised).
|
||||
require.NoError(t, s.SaveAgentNetworkGuardrail(ctx, newSetupTestGuardrail("guard-1", " GPT-5.4 ", "gpt-4.1")))
|
||||
require.NoError(t, s.SaveAgentNetworkPolicy(ctx, newSynthTestPolicy(provider.ID, "grp-eng", "guard-1")))
|
||||
|
||||
setup, err := mgr.effectiveSetupForGroups(ctx, testAccountID, []string{"grp-eng"})
|
||||
require.NoError(t, err)
|
||||
require.Len(t, setup.Providers, 1)
|
||||
p := setup.Providers[0]
|
||||
assert.False(t, p.AllModelsAllowed)
|
||||
assert.Equal(t, []string{"gpt-5.4"}, p.Models, "allowlist ∩ declared, in declared order and casing")
|
||||
}
|
||||
|
||||
func TestEffectiveSetup_RealStore_UnrestrictedPolicyWinsOverRestricted(t *testing.T) {
|
||||
mgr, s := newSetupTestMgr(t)
|
||||
ctx := context.Background()
|
||||
|
||||
require.NoError(t, s.SaveAgentNetworkSettings(ctx, newSynthTestSettings()))
|
||||
provider := newSynthTestProvider()
|
||||
require.NoError(t, s.SaveAgentNetworkProvider(ctx, provider))
|
||||
require.NoError(t, s.SaveAgentNetworkGuardrail(ctx, newSetupTestGuardrail("guard-1", "gpt-5.4")))
|
||||
restricted := newSynthTestPolicy(provider.ID, "grp-eng", "guard-1")
|
||||
require.NoError(t, s.SaveAgentNetworkPolicy(ctx, restricted))
|
||||
open := newSynthTestPolicy(provider.ID, "grp-eng", "")
|
||||
open.ID = "pol-2"
|
||||
require.NoError(t, s.SaveAgentNetworkPolicy(ctx, open))
|
||||
|
||||
setup, err := mgr.effectiveSetupForGroups(ctx, testAccountID, []string{"grp-eng"})
|
||||
require.NoError(t, err)
|
||||
require.Len(t, setup.Providers, 1)
|
||||
assert.True(t, setup.Providers[0].AllModelsAllowed,
|
||||
"one applicable policy without an allowlist makes the provider unrestricted — the proxy would admit any model through it")
|
||||
}
|
||||
|
||||
func TestEffectiveSetup_RealStore_AllowlistUnionAcrossPolicies(t *testing.T) {
|
||||
mgr, s := newSetupTestMgr(t)
|
||||
ctx := context.Background()
|
||||
|
||||
require.NoError(t, s.SaveAgentNetworkSettings(ctx, newSynthTestSettings()))
|
||||
provider := newSynthTestProvider()
|
||||
provider.Models = []types.ProviderModel{{ID: "gpt-5.4"}, {ID: "gpt-4o"}, {ID: "o4-mini"}}
|
||||
require.NoError(t, s.SaveAgentNetworkProvider(ctx, provider))
|
||||
require.NoError(t, s.SaveAgentNetworkGuardrail(ctx, newSetupTestGuardrail("guard-1", "gpt-5.4")))
|
||||
require.NoError(t, s.SaveAgentNetworkGuardrail(ctx, newSetupTestGuardrail("guard-2", "gpt-4o")))
|
||||
p1 := newSynthTestPolicy(provider.ID, "grp-eng", "guard-1")
|
||||
require.NoError(t, s.SaveAgentNetworkPolicy(ctx, p1))
|
||||
p2 := newSynthTestPolicy(provider.ID, "grp-eng", "guard-2")
|
||||
p2.ID = "pol-2"
|
||||
require.NoError(t, s.SaveAgentNetworkPolicy(ctx, p2))
|
||||
|
||||
setup, err := mgr.effectiveSetupForGroups(ctx, testAccountID, []string{"grp-eng"})
|
||||
require.NoError(t, err)
|
||||
require.Len(t, setup.Providers, 1)
|
||||
p := setup.Providers[0]
|
||||
assert.False(t, p.AllModelsAllowed)
|
||||
assert.ElementsMatch(t, []string{"gpt-5.4", "gpt-4o"}, p.Models, "union of allowlists across applicable policies")
|
||||
}
|
||||
|
||||
func TestEffectiveSetup_RealStore_OrphanAndDisabledProvidersOmitted(t *testing.T) {
|
||||
mgr, s := newSetupTestMgr(t)
|
||||
ctx := context.Background()
|
||||
|
||||
require.NoError(t, s.SaveAgentNetworkSettings(ctx, newSynthTestSettings()))
|
||||
// Orphan: enabled but referenced by no policy.
|
||||
orphan := newSynthTestProvider()
|
||||
orphan.ID = "prov-orphan"
|
||||
require.NoError(t, s.SaveAgentNetworkProvider(ctx, orphan))
|
||||
// Disabled but referenced by an applicable policy.
|
||||
disabled := newSynthTestProvider()
|
||||
disabled.ID = "prov-disabled"
|
||||
disabled.Enabled = false
|
||||
require.NoError(t, s.SaveAgentNetworkProvider(ctx, disabled))
|
||||
require.NoError(t, s.SaveAgentNetworkPolicy(ctx, newSynthTestPolicy(disabled.ID, "grp-eng", "")))
|
||||
|
||||
setup, err := mgr.effectiveSetupForGroups(ctx, testAccountID, []string{"grp-eng"})
|
||||
require.NoError(t, err)
|
||||
assert.False(t, setup.Configured, "neither an orphan nor a disabled provider is reachable, so nothing is configured for the caller")
|
||||
assert.Empty(t, setup.Providers)
|
||||
}
|
||||
|
||||
func TestEffectiveSetup_RealStore_DisabledPolicyIgnored(t *testing.T) {
|
||||
mgr, s := newSetupTestMgr(t)
|
||||
ctx := context.Background()
|
||||
|
||||
require.NoError(t, s.SaveAgentNetworkSettings(ctx, newSynthTestSettings()))
|
||||
provider := newSynthTestProvider()
|
||||
require.NoError(t, s.SaveAgentNetworkProvider(ctx, provider))
|
||||
policy := newSynthTestPolicy(provider.ID, "grp-eng", "")
|
||||
policy.Enabled = false
|
||||
require.NoError(t, s.SaveAgentNetworkPolicy(ctx, policy))
|
||||
|
||||
setup, err := mgr.effectiveSetupForGroups(ctx, testAccountID, []string{"grp-eng"})
|
||||
require.NoError(t, err)
|
||||
assert.False(t, setup.Configured)
|
||||
}
|
||||
|
||||
func TestEffectiveSetup_RealStore_UndeclaredModelsUseAllowlistAsIs(t *testing.T) {
|
||||
mgr, s := newSetupTestMgr(t)
|
||||
ctx := context.Background()
|
||||
|
||||
require.NoError(t, s.SaveAgentNetworkSettings(ctx, newSynthTestSettings()))
|
||||
// Gateway-style provider: no declared models — the router claims every
|
||||
// model, so the allowlist union is the effective set on its own.
|
||||
provider := newSynthTestProvider()
|
||||
provider.ProviderID = "litellm_proxy"
|
||||
provider.Name = "LiteLLM"
|
||||
provider.Models = nil
|
||||
require.NoError(t, s.SaveAgentNetworkProvider(ctx, provider))
|
||||
require.NoError(t, s.SaveAgentNetworkGuardrail(ctx, newSetupTestGuardrail("guard-1", "claude-sonnet-4-5")))
|
||||
require.NoError(t, s.SaveAgentNetworkPolicy(ctx, newSynthTestPolicy(provider.ID, "grp-eng", "guard-1")))
|
||||
|
||||
setup, err := mgr.effectiveSetupForGroups(ctx, testAccountID, []string{"grp-eng"})
|
||||
require.NoError(t, err)
|
||||
require.Len(t, setup.Providers, 1)
|
||||
p := setup.Providers[0]
|
||||
assert.False(t, p.AllModelsAllowed)
|
||||
assert.Equal(t, []string{"claude-sonnet-4-5"}, p.Models)
|
||||
}
|
||||
|
||||
func TestEffectiveSetup_RealStore_ProvidersInCreatedAtOrder(t *testing.T) {
|
||||
mgr, s := newSetupTestMgr(t)
|
||||
ctx := context.Background()
|
||||
|
||||
require.NoError(t, s.SaveAgentNetworkSettings(ctx, newSynthTestSettings()))
|
||||
newer := newSynthTestProvider()
|
||||
newer.ID = "prov-newer"
|
||||
newer.Name = "Newer"
|
||||
newer.CreatedAt = time.Date(2026, 2, 1, 0, 0, 0, 0, time.UTC)
|
||||
require.NoError(t, s.SaveAgentNetworkProvider(ctx, newer))
|
||||
older := newSynthTestProvider()
|
||||
older.ID = "prov-older"
|
||||
older.Name = "Older"
|
||||
older.CreatedAt = time.Date(2026, 1, 1, 0, 0, 0, 0, time.UTC)
|
||||
require.NoError(t, s.SaveAgentNetworkProvider(ctx, older))
|
||||
|
||||
policy := newSynthTestPolicy(newer.ID, "grp-eng", "")
|
||||
policy.DestinationProviderIDs = []string{newer.ID, older.ID}
|
||||
require.NoError(t, s.SaveAgentNetworkPolicy(ctx, policy))
|
||||
|
||||
setup, err := mgr.effectiveSetupForGroups(ctx, testAccountID, []string{"grp-eng"})
|
||||
require.NoError(t, err)
|
||||
require.Len(t, setup.Providers, 2)
|
||||
assert.Equal(t, "Older", setup.Providers[0].Name)
|
||||
assert.Equal(t, "Newer", setup.Providers[1].Name)
|
||||
}
|
||||
|
||||
// TestGetSetupForPeer_RealStore pins the peer entry point: the peer's
|
||||
// group memberships (not any user identity) scope the answer, which is
|
||||
// exactly what the proxy enforces via AllowedGroupIDs — including for
|
||||
// setup-key/machine peers that have no user attached.
|
||||
func TestGetSetupForPeer_RealStore(t *testing.T) {
|
||||
mgr, s := newSetupTestMgr(t)
|
||||
ctx := context.Background()
|
||||
|
||||
require.NoError(t, s.SaveAgentNetworkSettings(ctx, newSynthTestSettings()))
|
||||
provider := newSynthTestProvider()
|
||||
require.NoError(t, s.SaveAgentNetworkProvider(ctx, provider))
|
||||
require.NoError(t, s.SaveAgentNetworkPolicy(ctx, newSynthTestPolicy(provider.ID, "grp-eng", "")))
|
||||
|
||||
require.NoError(t, s.AddPeerToGroup(ctx, testAccountID, "peer-in", "grp-eng"))
|
||||
require.NoError(t, s.AddPeerToGroup(ctx, testAccountID, "peer-out", "grp-other"))
|
||||
|
||||
setupIn, err := mgr.GetSetupForPeer(ctx, testAccountID, "peer-in")
|
||||
require.NoError(t, err)
|
||||
assert.True(t, setupIn.Configured)
|
||||
require.Len(t, setupIn.Providers, 1)
|
||||
|
||||
setupOut, err := mgr.GetSetupForPeer(ctx, testAccountID, "peer-out")
|
||||
require.NoError(t, err)
|
||||
assert.False(t, setupOut.Configured, "peer outside the policy's source groups gets the not-configured answer")
|
||||
}
|
||||
40
management/internals/modules/agentnetwork/types/setup.go
Normal file
40
management/internals/modules/agentnetwork/types/setup.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package types
|
||||
|
||||
// EffectiveSetup is the caller-scoped answer to "what may this caller
|
||||
// use on the Agent Network?" — the account's proxy endpoint plus the
|
||||
// providers and models the caller's groups authorize. It intentionally
|
||||
// carries display metadata only: no keys, no upstream URLs, no policy or
|
||||
// guardrail structure, and no hint of providers the caller cannot reach.
|
||||
type EffectiveSetup struct {
|
||||
// Configured is false when the account has no Agent Network set up or
|
||||
// when nothing is authorized for the caller's groups — the two cases
|
||||
// are deliberately indistinguishable so the response leaks nothing
|
||||
// about what exists for others.
|
||||
Configured bool
|
||||
// Endpoint is the account's proxy base URL
|
||||
// ("https://<subdomain>.<cluster>"), reachable over the NetBird tunnel
|
||||
// only. Empty when Configured is false.
|
||||
Endpoint string
|
||||
// Providers lists the providers at least one applicable policy
|
||||
// authorizes for the caller, in the account's created_at order.
|
||||
Providers []EffectiveProvider
|
||||
}
|
||||
|
||||
// EffectiveProvider is one authorized provider in an EffectiveSetup.
|
||||
type EffectiveProvider struct {
|
||||
// Name is the operator-assigned label, e.g. "Bedrock prod".
|
||||
Name string
|
||||
// CatalogID names the catalog entry, e.g. "anthropic_api".
|
||||
CatalogID string
|
||||
// APIFlavor is the request-body shape the provider speaks — the
|
||||
// catalog entry's parser id ("anthropic", "openai"); empty when the
|
||||
// proxy dispatches the provider by URL path instead.
|
||||
APIFlavor string
|
||||
// AllModelsAllowed is true when no model allowlist restricts this
|
||||
// provider for the caller. Models then lists the declared/catalog
|
||||
// models as a courtesy (possibly none for gateway-style providers).
|
||||
AllModelsAllowed bool
|
||||
// Models is the effective model allowlist for the caller, or the
|
||||
// declared/catalog models when AllModelsAllowed is true.
|
||||
Models []string
|
||||
}
|
||||
@@ -211,10 +211,12 @@ func (s *BaseServer) GRPCServer() *grpc.Server {
|
||||
}
|
||||
serviceMgr := s.ServiceManager()
|
||||
srv.SetReverseProxyManager(serviceMgr)
|
||||
srv.SetAgentNetworkSetupService(s.AgentNetworkManager())
|
||||
if serviceMgr != nil {
|
||||
serviceMgr.StartExposeReaper(context.Background())
|
||||
}
|
||||
mgmtProto.RegisterManagementServiceServer(gRPCAPIHandler, srv)
|
||||
log.Info("ManagementService registered on gRPC server (agent-network setup RPC available)")
|
||||
|
||||
mgmtProto.RegisterProxyServiceServer(gRPCAPIHandler, s.ReverseProxyGRPCServer())
|
||||
log.Info("ProxyService registered on gRPC server")
|
||||
|
||||
81
management/internals/shared/grpc/agentnetwork_service.go
Normal file
81
management/internals/shared/grpc/agentnetwork_service.go
Normal file
@@ -0,0 +1,81 @@
|
||||
package grpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
|
||||
antypes "github.com/netbirdio/netbird/management/internals/modules/agentnetwork/types"
|
||||
"github.com/netbirdio/netbird/shared/management/proto"
|
||||
)
|
||||
|
||||
// AgentNetworkSetupService is the minimal slice of agentnetwork.Manager
|
||||
// the peer-facing setup RPC needs. Narrow on purpose so the gRPC server
|
||||
// never sees the manager's operator-facing surface.
|
||||
type AgentNetworkSetupService interface {
|
||||
GetSetupForPeer(ctx context.Context, accountID, peerID string) (*antypes.EffectiveSetup, error)
|
||||
}
|
||||
|
||||
// GetAgentNetworkSetup handles a peer request for its Agent Network
|
||||
// connection info. The WireGuard key is the credential (same trust model
|
||||
// as the Expose RPCs); the response is scoped to what the calling peer's
|
||||
// own groups authorize and carries display metadata only.
|
||||
func (s *Server) GetAgentNetworkSetup(ctx context.Context, req *proto.EncryptedMessage) (*proto.EncryptedMessage, error) {
|
||||
setupReq := &proto.AgentNetworkSetupRequest{}
|
||||
peerKey, err := s.parseRequest(ctx, req, setupReq)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
accountID, peer, err := s.authenticateExposePeer(ctx, peerKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
setupSvc := s.getAgentNetworkSetupService()
|
||||
if setupSvc == nil {
|
||||
return nil, status.Errorf(codes.Internal, "agent network manager not available")
|
||||
}
|
||||
|
||||
setup, err := setupSvc.GetSetupForPeer(ctx, accountID, peer.ID)
|
||||
if err != nil {
|
||||
log.WithContext(ctx).Errorf("get agent network setup for peer %s: %v", peer.ID, err)
|
||||
return nil, status.Errorf(codes.Internal, "internal error")
|
||||
}
|
||||
|
||||
return s.encryptResponse(peerKey, toProtoAgentNetworkSetup(setup))
|
||||
}
|
||||
|
||||
func toProtoAgentNetworkSetup(setup *antypes.EffectiveSetup) *proto.AgentNetworkSetupResponse {
|
||||
resp := &proto.AgentNetworkSetupResponse{
|
||||
Configured: setup.Configured,
|
||||
Endpoint: setup.Endpoint,
|
||||
Providers: make([]*proto.AgentNetworkProviderInfo, 0, len(setup.Providers)),
|
||||
}
|
||||
for _, p := range setup.Providers {
|
||||
resp.Providers = append(resp.Providers, &proto.AgentNetworkProviderInfo{
|
||||
Name: p.Name,
|
||||
CatalogId: p.CatalogID,
|
||||
ApiFlavor: p.APIFlavor,
|
||||
AllModelsAllowed: p.AllModelsAllowed,
|
||||
Models: p.Models,
|
||||
})
|
||||
}
|
||||
return resp
|
||||
}
|
||||
|
||||
func (s *Server) getAgentNetworkSetupService() AgentNetworkSetupService {
|
||||
s.agentNetworkSetupMu.RLock()
|
||||
defer s.agentNetworkSetupMu.RUnlock()
|
||||
return s.agentNetworkSetup
|
||||
}
|
||||
|
||||
// SetAgentNetworkSetupService wires the agent-network setup service on
|
||||
// the server.
|
||||
func (s *Server) SetAgentNetworkSetupService(svc AgentNetworkSetupService) {
|
||||
s.agentNetworkSetupMu.Lock()
|
||||
defer s.agentNetworkSetupMu.Unlock()
|
||||
s.agentNetworkSetup = svc
|
||||
}
|
||||
@@ -87,6 +87,9 @@ type Server struct {
|
||||
|
||||
reverseProxyManager rpservice.Manager
|
||||
reverseProxyMu sync.RWMutex
|
||||
|
||||
agentNetworkSetup AgentNetworkSetupService
|
||||
agentNetworkSetupMu sync.RWMutex
|
||||
}
|
||||
|
||||
// NewServer creates a new Management server
|
||||
|
||||
89
shared/management/client/agentnetwork_test.go
Normal file
89
shared/management/client/agentnetwork_test.go
Normal file
@@ -0,0 +1,89 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||
"google.golang.org/grpc"
|
||||
|
||||
"github.com/netbirdio/netbird/encryption"
|
||||
mgmtProto "github.com/netbirdio/netbird/shared/management/proto"
|
||||
)
|
||||
|
||||
// agentNetworkSetupServer is a minimal ManagementService that answers
|
||||
// GetServerKey and GetAgentNetworkSetup with the real NaCl-box envelope,
|
||||
// so the test pins the full wire path: gRPC method routing, request
|
||||
// encryption, and response decryption.
|
||||
type agentNetworkSetupServer struct {
|
||||
mgmtProto.UnimplementedManagementServiceServer
|
||||
key wgtypes.Key
|
||||
}
|
||||
|
||||
func (s *agentNetworkSetupServer) GetServerKey(_ context.Context, _ *mgmtProto.Empty) (*mgmtProto.ServerKeyResponse, error) {
|
||||
return &mgmtProto.ServerKeyResponse{Key: s.key.PublicKey().String()}, nil
|
||||
}
|
||||
|
||||
func (s *agentNetworkSetupServer) GetAgentNetworkSetup(_ context.Context, msg *mgmtProto.EncryptedMessage) (*mgmtProto.EncryptedMessage, error) {
|
||||
peerKey, err := wgtypes.ParseKey(msg.WgPubKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req := &mgmtProto.AgentNetworkSetupRequest{}
|
||||
if err := encryption.DecryptMessage(peerKey, s.key, msg.Body, req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp := &mgmtProto.AgentNetworkSetupResponse{
|
||||
Configured: true,
|
||||
Endpoint: "https://violet.eu.proxy.example.com",
|
||||
Providers: []*mgmtProto.AgentNetworkProviderInfo{
|
||||
{
|
||||
Name: "Anthropic prod",
|
||||
CatalogId: "anthropic_api",
|
||||
ApiFlavor: "anthropic",
|
||||
Models: []string{"claude-sonnet-4-5"},
|
||||
},
|
||||
},
|
||||
}
|
||||
body, err := encryption.EncryptMessage(peerKey, s.key, resp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &mgmtProto.EncryptedMessage{WgPubKey: s.key.PublicKey().String(), Body: body}, nil
|
||||
}
|
||||
|
||||
// TestGetAgentNetworkSetup_RoundTrip proves the RPC is routable on any
|
||||
// server built from this tree and that the encrypt→invoke→decrypt path
|
||||
// the CLI uses round-trips. A server answering this call with
|
||||
// codes.Unimplemented is by definition running a binary compiled without
|
||||
// the regenerated management proto.
|
||||
func TestGetAgentNetworkSetup_RoundTrip(t *testing.T) {
|
||||
serverKey, err := wgtypes.GeneratePrivateKey()
|
||||
require.NoError(t, err)
|
||||
|
||||
lis, err := net.Listen("tcp", "127.0.0.1:0")
|
||||
require.NoError(t, err)
|
||||
|
||||
srv := grpc.NewServer()
|
||||
mgmtProto.RegisterManagementServiceServer(srv, &agentNetworkSetupServer{key: serverKey})
|
||||
go func() { _ = srv.Serve(lis) }()
|
||||
t.Cleanup(srv.Stop)
|
||||
|
||||
clientKey, err := wgtypes.GeneratePrivateKey()
|
||||
require.NoError(t, err)
|
||||
|
||||
client, err := NewClient(context.Background(), lis.Addr().String(), clientKey, false)
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() { _ = client.Close() })
|
||||
|
||||
setup, err := client.GetAgentNetworkSetup(context.Background())
|
||||
require.NoError(t, err)
|
||||
assert.True(t, setup.Configured)
|
||||
assert.Equal(t, "https://violet.eu.proxy.example.com", setup.Endpoint)
|
||||
require.Len(t, setup.Providers, 1)
|
||||
assert.Equal(t, "anthropic_api", setup.Providers[0].CatalogId)
|
||||
assert.Equal(t, []string{"claude-sonnet-4-5"}, setup.Providers[0].Models)
|
||||
}
|
||||
@@ -34,4 +34,8 @@ type Client interface {
|
||||
CreateExpose(ctx context.Context, req ExposeRequest) (*ExposeResponse, error)
|
||||
RenewExpose(ctx context.Context, domain string) error
|
||||
StopExpose(ctx context.Context, domain string) error
|
||||
// GetAgentNetworkSetup returns the Agent Network connection info the
|
||||
// calling peer's groups authorize: proxy endpoint plus effective
|
||||
// providers and models.
|
||||
GetAgentNetworkSetup(ctx context.Context) (*proto.AgentNetworkSetupResponse, error)
|
||||
}
|
||||
|
||||
@@ -914,6 +914,38 @@ func (c *GrpcClient) StopExpose(ctx context.Context, domain string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// GetAgentNetworkSetup asks the management server for the Agent Network
|
||||
// connection info the calling peer's groups authorize.
|
||||
func (c *GrpcClient) GetAgentNetworkSetup(ctx context.Context) (*proto.AgentNetworkSetupResponse, error) {
|
||||
serverPubKey, err := c.getServerPublicKey()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
encReq, err := encryption.EncryptMessage(*serverPubKey, c.key, &proto.AgentNetworkSetupRequest{})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("encrypt agent network setup request: %w", err)
|
||||
}
|
||||
|
||||
mgmCtx, cancel := context.WithTimeout(ctx, ConnectTimeout)
|
||||
defer cancel()
|
||||
|
||||
resp, err := c.realClient.GetAgentNetworkSetup(mgmCtx, &proto.EncryptedMessage{
|
||||
WgPubKey: c.key.PublicKey().String(),
|
||||
Body: encReq,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
setupResp := &proto.AgentNetworkSetupResponse{}
|
||||
if err := encryption.DecryptMessage(*serverPubKey, c.key, resp.Body, setupResp); err != nil {
|
||||
return nil, fmt.Errorf("decrypt agent network setup response: %w", err)
|
||||
}
|
||||
|
||||
return setupResp, nil
|
||||
}
|
||||
|
||||
func fromProtoExposeResponse(resp *proto.ExposeServiceResponse) *ExposeResponse {
|
||||
return &ExposeResponse{
|
||||
ServiceName: resp.ServiceName,
|
||||
|
||||
@@ -25,6 +25,7 @@ type MockClient struct {
|
||||
CreateExposeFunc func(ctx context.Context, req ExposeRequest) (*ExposeResponse, error)
|
||||
RenewExposeFunc func(ctx context.Context, domain string) error
|
||||
StopExposeFunc func(ctx context.Context, domain string) error
|
||||
GetAgentNetworkSetupFunc func(ctx context.Context) (*proto.AgentNetworkSetupResponse, error)
|
||||
}
|
||||
|
||||
func (m *MockClient) IsHealthy() bool {
|
||||
@@ -136,3 +137,10 @@ func (m *MockClient) StopExpose(ctx context.Context, domain string) error {
|
||||
}
|
||||
return m.StopExposeFunc(ctx, domain)
|
||||
}
|
||||
|
||||
func (m *MockClient) GetAgentNetworkSetup(ctx context.Context) (*proto.AgentNetworkSetupResponse, error) {
|
||||
if m.GetAgentNetworkSetupFunc == nil {
|
||||
return &proto.AgentNetworkSetupResponse{}, nil
|
||||
}
|
||||
return m.GetAgentNetworkSetupFunc(ctx)
|
||||
}
|
||||
|
||||
@@ -6653,6 +6653,201 @@ func (x *PeerIndexSet) GetPeerIndexes() []uint32 {
|
||||
return nil
|
||||
}
|
||||
|
||||
type AgentNetworkSetupRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
}
|
||||
|
||||
func (x *AgentNetworkSetupRequest) Reset() {
|
||||
*x = AgentNetworkSetupRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_management_proto_msgTypes[76]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *AgentNetworkSetupRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*AgentNetworkSetupRequest) ProtoMessage() {}
|
||||
|
||||
func (x *AgentNetworkSetupRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_management_proto_msgTypes[76]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use AgentNetworkSetupRequest.ProtoReflect.Descriptor instead.
|
||||
func (*AgentNetworkSetupRequest) Descriptor() ([]byte, []int) {
|
||||
return file_management_proto_rawDescGZIP(), []int{76}
|
||||
}
|
||||
|
||||
type AgentNetworkSetupResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// configured is false when the account has no Agent Network set up or
|
||||
// the calling peer's groups authorize none of it — the two cases are
|
||||
// deliberately indistinguishable.
|
||||
Configured bool `protobuf:"varint,1,opt,name=configured,proto3" json:"configured,omitempty"`
|
||||
// endpoint is the account's proxy base URL, e.g.
|
||||
// "https://calm-otter.proxy.example.com". Reachable over the NetBird
|
||||
// tunnel only. Empty when configured is false.
|
||||
Endpoint string `protobuf:"bytes,2,opt,name=endpoint,proto3" json:"endpoint,omitempty"`
|
||||
Providers []*AgentNetworkProviderInfo `protobuf:"bytes,3,rep,name=providers,proto3" json:"providers,omitempty"`
|
||||
}
|
||||
|
||||
func (x *AgentNetworkSetupResponse) Reset() {
|
||||
*x = AgentNetworkSetupResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_management_proto_msgTypes[77]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *AgentNetworkSetupResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*AgentNetworkSetupResponse) ProtoMessage() {}
|
||||
|
||||
func (x *AgentNetworkSetupResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_management_proto_msgTypes[77]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use AgentNetworkSetupResponse.ProtoReflect.Descriptor instead.
|
||||
func (*AgentNetworkSetupResponse) Descriptor() ([]byte, []int) {
|
||||
return file_management_proto_rawDescGZIP(), []int{77}
|
||||
}
|
||||
|
||||
func (x *AgentNetworkSetupResponse) GetConfigured() bool {
|
||||
if x != nil {
|
||||
return x.Configured
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *AgentNetworkSetupResponse) GetEndpoint() string {
|
||||
if x != nil {
|
||||
return x.Endpoint
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *AgentNetworkSetupResponse) GetProviders() []*AgentNetworkProviderInfo {
|
||||
if x != nil {
|
||||
return x.Providers
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type AgentNetworkProviderInfo struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// name is the operator-assigned provider label, e.g. "Bedrock prod".
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
// catalog_id names the catalog entry, e.g. "anthropic_api", "bedrock_api".
|
||||
CatalogId string `protobuf:"bytes,2,opt,name=catalog_id,json=catalogId,proto3" json:"catalog_id,omitempty"`
|
||||
// api_flavor is the request-body shape the provider speaks ("anthropic",
|
||||
// "openai"); empty when the proxy dispatches it by URL path instead.
|
||||
ApiFlavor string `protobuf:"bytes,3,opt,name=api_flavor,json=apiFlavor,proto3" json:"api_flavor,omitempty"`
|
||||
// all_models_allowed is true when no model allowlist restricts this
|
||||
// provider for the caller; models then lists the declared/catalog models
|
||||
// as a courtesy (possibly none for gateway-style providers).
|
||||
AllModelsAllowed bool `protobuf:"varint,4,opt,name=all_models_allowed,json=allModelsAllowed,proto3" json:"all_models_allowed,omitempty"`
|
||||
// models is the effective model allowlist for the caller (or the
|
||||
// declared/catalog models when all_models_allowed is true).
|
||||
Models []string `protobuf:"bytes,5,rep,name=models,proto3" json:"models,omitempty"`
|
||||
}
|
||||
|
||||
func (x *AgentNetworkProviderInfo) Reset() {
|
||||
*x = AgentNetworkProviderInfo{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_management_proto_msgTypes[78]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *AgentNetworkProviderInfo) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*AgentNetworkProviderInfo) ProtoMessage() {}
|
||||
|
||||
func (x *AgentNetworkProviderInfo) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_management_proto_msgTypes[78]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use AgentNetworkProviderInfo.ProtoReflect.Descriptor instead.
|
||||
func (*AgentNetworkProviderInfo) Descriptor() ([]byte, []int) {
|
||||
return file_management_proto_rawDescGZIP(), []int{78}
|
||||
}
|
||||
|
||||
func (x *AgentNetworkProviderInfo) GetName() string {
|
||||
if x != nil {
|
||||
return x.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *AgentNetworkProviderInfo) GetCatalogId() string {
|
||||
if x != nil {
|
||||
return x.CatalogId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *AgentNetworkProviderInfo) GetApiFlavor() string {
|
||||
if x != nil {
|
||||
return x.ApiFlavor
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *AgentNetworkProviderInfo) GetAllModelsAllowed() bool {
|
||||
if x != nil {
|
||||
return x.AllModelsAllowed
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *AgentNetworkProviderInfo) GetModels() []string {
|
||||
if x != nil {
|
||||
return x.Models
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type PortInfo_Range struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@@ -6665,7 +6860,7 @@ type PortInfo_Range struct {
|
||||
func (x *PortInfo_Range) Reset() {
|
||||
*x = PortInfo_Range{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_management_proto_msgTypes[77]
|
||||
mi := &file_management_proto_msgTypes[80]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -6678,7 +6873,7 @@ func (x *PortInfo_Range) String() string {
|
||||
func (*PortInfo_Range) ProtoMessage() {}
|
||||
|
||||
func (x *PortInfo_Range) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_management_proto_msgTypes[77]
|
||||
mi := &file_management_proto_msgTypes[80]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -7744,99 +7939,127 @@ var file_management_proto_rawDesc = []byte{
|
||||
0x0c, 0x50, 0x65, 0x65, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x53, 0x65, 0x74, 0x12, 0x21, 0x0a,
|
||||
0x0c, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x73, 0x18, 0x01, 0x20,
|
||||
0x03, 0x28, 0x0d, 0x52, 0x0b, 0x70, 0x65, 0x65, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x73,
|
||||
0x2a, 0x3a, 0x0a, 0x09, 0x4a, 0x6f, 0x62, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x12, 0x0a,
|
||||
0x0e, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x10,
|
||||
0x00, 0x12, 0x0d, 0x0a, 0x09, 0x73, 0x75, 0x63, 0x63, 0x65, 0x65, 0x64, 0x65, 0x64, 0x10, 0x01,
|
||||
0x12, 0x0a, 0x0a, 0x06, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x10, 0x02, 0x2a, 0x93, 0x01, 0x0a,
|
||||
0x0e, 0x50, 0x65, 0x65, 0x72, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12,
|
||||
0x19, 0x0a, 0x15, 0x50, 0x65, 0x65, 0x72, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74,
|
||||
0x79, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x00, 0x12, 0x20, 0x0a, 0x1c, 0x50, 0x65,
|
||||
0x65, 0x72, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x53, 0x6f, 0x75, 0x72,
|
||||
0x63, 0x65, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x65, 0x73, 0x10, 0x01, 0x12, 0x1d, 0x0a, 0x19,
|
||||
0x50, 0x65, 0x65, 0x72, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x49, 0x50,
|
||||
0x76, 0x36, 0x4f, 0x76, 0x65, 0x72, 0x6c, 0x61, 0x79, 0x10, 0x02, 0x12, 0x25, 0x0a, 0x21, 0x50,
|
||||
0x65, 0x65, 0x72, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6d,
|
||||
0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x4d, 0x61, 0x70,
|
||||
0x10, 0x03, 0x2a, 0x5d, 0x0a, 0x0c, 0x52, 0x75, 0x6c, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63,
|
||||
0x6f, 0x6c, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12,
|
||||
0x07, 0x0a, 0x03, 0x41, 0x4c, 0x4c, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, 0x54, 0x43, 0x50, 0x10,
|
||||
0x02, 0x12, 0x07, 0x0a, 0x03, 0x55, 0x44, 0x50, 0x10, 0x03, 0x12, 0x08, 0x0a, 0x04, 0x49, 0x43,
|
||||
0x4d, 0x50, 0x10, 0x04, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x55, 0x53, 0x54, 0x4f, 0x4d, 0x10, 0x05,
|
||||
0x12, 0x0f, 0x0a, 0x0b, 0x4e, 0x45, 0x54, 0x42, 0x49, 0x52, 0x44, 0x5f, 0x53, 0x53, 0x48, 0x10,
|
||||
0x06, 0x2a, 0x20, 0x0a, 0x0d, 0x52, 0x75, 0x6c, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x12, 0x06, 0x0a, 0x02, 0x49, 0x4e, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x4f, 0x55,
|
||||
0x54, 0x10, 0x01, 0x2a, 0x22, 0x0a, 0x0a, 0x52, 0x75, 0x6c, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x12, 0x0a, 0x0a, 0x06, 0x41, 0x43, 0x43, 0x45, 0x50, 0x54, 0x10, 0x00, 0x12, 0x08, 0x0a,
|
||||
0x04, 0x44, 0x52, 0x4f, 0x50, 0x10, 0x01, 0x2a, 0x63, 0x0a, 0x0e, 0x45, 0x78, 0x70, 0x6f, 0x73,
|
||||
0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x0f, 0x0a, 0x0b, 0x45, 0x58, 0x50,
|
||||
0x4f, 0x53, 0x45, 0x5f, 0x48, 0x54, 0x54, 0x50, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x45, 0x58,
|
||||
0x50, 0x4f, 0x53, 0x45, 0x5f, 0x48, 0x54, 0x54, 0x50, 0x53, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a,
|
||||
0x45, 0x58, 0x50, 0x4f, 0x53, 0x45, 0x5f, 0x54, 0x43, 0x50, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a,
|
||||
0x45, 0x58, 0x50, 0x4f, 0x53, 0x45, 0x5f, 0x55, 0x44, 0x50, 0x10, 0x03, 0x12, 0x0e, 0x0a, 0x0a,
|
||||
0x45, 0x58, 0x50, 0x4f, 0x53, 0x45, 0x5f, 0x54, 0x4c, 0x53, 0x10, 0x04, 0x32, 0xd0, 0x07, 0x0a,
|
||||
0x11, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69,
|
||||
0x63, 0x65, 0x12, 0x45, 0x0a, 0x05, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x1c, 0x2e, 0x6d, 0x61,
|
||||
0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74,
|
||||
0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61,
|
||||
0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64,
|
||||
0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x46, 0x0a, 0x04, 0x53, 0x79, 0x6e,
|
||||
0x63, 0x12, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45,
|
||||
0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a,
|
||||
0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63,
|
||||
0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x30,
|
||||
0x01, 0x12, 0x42, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4b, 0x65,
|
||||
0x79, 0x12, 0x11, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45,
|
||||
0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1d, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e,
|
||||
0x74, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x33, 0x0a, 0x09, 0x69, 0x73, 0x48, 0x65, 0x61, 0x6c, 0x74,
|
||||
0x68, 0x79, 0x12, 0x11, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e,
|
||||
0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x11, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65,
|
||||
0x6e, 0x74, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x5a, 0x0a, 0x1a, 0x47, 0x65,
|
||||
0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x46, 0x6c, 0x6f, 0x77, 0x12, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67,
|
||||
0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d,
|
||||
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d,
|
||||
0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73,
|
||||
0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x58, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x50, 0x4b, 0x43,
|
||||
0x45, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x6c,
|
||||
0x6f, 0x77, 0x12, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e,
|
||||
0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
|
||||
0x1a, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e,
|
||||
0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00,
|
||||
0x12, 0x3d, 0x0a, 0x08, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x1c, 0x2e, 0x6d,
|
||||
0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70,
|
||||
0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x11, 0x2e, 0x6d, 0x61, 0x6e,
|
||||
0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12,
|
||||
0x3b, 0x0a, 0x06, 0x4c, 0x6f, 0x67, 0x6f, 0x75, 0x74, 0x12, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61,
|
||||
0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64,
|
||||
0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x11, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65,
|
||||
0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x47, 0x0a, 0x03,
|
||||
0x4a, 0x6f, 0x62, 0x12, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74,
|
||||
0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
|
||||
0x65, 0x1a, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45,
|
||||
0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22,
|
||||
0x00, 0x28, 0x01, 0x30, 0x01, 0x12, 0x51, 0x0a, 0x11, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x41,
|
||||
0x75, 0x74, 0x68, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x2e, 0x6d, 0x61, 0x6e,
|
||||
0x22, 0x1a, 0x0a, 0x18, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b,
|
||||
0x53, 0x65, 0x74, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x9b, 0x01, 0x0a,
|
||||
0x19, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x53, 0x65, 0x74,
|
||||
0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f,
|
||||
0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a,
|
||||
0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x6e,
|
||||
0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x6e,
|
||||
0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x42, 0x0a, 0x09, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64,
|
||||
0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6d, 0x61, 0x6e, 0x61,
|
||||
0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x4e, 0x65, 0x74, 0x77,
|
||||
0x6f, 0x72, 0x6b, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52,
|
||||
0x09, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x22, 0xb2, 0x01, 0x0a, 0x18, 0x41,
|
||||
0x67, 0x65, 0x6e, 0x74, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x50, 0x72, 0x6f, 0x76, 0x69,
|
||||
0x64, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x63,
|
||||
0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x09, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x70,
|
||||
0x69, 0x5f, 0x66, 0x6c, 0x61, 0x76, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09,
|
||||
0x61, 0x70, 0x69, 0x46, 0x6c, 0x61, 0x76, 0x6f, 0x72, 0x12, 0x2c, 0x0a, 0x12, 0x61, 0x6c, 0x6c,
|
||||
0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x18,
|
||||
0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x61, 0x6c, 0x6c, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x73,
|
||||
0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x6f, 0x64, 0x65, 0x6c,
|
||||
0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x2a,
|
||||
0x3a, 0x0a, 0x09, 0x4a, 0x6f, 0x62, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x12, 0x0a, 0x0e,
|
||||
0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x10, 0x00,
|
||||
0x12, 0x0d, 0x0a, 0x09, 0x73, 0x75, 0x63, 0x63, 0x65, 0x65, 0x64, 0x65, 0x64, 0x10, 0x01, 0x12,
|
||||
0x0a, 0x0a, 0x06, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x10, 0x02, 0x2a, 0x93, 0x01, 0x0a, 0x0e,
|
||||
0x50, 0x65, 0x65, 0x72, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x19,
|
||||
0x0a, 0x15, 0x50, 0x65, 0x65, 0x72, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79,
|
||||
0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x00, 0x12, 0x20, 0x0a, 0x1c, 0x50, 0x65, 0x65,
|
||||
0x72, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x53, 0x6f, 0x75, 0x72, 0x63,
|
||||
0x65, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x65, 0x73, 0x10, 0x01, 0x12, 0x1d, 0x0a, 0x19, 0x50,
|
||||
0x65, 0x65, 0x72, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x49, 0x50, 0x76,
|
||||
0x36, 0x4f, 0x76, 0x65, 0x72, 0x6c, 0x61, 0x79, 0x10, 0x02, 0x12, 0x25, 0x0a, 0x21, 0x50, 0x65,
|
||||
0x65, 0x72, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6d, 0x70,
|
||||
0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x4d, 0x61, 0x70, 0x10,
|
||||
0x03, 0x2a, 0x5d, 0x0a, 0x0c, 0x52, 0x75, 0x6c, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f,
|
||||
0x6c, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x07,
|
||||
0x0a, 0x03, 0x41, 0x4c, 0x4c, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, 0x54, 0x43, 0x50, 0x10, 0x02,
|
||||
0x12, 0x07, 0x0a, 0x03, 0x55, 0x44, 0x50, 0x10, 0x03, 0x12, 0x08, 0x0a, 0x04, 0x49, 0x43, 0x4d,
|
||||
0x50, 0x10, 0x04, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x55, 0x53, 0x54, 0x4f, 0x4d, 0x10, 0x05, 0x12,
|
||||
0x0f, 0x0a, 0x0b, 0x4e, 0x45, 0x54, 0x42, 0x49, 0x52, 0x44, 0x5f, 0x53, 0x53, 0x48, 0x10, 0x06,
|
||||
0x2a, 0x20, 0x0a, 0x0d, 0x52, 0x75, 0x6c, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x12, 0x06, 0x0a, 0x02, 0x49, 0x4e, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x4f, 0x55, 0x54,
|
||||
0x10, 0x01, 0x2a, 0x22, 0x0a, 0x0a, 0x52, 0x75, 0x6c, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x12, 0x0a, 0x0a, 0x06, 0x41, 0x43, 0x43, 0x45, 0x50, 0x54, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04,
|
||||
0x44, 0x52, 0x4f, 0x50, 0x10, 0x01, 0x2a, 0x63, 0x0a, 0x0e, 0x45, 0x78, 0x70, 0x6f, 0x73, 0x65,
|
||||
0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x0f, 0x0a, 0x0b, 0x45, 0x58, 0x50, 0x4f,
|
||||
0x53, 0x45, 0x5f, 0x48, 0x54, 0x54, 0x50, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x45, 0x58, 0x50,
|
||||
0x4f, 0x53, 0x45, 0x5f, 0x48, 0x54, 0x54, 0x50, 0x53, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x45,
|
||||
0x58, 0x50, 0x4f, 0x53, 0x45, 0x5f, 0x54, 0x43, 0x50, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x45,
|
||||
0x58, 0x50, 0x4f, 0x53, 0x45, 0x5f, 0x55, 0x44, 0x50, 0x10, 0x03, 0x12, 0x0e, 0x0a, 0x0a, 0x45,
|
||||
0x58, 0x50, 0x4f, 0x53, 0x45, 0x5f, 0x54, 0x4c, 0x53, 0x10, 0x04, 0x32, 0xa6, 0x08, 0x0a, 0x11,
|
||||
0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
|
||||
0x65, 0x12, 0x45, 0x0a, 0x05, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x1c, 0x2e, 0x6d, 0x61, 0x6e,
|
||||
0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65,
|
||||
0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67,
|
||||
0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d,
|
||||
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x4c, 0x0a, 0x0c, 0x43, 0x72, 0x65, 0x61,
|
||||
0x74, 0x65, 0x45, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x12, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67,
|
||||
0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d,
|
||||
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d,
|
||||
0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73,
|
||||
0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x4b, 0x0a, 0x0b, 0x52, 0x65, 0x6e, 0x65, 0x77, 0x45,
|
||||
0x78, 0x70, 0x6f, 0x73, 0x65, 0x12, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65,
|
||||
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x46, 0x0a, 0x04, 0x53, 0x79, 0x6e, 0x63,
|
||||
0x12, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e,
|
||||
0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x1c,
|
||||
0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72,
|
||||
0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x30, 0x01,
|
||||
0x12, 0x42, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4b, 0x65, 0x79,
|
||||
0x12, 0x11, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6d,
|
||||
0x70, 0x74, 0x79, 0x1a, 0x1d, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74,
|
||||
0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x22, 0x00, 0x12, 0x33, 0x0a, 0x09, 0x69, 0x73, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68,
|
||||
0x79, 0x12, 0x11, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45,
|
||||
0x6d, 0x70, 0x74, 0x79, 0x1a, 0x11, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e,
|
||||
0x74, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x5a, 0x0a, 0x1a, 0x47, 0x65, 0x74,
|
||||
0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x46, 0x6c, 0x6f, 0x77, 0x12, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65,
|
||||
0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65,
|
||||
0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65,
|
||||
0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73,
|
||||
0x61, 0x67, 0x65, 0x1a, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74,
|
||||
0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
|
||||
0x65, 0x22, 0x00, 0x12, 0x4a, 0x0a, 0x0a, 0x53, 0x74, 0x6f, 0x70, 0x45, 0x78, 0x70, 0x6f, 0x73,
|
||||
0x65, 0x12, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45,
|
||||
0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x58, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x50, 0x4b, 0x43, 0x45,
|
||||
0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x6c, 0x6f,
|
||||
0x77, 0x12, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45,
|
||||
0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a,
|
||||
0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63,
|
||||
0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x42,
|
||||
0x08, 0x5a, 0x06, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x33,
|
||||
0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12,
|
||||
0x3d, 0x0a, 0x08, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x1c, 0x2e, 0x6d, 0x61,
|
||||
0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74,
|
||||
0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x11, 0x2e, 0x6d, 0x61, 0x6e, 0x61,
|
||||
0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x3b,
|
||||
0x0a, 0x06, 0x4c, 0x6f, 0x67, 0x6f, 0x75, 0x74, 0x12, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67,
|
||||
0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d,
|
||||
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x11, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d,
|
||||
0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x47, 0x0a, 0x03, 0x4a,
|
||||
0x6f, 0x62, 0x12, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e,
|
||||
0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
|
||||
0x1a, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e,
|
||||
0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00,
|
||||
0x28, 0x01, 0x30, 0x01, 0x12, 0x51, 0x0a, 0x11, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x41, 0x75,
|
||||
0x74, 0x68, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61,
|
||||
0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64,
|
||||
0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65,
|
||||
0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65,
|
||||
0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x4c, 0x0a, 0x0c, 0x43, 0x72, 0x65, 0x61, 0x74,
|
||||
0x65, 0x45, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x12, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65,
|
||||
0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65,
|
||||
0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65,
|
||||
0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73,
|
||||
0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x4b, 0x0a, 0x0b, 0x52, 0x65, 0x6e, 0x65, 0x77, 0x45, 0x78,
|
||||
0x70, 0x6f, 0x73, 0x65, 0x12, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e,
|
||||
0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61,
|
||||
0x67, 0x65, 0x1a, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e,
|
||||
0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
|
||||
0x22, 0x00, 0x12, 0x4a, 0x0a, 0x0a, 0x53, 0x74, 0x6f, 0x70, 0x45, 0x78, 0x70, 0x6f, 0x73, 0x65,
|
||||
0x12, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e,
|
||||
0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x1c,
|
||||
0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72,
|
||||
0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x54,
|
||||
0x0a, 0x14, 0x47, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72,
|
||||
0x6b, 0x53, 0x65, 0x74, 0x75, 0x70, 0x12, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d,
|
||||
0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73,
|
||||
0x73, 0x61, 0x67, 0x65, 0x1a, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e,
|
||||
0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61,
|
||||
0x67, 0x65, 0x22, 0x00, 0x42, 0x08, 0x5a, 0x06, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -7852,7 +8075,7 @@ func file_management_proto_rawDescGZIP() []byte {
|
||||
}
|
||||
|
||||
var file_management_proto_enumTypes = make([]protoimpl.EnumInfo, 8)
|
||||
var file_management_proto_msgTypes = make([]protoimpl.MessageInfo, 83)
|
||||
var file_management_proto_msgTypes = make([]protoimpl.MessageInfo, 86)
|
||||
var file_management_proto_goTypes = []interface{}{
|
||||
(JobStatus)(0), // 0: management.JobStatus
|
||||
(PeerCapability)(0), // 1: management.PeerCapability
|
||||
@@ -7938,15 +8161,18 @@ var file_management_proto_goTypes = []interface{}{
|
||||
(*PolicyIds)(nil), // 81: management.PolicyIds
|
||||
(*UserIDList)(nil), // 82: management.UserIDList
|
||||
(*PeerIndexSet)(nil), // 83: management.PeerIndexSet
|
||||
nil, // 84: management.SSHAuth.MachineUsersEntry
|
||||
(*PortInfo_Range)(nil), // 85: management.PortInfo.Range
|
||||
nil, // 86: management.NetworkMapComponentsFull.RoutersMapEntry
|
||||
nil, // 87: management.NetworkMapComponentsFull.ResourcePoliciesMapEntry
|
||||
nil, // 88: management.NetworkMapComponentsFull.GroupIdToUserIdsEntry
|
||||
nil, // 89: management.NetworkMapComponentsFull.PostureFailedPeersEntry
|
||||
nil, // 90: management.PolicyCompact.AuthorizedGroupsEntry
|
||||
(*timestamppb.Timestamp)(nil), // 91: google.protobuf.Timestamp
|
||||
(*durationpb.Duration)(nil), // 92: google.protobuf.Duration
|
||||
(*AgentNetworkSetupRequest)(nil), // 84: management.AgentNetworkSetupRequest
|
||||
(*AgentNetworkSetupResponse)(nil), // 85: management.AgentNetworkSetupResponse
|
||||
(*AgentNetworkProviderInfo)(nil), // 86: management.AgentNetworkProviderInfo
|
||||
nil, // 87: management.SSHAuth.MachineUsersEntry
|
||||
(*PortInfo_Range)(nil), // 88: management.PortInfo.Range
|
||||
nil, // 89: management.NetworkMapComponentsFull.RoutersMapEntry
|
||||
nil, // 90: management.NetworkMapComponentsFull.ResourcePoliciesMapEntry
|
||||
nil, // 91: management.NetworkMapComponentsFull.GroupIdToUserIdsEntry
|
||||
nil, // 92: management.NetworkMapComponentsFull.PostureFailedPeersEntry
|
||||
nil, // 93: management.PolicyCompact.AuthorizedGroupsEntry
|
||||
(*timestamppb.Timestamp)(nil), // 94: google.protobuf.Timestamp
|
||||
(*durationpb.Duration)(nil), // 95: google.protobuf.Duration
|
||||
}
|
||||
var file_management_proto_depIdxs = []int32{
|
||||
11, // 0: management.JobRequest.bundle:type_name -> management.BundleParameters
|
||||
@@ -7958,7 +8184,7 @@ var file_management_proto_depIdxs = []int32{
|
||||
39, // 6: management.SyncResponse.remotePeers:type_name -> management.RemotePeerConfig
|
||||
36, // 7: management.SyncResponse.NetworkMap:type_name -> management.NetworkMap
|
||||
54, // 8: management.SyncResponse.Checks:type_name -> management.Checks
|
||||
91, // 9: management.SyncResponse.sessionExpiresAt:type_name -> google.protobuf.Timestamp
|
||||
94, // 9: management.SyncResponse.sessionExpiresAt:type_name -> google.protobuf.Timestamp
|
||||
64, // 10: management.SyncResponse.NetworkMapEnvelope:type_name -> management.NetworkMapEnvelope
|
||||
21, // 11: management.SyncMetaRequest.meta:type_name -> management.PeerSystemMeta
|
||||
21, // 12: management.LoginRequest.meta:type_name -> management.PeerSystemMeta
|
||||
@@ -7971,10 +8197,10 @@ var file_management_proto_depIdxs = []int32{
|
||||
27, // 19: management.LoginResponse.netbirdConfig:type_name -> management.NetbirdConfig
|
||||
34, // 20: management.LoginResponse.peerConfig:type_name -> management.PeerConfig
|
||||
54, // 21: management.LoginResponse.Checks:type_name -> management.Checks
|
||||
91, // 22: management.LoginResponse.sessionExpiresAt:type_name -> google.protobuf.Timestamp
|
||||
94, // 22: management.LoginResponse.sessionExpiresAt:type_name -> google.protobuf.Timestamp
|
||||
21, // 23: management.ExtendAuthSessionRequest.meta:type_name -> management.PeerSystemMeta
|
||||
91, // 24: management.ExtendAuthSessionResponse.sessionExpiresAt:type_name -> google.protobuf.Timestamp
|
||||
91, // 25: management.ServerKeyResponse.expiresAt:type_name -> google.protobuf.Timestamp
|
||||
94, // 24: management.ExtendAuthSessionResponse.sessionExpiresAt:type_name -> google.protobuf.Timestamp
|
||||
94, // 25: management.ServerKeyResponse.expiresAt:type_name -> google.protobuf.Timestamp
|
||||
28, // 26: management.NetbirdConfig.stuns:type_name -> management.HostConfig
|
||||
33, // 27: management.NetbirdConfig.turns:type_name -> management.ProtectedHostConfig
|
||||
28, // 28: management.NetbirdConfig.signal:type_name -> management.HostConfig
|
||||
@@ -7982,7 +8208,7 @@ var file_management_proto_depIdxs = []int32{
|
||||
30, // 30: management.NetbirdConfig.flow:type_name -> management.FlowConfig
|
||||
31, // 31: management.NetbirdConfig.metrics:type_name -> management.MetricsConfig
|
||||
6, // 32: management.HostConfig.protocol:type_name -> management.HostConfig.Protocol
|
||||
92, // 33: management.FlowConfig.interval:type_name -> google.protobuf.Duration
|
||||
95, // 33: management.FlowConfig.interval:type_name -> google.protobuf.Duration
|
||||
28, // 34: management.ProtectedHostConfig.hostConfig:type_name -> management.HostConfig
|
||||
40, // 35: management.PeerConfig.sshConfig:type_name -> management.SSHConfig
|
||||
35, // 36: management.PeerConfig.autoUpdate:type_name -> management.AutoUpdateSettings
|
||||
@@ -7995,7 +8221,7 @@ var file_management_proto_depIdxs = []int32{
|
||||
56, // 43: management.NetworkMap.routesFirewallRules:type_name -> management.RouteFirewallRule
|
||||
57, // 44: management.NetworkMap.forwardingRules:type_name -> management.ForwardingRule
|
||||
37, // 45: management.NetworkMap.sshAuth:type_name -> management.SSHAuth
|
||||
84, // 46: management.SSHAuth.machine_users:type_name -> management.SSHAuth.MachineUsersEntry
|
||||
87, // 46: management.SSHAuth.machine_users:type_name -> management.SSHAuth.MachineUsersEntry
|
||||
40, // 47: management.RemotePeerConfig.sshConfig:type_name -> management.SSHConfig
|
||||
32, // 48: management.SSHConfig.jwtConfig:type_name -> management.JWTConfig
|
||||
7, // 49: management.DeviceAuthorizationFlow.Provider:type_name -> management.DeviceAuthorizationFlow.provider
|
||||
@@ -8009,7 +8235,7 @@ var file_management_proto_depIdxs = []int32{
|
||||
4, // 57: management.FirewallRule.Action:type_name -> management.RuleAction
|
||||
2, // 58: management.FirewallRule.Protocol:type_name -> management.RuleProtocol
|
||||
55, // 59: management.FirewallRule.PortInfo:type_name -> management.PortInfo
|
||||
85, // 60: management.PortInfo.range:type_name -> management.PortInfo.Range
|
||||
88, // 60: management.PortInfo.range:type_name -> management.PortInfo.Range
|
||||
4, // 61: management.RouteFirewallRule.action:type_name -> management.RuleAction
|
||||
2, // 62: management.RouteFirewallRule.protocol:type_name -> management.RuleProtocol
|
||||
55, // 63: management.RouteFirewallRule.portInfo:type_name -> management.PortInfo
|
||||
@@ -8031,10 +8257,10 @@ var file_management_proto_depIdxs = []int32{
|
||||
49, // 79: management.NetworkMapComponentsFull.all_dns_records:type_name -> management.SimpleRecord
|
||||
48, // 80: management.NetworkMapComponentsFull.account_zones:type_name -> management.CustomZone
|
||||
78, // 81: management.NetworkMapComponentsFull.network_resources:type_name -> management.NetworkResourceRaw
|
||||
86, // 82: management.NetworkMapComponentsFull.routers_map:type_name -> management.NetworkMapComponentsFull.RoutersMapEntry
|
||||
87, // 83: management.NetworkMapComponentsFull.resource_policies_map:type_name -> management.NetworkMapComponentsFull.ResourcePoliciesMapEntry
|
||||
88, // 84: management.NetworkMapComponentsFull.group_id_to_user_ids:type_name -> management.NetworkMapComponentsFull.GroupIdToUserIdsEntry
|
||||
89, // 85: management.NetworkMapComponentsFull.posture_failed_peers:type_name -> management.NetworkMapComponentsFull.PostureFailedPeersEntry
|
||||
89, // 82: management.NetworkMapComponentsFull.routers_map:type_name -> management.NetworkMapComponentsFull.RoutersMapEntry
|
||||
90, // 83: management.NetworkMapComponentsFull.resource_policies_map:type_name -> management.NetworkMapComponentsFull.ResourcePoliciesMapEntry
|
||||
91, // 84: management.NetworkMapComponentsFull.group_id_to_user_ids:type_name -> management.NetworkMapComponentsFull.GroupIdToUserIdsEntry
|
||||
92, // 85: management.NetworkMapComponentsFull.posture_failed_peers:type_name -> management.NetworkMapComponentsFull.PostureFailedPeersEntry
|
||||
66, // 86: management.NetworkMapComponentsFull.proxy_patch:type_name -> management.ProxyPatch
|
||||
39, // 87: management.ProxyPatch.peers:type_name -> management.RemotePeerConfig
|
||||
39, // 88: management.ProxyPatch.offline_peers:type_name -> management.RemotePeerConfig
|
||||
@@ -8044,49 +8270,52 @@ var file_management_proto_depIdxs = []int32{
|
||||
57, // 92: management.ProxyPatch.forwarding_rules:type_name -> management.ForwardingRule
|
||||
4, // 93: management.PolicyCompact.action:type_name -> management.RuleAction
|
||||
2, // 94: management.PolicyCompact.protocol:type_name -> management.RuleProtocol
|
||||
85, // 95: management.PolicyCompact.port_ranges:type_name -> management.PortInfo.Range
|
||||
90, // 96: management.PolicyCompact.authorized_groups:type_name -> management.PolicyCompact.AuthorizedGroupsEntry
|
||||
88, // 95: management.PolicyCompact.port_ranges:type_name -> management.PortInfo.Range
|
||||
93, // 96: management.PolicyCompact.authorized_groups:type_name -> management.PolicyCompact.AuthorizedGroupsEntry
|
||||
72, // 97: management.PolicyCompact.source_resource:type_name -> management.ResourceCompact
|
||||
72, // 98: management.PolicyCompact.destination_resource:type_name -> management.ResourceCompact
|
||||
51, // 99: management.NameServerGroupRaw.nameservers:type_name -> management.NameServer
|
||||
80, // 100: management.NetworkRouterList.entries:type_name -> management.NetworkRouterEntry
|
||||
38, // 101: management.SSHAuth.MachineUsersEntry.value:type_name -> management.MachineUserIndexes
|
||||
79, // 102: management.NetworkMapComponentsFull.RoutersMapEntry.value:type_name -> management.NetworkRouterList
|
||||
81, // 103: management.NetworkMapComponentsFull.ResourcePoliciesMapEntry.value:type_name -> management.PolicyIds
|
||||
82, // 104: management.NetworkMapComponentsFull.GroupIdToUserIdsEntry.value:type_name -> management.UserIDList
|
||||
83, // 105: management.NetworkMapComponentsFull.PostureFailedPeersEntry.value:type_name -> management.PeerIndexSet
|
||||
73, // 106: management.PolicyCompact.AuthorizedGroupsEntry.value:type_name -> management.UserNameList
|
||||
8, // 107: management.ManagementService.Login:input_type -> management.EncryptedMessage
|
||||
8, // 108: management.ManagementService.Sync:input_type -> management.EncryptedMessage
|
||||
26, // 109: management.ManagementService.GetServerKey:input_type -> management.Empty
|
||||
26, // 110: management.ManagementService.isHealthy:input_type -> management.Empty
|
||||
8, // 111: management.ManagementService.GetDeviceAuthorizationFlow:input_type -> management.EncryptedMessage
|
||||
8, // 112: management.ManagementService.GetPKCEAuthorizationFlow:input_type -> management.EncryptedMessage
|
||||
8, // 113: management.ManagementService.SyncMeta:input_type -> management.EncryptedMessage
|
||||
8, // 114: management.ManagementService.Logout:input_type -> management.EncryptedMessage
|
||||
8, // 115: management.ManagementService.Job:input_type -> management.EncryptedMessage
|
||||
8, // 116: management.ManagementService.ExtendAuthSession:input_type -> management.EncryptedMessage
|
||||
8, // 117: management.ManagementService.CreateExpose:input_type -> management.EncryptedMessage
|
||||
8, // 118: management.ManagementService.RenewExpose:input_type -> management.EncryptedMessage
|
||||
8, // 119: management.ManagementService.StopExpose:input_type -> management.EncryptedMessage
|
||||
8, // 120: management.ManagementService.Login:output_type -> management.EncryptedMessage
|
||||
8, // 121: management.ManagementService.Sync:output_type -> management.EncryptedMessage
|
||||
25, // 122: management.ManagementService.GetServerKey:output_type -> management.ServerKeyResponse
|
||||
26, // 123: management.ManagementService.isHealthy:output_type -> management.Empty
|
||||
8, // 124: management.ManagementService.GetDeviceAuthorizationFlow:output_type -> management.EncryptedMessage
|
||||
8, // 125: management.ManagementService.GetPKCEAuthorizationFlow:output_type -> management.EncryptedMessage
|
||||
26, // 126: management.ManagementService.SyncMeta:output_type -> management.Empty
|
||||
26, // 127: management.ManagementService.Logout:output_type -> management.Empty
|
||||
8, // 128: management.ManagementService.Job:output_type -> management.EncryptedMessage
|
||||
8, // 129: management.ManagementService.ExtendAuthSession:output_type -> management.EncryptedMessage
|
||||
8, // 130: management.ManagementService.CreateExpose:output_type -> management.EncryptedMessage
|
||||
8, // 131: management.ManagementService.RenewExpose:output_type -> management.EncryptedMessage
|
||||
8, // 132: management.ManagementService.StopExpose:output_type -> management.EncryptedMessage
|
||||
120, // [120:133] is the sub-list for method output_type
|
||||
107, // [107:120] is the sub-list for method input_type
|
||||
107, // [107:107] is the sub-list for extension type_name
|
||||
107, // [107:107] is the sub-list for extension extendee
|
||||
0, // [0:107] is the sub-list for field type_name
|
||||
86, // 101: management.AgentNetworkSetupResponse.providers:type_name -> management.AgentNetworkProviderInfo
|
||||
38, // 102: management.SSHAuth.MachineUsersEntry.value:type_name -> management.MachineUserIndexes
|
||||
79, // 103: management.NetworkMapComponentsFull.RoutersMapEntry.value:type_name -> management.NetworkRouterList
|
||||
81, // 104: management.NetworkMapComponentsFull.ResourcePoliciesMapEntry.value:type_name -> management.PolicyIds
|
||||
82, // 105: management.NetworkMapComponentsFull.GroupIdToUserIdsEntry.value:type_name -> management.UserIDList
|
||||
83, // 106: management.NetworkMapComponentsFull.PostureFailedPeersEntry.value:type_name -> management.PeerIndexSet
|
||||
73, // 107: management.PolicyCompact.AuthorizedGroupsEntry.value:type_name -> management.UserNameList
|
||||
8, // 108: management.ManagementService.Login:input_type -> management.EncryptedMessage
|
||||
8, // 109: management.ManagementService.Sync:input_type -> management.EncryptedMessage
|
||||
26, // 110: management.ManagementService.GetServerKey:input_type -> management.Empty
|
||||
26, // 111: management.ManagementService.isHealthy:input_type -> management.Empty
|
||||
8, // 112: management.ManagementService.GetDeviceAuthorizationFlow:input_type -> management.EncryptedMessage
|
||||
8, // 113: management.ManagementService.GetPKCEAuthorizationFlow:input_type -> management.EncryptedMessage
|
||||
8, // 114: management.ManagementService.SyncMeta:input_type -> management.EncryptedMessage
|
||||
8, // 115: management.ManagementService.Logout:input_type -> management.EncryptedMessage
|
||||
8, // 116: management.ManagementService.Job:input_type -> management.EncryptedMessage
|
||||
8, // 117: management.ManagementService.ExtendAuthSession:input_type -> management.EncryptedMessage
|
||||
8, // 118: management.ManagementService.CreateExpose:input_type -> management.EncryptedMessage
|
||||
8, // 119: management.ManagementService.RenewExpose:input_type -> management.EncryptedMessage
|
||||
8, // 120: management.ManagementService.StopExpose:input_type -> management.EncryptedMessage
|
||||
8, // 121: management.ManagementService.GetAgentNetworkSetup:input_type -> management.EncryptedMessage
|
||||
8, // 122: management.ManagementService.Login:output_type -> management.EncryptedMessage
|
||||
8, // 123: management.ManagementService.Sync:output_type -> management.EncryptedMessage
|
||||
25, // 124: management.ManagementService.GetServerKey:output_type -> management.ServerKeyResponse
|
||||
26, // 125: management.ManagementService.isHealthy:output_type -> management.Empty
|
||||
8, // 126: management.ManagementService.GetDeviceAuthorizationFlow:output_type -> management.EncryptedMessage
|
||||
8, // 127: management.ManagementService.GetPKCEAuthorizationFlow:output_type -> management.EncryptedMessage
|
||||
26, // 128: management.ManagementService.SyncMeta:output_type -> management.Empty
|
||||
26, // 129: management.ManagementService.Logout:output_type -> management.Empty
|
||||
8, // 130: management.ManagementService.Job:output_type -> management.EncryptedMessage
|
||||
8, // 131: management.ManagementService.ExtendAuthSession:output_type -> management.EncryptedMessage
|
||||
8, // 132: management.ManagementService.CreateExpose:output_type -> management.EncryptedMessage
|
||||
8, // 133: management.ManagementService.RenewExpose:output_type -> management.EncryptedMessage
|
||||
8, // 134: management.ManagementService.StopExpose:output_type -> management.EncryptedMessage
|
||||
8, // 135: management.ManagementService.GetAgentNetworkSetup:output_type -> management.EncryptedMessage
|
||||
122, // [122:136] is the sub-list for method output_type
|
||||
108, // [108:122] is the sub-list for method input_type
|
||||
108, // [108:108] is the sub-list for extension type_name
|
||||
108, // [108:108] is the sub-list for extension extendee
|
||||
0, // [0:108] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_management_proto_init() }
|
||||
@@ -9007,7 +9236,43 @@ func file_management_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_management_proto_msgTypes[76].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*AgentNetworkSetupRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_management_proto_msgTypes[77].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*AgentNetworkSetupResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_management_proto_msgTypes[78].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*AgentNetworkProviderInfo); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_management_proto_msgTypes[80].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*PortInfo_Range); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -9040,7 +9305,7 @@ func file_management_proto_init() {
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_management_proto_rawDesc,
|
||||
NumEnums: 8,
|
||||
NumMessages: 83,
|
||||
NumMessages: 86,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
|
||||
@@ -68,6 +68,13 @@ service ManagementService {
|
||||
|
||||
// StopExpose terminates an active expose session
|
||||
rpc StopExpose(EncryptedMessage) returns (EncryptedMessage) {}
|
||||
|
||||
// GetAgentNetworkSetup returns the Agent Network connection info the
|
||||
// calling peer's groups authorize: proxy endpoint plus effective
|
||||
// providers and models. Caller-scoped by the peer's WireGuard key.
|
||||
// EncryptedMessage of the request has a body of AgentNetworkSetupRequest.
|
||||
// EncryptedMessage of the response has a body of AgentNetworkSetupResponse.
|
||||
rpc GetAgentNetworkSetup(EncryptedMessage) returns (EncryptedMessage) {}
|
||||
}
|
||||
|
||||
message EncryptedMessage {
|
||||
@@ -1207,3 +1214,34 @@ message UserIDList {
|
||||
message PeerIndexSet {
|
||||
repeated uint32 peer_indexes = 1;
|
||||
}
|
||||
|
||||
message AgentNetworkSetupRequest {}
|
||||
|
||||
message AgentNetworkSetupResponse {
|
||||
// configured is false when the account has no Agent Network set up or
|
||||
// the calling peer's groups authorize none of it — the two cases are
|
||||
// deliberately indistinguishable.
|
||||
bool configured = 1;
|
||||
// endpoint is the account's proxy base URL, e.g.
|
||||
// "https://calm-otter.proxy.example.com". Reachable over the NetBird
|
||||
// tunnel only. Empty when configured is false.
|
||||
string endpoint = 2;
|
||||
repeated AgentNetworkProviderInfo providers = 3;
|
||||
}
|
||||
|
||||
message AgentNetworkProviderInfo {
|
||||
// name is the operator-assigned provider label, e.g. "Bedrock prod".
|
||||
string name = 1;
|
||||
// catalog_id names the catalog entry, e.g. "anthropic_api", "bedrock_api".
|
||||
string catalog_id = 2;
|
||||
// api_flavor is the request-body shape the provider speaks ("anthropic",
|
||||
// "openai"); empty when the proxy dispatches it by URL path instead.
|
||||
string api_flavor = 3;
|
||||
// all_models_allowed is true when no model allowlist restricts this
|
||||
// provider for the caller; models then lists the declared/catalog models
|
||||
// as a courtesy (possibly none for gateway-style providers).
|
||||
bool all_models_allowed = 4;
|
||||
// models is the effective model allowlist for the caller (or the
|
||||
// declared/catalog models when all_models_allowed is true).
|
||||
repeated string models = 5;
|
||||
}
|
||||
|
||||
@@ -65,6 +65,12 @@ type ManagementServiceClient interface {
|
||||
RenewExpose(ctx context.Context, in *EncryptedMessage, opts ...grpc.CallOption) (*EncryptedMessage, error)
|
||||
// StopExpose terminates an active expose session
|
||||
StopExpose(ctx context.Context, in *EncryptedMessage, opts ...grpc.CallOption) (*EncryptedMessage, error)
|
||||
// GetAgentNetworkSetup returns the Agent Network connection info the
|
||||
// calling peer's groups authorize: proxy endpoint plus effective
|
||||
// providers and models. Caller-scoped by the peer's WireGuard key.
|
||||
// EncryptedMessage of the request has a body of AgentNetworkSetupRequest.
|
||||
// EncryptedMessage of the response has a body of AgentNetworkSetupResponse.
|
||||
GetAgentNetworkSetup(ctx context.Context, in *EncryptedMessage, opts ...grpc.CallOption) (*EncryptedMessage, error)
|
||||
}
|
||||
|
||||
type managementServiceClient struct {
|
||||
@@ -237,6 +243,15 @@ func (c *managementServiceClient) StopExpose(ctx context.Context, in *EncryptedM
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *managementServiceClient) GetAgentNetworkSetup(ctx context.Context, in *EncryptedMessage, opts ...grpc.CallOption) (*EncryptedMessage, error) {
|
||||
out := new(EncryptedMessage)
|
||||
err := c.cc.Invoke(ctx, "/management.ManagementService/GetAgentNetworkSetup", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// ManagementServiceServer is the server API for ManagementService service.
|
||||
// All implementations must embed UnimplementedManagementServiceServer
|
||||
// for forward compatibility
|
||||
@@ -288,6 +303,12 @@ type ManagementServiceServer interface {
|
||||
RenewExpose(context.Context, *EncryptedMessage) (*EncryptedMessage, error)
|
||||
// StopExpose terminates an active expose session
|
||||
StopExpose(context.Context, *EncryptedMessage) (*EncryptedMessage, error)
|
||||
// GetAgentNetworkSetup returns the Agent Network connection info the
|
||||
// calling peer's groups authorize: proxy endpoint plus effective
|
||||
// providers and models. Caller-scoped by the peer's WireGuard key.
|
||||
// EncryptedMessage of the request has a body of AgentNetworkSetupRequest.
|
||||
// EncryptedMessage of the response has a body of AgentNetworkSetupResponse.
|
||||
GetAgentNetworkSetup(context.Context, *EncryptedMessage) (*EncryptedMessage, error)
|
||||
mustEmbedUnimplementedManagementServiceServer()
|
||||
}
|
||||
|
||||
@@ -334,6 +355,9 @@ func (UnimplementedManagementServiceServer) RenewExpose(context.Context, *Encryp
|
||||
func (UnimplementedManagementServiceServer) StopExpose(context.Context, *EncryptedMessage) (*EncryptedMessage, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method StopExpose not implemented")
|
||||
}
|
||||
func (UnimplementedManagementServiceServer) GetAgentNetworkSetup(context.Context, *EncryptedMessage) (*EncryptedMessage, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetAgentNetworkSetup not implemented")
|
||||
}
|
||||
func (UnimplementedManagementServiceServer) mustEmbedUnimplementedManagementServiceServer() {}
|
||||
|
||||
// UnsafeManagementServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||
@@ -592,6 +616,24 @@ func _ManagementService_StopExpose_Handler(srv interface{}, ctx context.Context,
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _ManagementService_GetAgentNetworkSetup_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(EncryptedMessage)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ManagementServiceServer).GetAgentNetworkSetup(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/management.ManagementService/GetAgentNetworkSetup",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ManagementServiceServer).GetAgentNetworkSetup(ctx, req.(*EncryptedMessage))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// ManagementService_ServiceDesc is the grpc.ServiceDesc for ManagementService service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
@@ -643,6 +685,10 @@ var ManagementService_ServiceDesc = grpc.ServiceDesc{
|
||||
MethodName: "StopExpose",
|
||||
Handler: _ManagementService_StopExpose_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetAgentNetworkSetup",
|
||||
Handler: _ManagementService_GetAgentNetworkSetup_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user