Skip to content

Commit

Permalink
most minimal public sharing (proxy only) to elaborate plumbing (#463)
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelquigley committed Aug 26, 2024
1 parent b69025c commit a9bac04
Show file tree
Hide file tree
Showing 7 changed files with 569 additions and 72 deletions.
365 changes: 295 additions & 70 deletions agent/agentGrpc/agent.pb.go

Large diffs are not rendered by default.

18 changes: 18 additions & 0 deletions agent/agentGrpc/agent.proto
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ syntax = "proto3";
option go_package = "github.com/openziti/zrok/agent/agentGrpc";

service Agent {
rpc PublicShare(PublicShareRequest) returns (PublicShareReply) {}
rpc Status(StatusRequest) returns (StatusReply) {}
rpc Version(VersionRequest) returns (VersionReply) {}
}
Expand All @@ -13,6 +14,23 @@ message AccessDetail {
repeated string responseHeaders = 3;
}

message PublicShareReply {
string token = 1;
}

message PublicShareRequest {
string target = 1;
repeated string basicAuth = 2;
repeated string frontendSelection = 3;
string backendMode = 4;
bool insecure = 5;
string oauthProvider = 6;
repeated string oauthEmailAddressPatterns = 7;
string oauthCheckInterval = 8;
bool closed = 9;
repeated string accessGrants = 10;
}

message ShareDetail {
string token = 1;
string shareMode = 2;
Expand Down
42 changes: 40 additions & 2 deletions agent/agentGrpc/agent_grpc.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions agent/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ type share struct {
oauthCheckInterval time.Duration
closed bool
accessGrants []string

handler backendHandler
}

type access struct {
Expand All @@ -34,3 +36,7 @@ type agentGrpcImpl struct {
agentGrpc.UnimplementedAgentServer
a *Agent
}

type backendHandler interface {
Run() error
}
93 changes: 93 additions & 0 deletions agent/publicShare.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package agent

import (
"context"
"errors"
"github.com/openziti/zrok/agent/agentGrpc"
"github.com/openziti/zrok/endpoints/proxy"
"github.com/openziti/zrok/environment"
"github.com/openziti/zrok/sdk/golang/sdk"
"github.com/sirupsen/logrus"
"time"
)

func (i *agentGrpcImpl) PublicShare(_ context.Context, req *agentGrpc.PublicShareRequest) (*agentGrpc.PublicShareReply, error) {
root, err := environment.LoadRoot()
if err != nil {
return nil, err
}

if !root.IsEnabled() {
return nil, errors.New("unable to load environment; did you 'zrok enable'?")
}

zif, err := root.ZitiIdentityNamed(root.EnvironmentIdentityName())
if err != nil {
return nil, err
}

shrReq := &sdk.ShareRequest{
BackendMode: sdk.BackendMode(req.BackendMode),
ShareMode: sdk.PublicShareMode,
Frontends: req.FrontendSelection,
BasicAuth: req.BasicAuth,
Target: req.Target,
}
if req.Closed {
shrReq.PermissionMode = sdk.ClosedPermissionMode
shrReq.AccessGrants = req.AccessGrants
}
if req.OauthProvider != "" {
shrReq.OauthProvider = req.OauthProvider
shrReq.OauthEmailAddressPatterns = req.OauthEmailAddressPatterns
checkInterval, err := time.ParseDuration(req.GetOauthCheckInterval())
if err != nil {
return nil, err
}
shrReq.OauthAuthorizationCheckInterval = checkInterval
}
shr, err := sdk.CreateShare(root, shrReq)
if err != nil {
return nil, err
}

switch req.BackendMode {
case "proxy":
cfg := &proxy.BackendConfig{
IdentityPath: zif,
EndpointAddress: req.Target,
ShrToken: shr.Token,
Insecure: req.Insecure,
}

be, err := proxy.NewBackend(cfg)
if err != nil {
return nil, err
}

agentShr := &share{
token: shr.Token,
target: req.Target,
basicAuth: req.BasicAuth,
frontendSelection: shr.FrontendEndpoints,
shareMode: sdk.PublicShareMode,
backendMode: sdk.BackendMode(req.BackendMode),
insecure: req.Insecure,
oauthProvider: req.OauthProvider,
oauthEmailAddressPatterns: req.OauthEmailAddressPatterns,
oauthCheckInterval: shrReq.OauthAuthorizationCheckInterval,
closed: req.Closed,
accessGrants: req.AccessGrants,
handler: be,
}

i.a.shares[shr.Token] = agentShr
go func() {
if err := agentShr.handler.Run(); err != nil {
logrus.Errorf("error running proxy backend: %v", err)
}
}()
}

return &agentGrpc.PublicShareReply{Token: shr.Token}, nil
}
111 changes: 111 additions & 0 deletions cmd/zrok/agentSharePublic.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package main

import (
"context"
"fmt"
"github.com/openziti/zrok/agent/agentClient"
"github.com/openziti/zrok/agent/agentGrpc"
"github.com/openziti/zrok/environment"
"github.com/openziti/zrok/tui"
"github.com/spf13/cobra"
"time"
)

func init() {
agentShareCmd.AddCommand(newAgentSharePublicCommand().cmd)
}

type agentSharePublicCommand struct {
basicAuth []string
frontendSelection []string
backendMode string
headless bool
insecure bool
oauthProvider string
oauthEmailAddressPatterns []string
oauthCheckInterval time.Duration
closed bool
accessGrants []string
cmd *cobra.Command
}

func newAgentSharePublicCommand() *agentSharePublicCommand {
cmd := &cobra.Command{
Use: "public <target>",
Short: "Create a public share in the zrok Agent",
Args: cobra.ExactArgs(1),
}
command := &agentSharePublicCommand{cmd: cmd}
defaultFrontends := []string{"public"}
if root, err := environment.LoadRoot(); err == nil {
defaultFrontend, _ := root.DefaultFrontend()
defaultFrontends = []string{defaultFrontend}
}
cmd.Flags().StringArrayVar(&command.frontendSelection, "frontend", defaultFrontends, "Selected frontends to use for the share")
cmd.Flags().StringVarP(&command.backendMode, "backend-mode", "b", "proxy", "The backend mode {proxy, web, caddy, drive}")
cmd.Flags().BoolVar(&command.headless, "headless", false, "Disable TUI and run headless")
cmd.Flags().BoolVar(&command.insecure, "insecure", false, "Enable insecure TLS certificate validation for <target>")
cmd.Flags().BoolVar(&command.closed, "closed", false, "Enable closed permission mode (see --access-grant)")
cmd.Flags().StringArrayVar(&command.accessGrants, "access-grant", []string{}, "zrok accounts that are allowed to access this share (see --closed)")

cmd.Flags().StringArrayVar(&command.basicAuth, "basic-auth", []string{}, "Basic authentication users (<username:password>,...)")
cmd.Flags().StringVar(&command.oauthProvider, "oauth-provider", "", "Enable OAuth provider [google, github]")
cmd.Flags().StringArrayVar(&command.oauthEmailAddressPatterns, "oauth-email-address-patterns", []string{}, "Allow only these email domain globs to authenticate via OAuth")
cmd.Flags().DurationVar(&command.oauthCheckInterval, "oauth-check-interval", 3*time.Hour, "Maximum lifetime for OAuth authentication; reauthenticate after expiry")
cmd.MarkFlagsMutuallyExclusive("basic-auth", "oauth-provider")

cmd.Run = command.run
return command
}

func (cmd *agentSharePublicCommand) run(_ *cobra.Command, args []string) {
var target string

switch cmd.backendMode {
case "proxy":
v, err := parseUrl(args[0])
if err != nil {
if !panicInstead {
tui.Error("invalid target endpoint URL", err)
}
panic(err)
}
target = v
}

root, err := environment.LoadRoot()
if err != nil {
if !panicInstead {
tui.Error("unable to load environment", err)
}
panic(err)
}

if !root.IsEnabled() {
tui.Error("unable to load environment; did you 'zrok enable'?", nil)
}

client, conn, err := agentClient.NewClient(root)
if err != nil {
tui.Error("error connecting to agent", err)
}
defer conn.Close()

shr, err := client.PublicShare(context.Background(), &agentGrpc.PublicShareRequest{
Target: target,
BasicAuth: cmd.basicAuth,
FrontendSelection: cmd.frontendSelection,
BackendMode: cmd.backendMode,
Insecure: cmd.insecure,
OauthProvider: cmd.oauthProvider,
OauthEmailAddressPatterns: cmd.oauthEmailAddressPatterns,
OauthCheckInterval: cmd.oauthCheckInterval.String(),
Closed: cmd.closed,
AccessGrants: cmd.accessGrants,
})
if err != nil {
tui.Error("error creating share", err)
}

fmt.Println(shr.GetToken())
}
6 changes: 6 additions & 0 deletions cmd/zrok/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ func init() {
adminCmd.AddCommand(adminListCmd)
adminCmd.AddCommand(adminUpdateCmd)
rootCmd.AddCommand(agentCmd)
agentCmd.AddCommand(agentShareCmd)
testCmd.AddCommand(loopCmd)
rootCmd.AddCommand(adminCmd)
rootCmd.AddCommand(configCmd)
Expand Down Expand Up @@ -82,6 +83,11 @@ var agentCmd = &cobra.Command{
Aliases: []string{"daemon"},
}

var agentShareCmd = &cobra.Command{
Use: "share",
Short: "zrok Agent sharing commands",
}

var configCmd = &cobra.Command{
Use: "config",
Short: "Configure your zrok environment",
Expand Down

0 comments on commit a9bac04

Please sign in to comment.