Skip to content

Commit

Permalink
Add client daemon repo, server, and cmd
Browse files Browse the repository at this point in the history
The commands added are:
boundary daemon start
boundary daemon stop
boundary daemon add-token
boundary daemon status
boundary search

If these actions are performed on a platform that doesn't support sqlite
natively in go an error is returned.

Besides some hooks into the cmd package all the significant logic
resides in internal/clientcache

feat (cmds/authenticate): output the token name when storing token

feat: update go-dbw which now uses pure go sqlite driver

refact (base.Command): export FlagOutputCurlString

Exporting FlagOutputCurlString allows other commands that embed
the base.Command to access the flag as needed

feat: add a cache Repository to manage cache storage

feat: add a "cache" CLI command

This new command will support both managing and searching the
local CLI cache daemon.

feat: start cache daemon as needed when issue CLI commands

Move files to new directories and add persona table (#3526)

* Add persona table and move files to new directories

Client daemon now uses unix sockets and update pathing (#3535)

* Add unix socket listen and dialers with file permissions applied

* Update the pathing to match RFC

Cache refreshing now uses all stored personas. (#3545)

Updating headers for LLB files

Decouple daemon and cache server (#3566)

* Separate daemon from server

* Add persona handler to daemon server (#3579)

Moved search to use mql and added tests for the search command (#3589)

* search uses hashicorp/mql

Windows support for client side daemon (#3618)

* exec.Command for background process

* Log to stderr when in foreground and file always

* Use pid files across platform for start and stop

Requests with version info must match the daemon's version (#3640)

* requests with version info must match daemons

Update dependencies and breakout cgo/pure go sqlite drivers  (#3657)

upgrade go-dbw deps and add cgo build tags

Enable graceful shutdown in windows (#3695)

* Enable graceful shutdown in windows

Co-authored-by: Jim <jlambert@hashicorp.com>

Targets delete when a persona changes address or user id (#3673)

* Handle cache refresh in repo

Add sessions to the client side cache (#3682)

* Add sessions to repository

* Search command supports sessions

* adding session related tests to db and refresh

Change cache schema from personas to tokens+users (#3737)

* Change from personas to tokens+users

* Separate keyring tokens from auth tokens

Add support for keyringless auth tokens (#3765)

* Add support for keyringless auth tokens

Remove expired auth tokens from cache (#3768)

* Remove expired auth tokens from cache

Complete the TODO of checking for inflight tx (#3779)

Delete tokens that the controller says are invalid (#3782)

fix search test with boundary token check (#3799)

Collect resource info in repository_<resource>s.go (#3769)

* Collect resource info in repository_<resource>s.go

* Move search logic into the domain (#3794)

Daemon and search restricted to supported platforms (#3801)

* Daemon and search restricted to supported platforms

Reorganize the clientcache packages (#3814)

* Refactor for self contained domain logic

* Put clientcache stuff under internal
  • Loading branch information
jimlambrt authored and johanbrandhorst committed Jan 5, 2024
1 parent 6ba3676 commit fba9d1c
Show file tree
Hide file tree
Showing 71 changed files with 8,980 additions and 972 deletions.
50 changes: 38 additions & 12 deletions api/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"net/url"
"os"
"path"
"path/filepath"
"strconv"
"strings"
"sync"
Expand Down Expand Up @@ -57,7 +58,12 @@ type Config struct {
// HttpClient.
Addr string

// Token is the client token that reuslts from authentication and can be
// Set when the Addr is a unix socket. The parsing of this field takes
// a filename approach instead of a URL approach since parsing file names
// as a URL may error out on some platforms.
socketAddr string

// Token is the client token that results from authentication and can be
// used to make calls into Boundary
Token string

Expand Down Expand Up @@ -254,6 +260,16 @@ func (c *Config) ConfigureTLS() error {
// This also removes any trailing "/v1"; we'll use that in our commands so we
// don't require it from users.
func (c *Config) setAddr(addr string) error {
if strings.HasPrefix(addr, "unix://") {
c.socketAddr = strings.TrimPrefix(addr, "unix://")
c.socketAddr = filepath.Clean(c.socketAddr)

// Update the specified address to the cleaned up version
c.Addr = fmt.Sprintf("unix://%s", c.socketAddr)
return nil
}
c.socketAddr = ""

u, err := url.Parse(addr)
if err != nil {
return fmt.Errorf("error parsing address: %w", err)
Expand Down Expand Up @@ -582,6 +598,7 @@ func (c *Client) Clone() *Client {
config := c.config

newConfig := &Config{
socketAddr: config.socketAddr,
Addr: config.Addr,
Token: config.Token,
RecoveryKmsWrapper: config.RecoveryKmsWrapper,
Expand Down Expand Up @@ -645,31 +662,29 @@ func (c *Client) NewRequest(ctx context.Context, method, requestPath string, bod
}

c.modifyLock.RLock()
addr := c.config.Addr
srvLookup := c.config.SRVLookup
token := c.config.Token
httpClient := c.config.HttpClient
headers := copyHeaders(c.config.Headers)
c.modifyLock.RUnlock()

u, err := url.Parse(addr)
if err != nil {
return nil, err
}

if strings.HasPrefix(addr, "unix://") {
socket := strings.TrimPrefix(addr, "unix://")
var hostHeader string
var u *url.URL
switch {
case c.config.socketAddr != "":
transport := httpClient.Transport.(*http.Transport)
transport.DialContext = func(context.Context, string, string) (net.Conn, error) {
dialer := net.Dialer{}
return dialer.DialContext(ctx, "unix", socket)
return dialer.DialContext(ctx, "unix", c.config.socketAddr)
}

// Since the address points to a unix domain socket, the scheme in the
// *URL would be set to `unix`. The *URL in the client is expected to
// be pointing to the protocol used in the application layer and not to
// the transport layer. Hence, setting the fields accordingly.
u = &url.URL{}
u.Scheme = "http"
u.Host = c.config.socketAddr
u.Path = ""

// Go 1.21.0 introduced strict host header validation for clients.
Expand All @@ -680,7 +695,17 @@ func (c *Client) NewRequest(ctx context.Context, method, requestPath string, bod
// that isn't the actual unix domain socket address. Following
// Docker's lead (https://github.com/moby/moby/pull/45942),
// use a localhost TLD.
u.Host = "api.boundary.localhost"
hostHeader = "api.boundary.localhost"
case c.config.Addr != "":
addr := c.config.Addr
var err error
u, err = url.Parse(addr)
if err != nil {
return nil, err
}
hostHeader = u.Host
default:
return nil, errors.New("no valid address discovered")
}

host := u.Host
Expand All @@ -707,8 +732,9 @@ func (c *Client) NewRequest(ctx context.Context, method, requestPath string, bod
Host: host,
Path: path.Join(u.Path, "/v1/", requestPath),
},
Host: u.Host,
Host: hostHeader,
}

req.Header = headers
req.Header.Set("authorization", "Bearer "+token)
req.Header.Set("content-type", "application/json")
Expand Down
87 changes: 48 additions & 39 deletions api/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,71 +11,80 @@ import (

func TestConfigSetAddress(t *testing.T) {
type test struct {
name string
input string
address string
err string
name string
input string
address string
socketAddr string
}

tests := []test{
{
"bare",
"http://127.0.0.1:9200",
"http://127.0.0.1:9200",
"",
name: "bare",
input: "http://127.0.0.1:9200",
address: "http://127.0.0.1:9200",
},
{
"bare with version",
"http://127.0.0.1:9200/v1",
"http://127.0.0.1:9200",
"",
name: "bare with version",
input: "http://127.0.0.1:9200/v1",
address: "http://127.0.0.1:9200",
},
{
"bare with version and trailing slash",
"http://127.0.0.1:9200/v1/",
"http://127.0.0.1:9200",
"",
name: "bare with version and trailing slash",
input: "http://127.0.0.1:9200/v1/",
address: "http://127.0.0.1:9200",
},
{
"valid top level scope",
"http://127.0.0.1:9200/v1/scopes",
"http://127.0.0.1:9200",
"",
name: "valid top level scope",
input: "http://127.0.0.1:9200/v1/scopes",
address: "http://127.0.0.1:9200",
},
{
"valid scope",
"http://127.0.0.1:9200/v1/scopes/scopeid",
"http://127.0.0.1:9200",
"",
name: "valid scope",
input: "http://127.0.0.1:9200/v1/scopes/scopeid",
address: "http://127.0.0.1:9200",
},
{
"longer path project",
"http://127.0.0.1:9200/v1/auth-methods",
"http://127.0.0.1:9200",
"",
name: "longer path project",
input: "http://127.0.0.1:9200/v1/auth-methods",
address: "http://127.0.0.1:9200",
},
{
"valid project",
"http://127.0.0.1:9200/my-install",
"http://127.0.0.1:9200/my-install",
"",
name: "valid project",
input: "http://127.0.0.1:9200/my-install",
address: "http://127.0.0.1:9200/my-install",
},
{
"valid project path containing v1",
"http://127.0.0.1:9200/randomPathHasv1InIt",
"http://127.0.0.1:9200/randomPathHasv1InIt",
"",
name: "valid project path containing v1",
input: "http://127.0.0.1:9200/randomPathHasv1InIt",
address: "http://127.0.0.1:9200/randomPathHasv1InIt",
},
{
name: "unix socket with linux pathing",
input: "unix:///home/username/.boundary/socketdir/boundary.sock",
address: "unix:///home/username/.boundary/socketdir/boundary.sock",
socketAddr: "/home/username/.boundary/socketdir/boundary.sock",
},
{
name: "unix socket with weird linux pathing",
input: "unix:///home/username/.boundary/something/../socketdir/boundary.sock",
address: "unix:///home/username/.boundary/socketdir/boundary.sock",
socketAddr: "/home/username/.boundary/socketdir/boundary.sock",
},
{
name: "unix socket with windows pathing",
input: "unix://C:\\Users\\Admin\\AppData\\boundary.sock",
address: "unix://C:\\Users\\Admin\\AppData\\boundary.sock",
socketAddr: "C:\\Users\\Admin\\AppData\\boundary.sock",
},
}

for _, v := range tests {
t.Run(v.name, func(t *testing.T) {
var c Config
err := c.setAddr(v.input)
if err != nil {
assert.Equal(t, v.err, err.Error())
}
assert.NoError(t, err)
assert.Equal(t, v.address, c.Addr)
assert.Equal(t, v.socketAddr, c.socketAddr)
})
}
}
29 changes: 23 additions & 6 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,9 @@ require github.com/hashicorp/go-dbw v0.1.1

require (
github.com/DATA-DOG/go-sqlmock v1.5.0
github.com/cenkalti/backoff/v4 v4.2.1
github.com/creack/pty v1.1.20
github.com/cenkalti/backoff/v4 v4.2.0
github.com/creack/pty v1.1.18
github.com/glebarez/sqlite v1.9.0
github.com/golang/protobuf v1.5.3
github.com/hashicorp/cap/ldap v0.0.0-20231012003312-273118a6e3b8
github.com/hashicorp/dbassert v0.0.0-20231012105025-1bc1bd88e22b
Expand All @@ -102,12 +103,30 @@ require (
github.com/kelseyhightower/envconfig v1.4.0
github.com/miekg/dns v1.1.56
github.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a
github.com/mitchellh/go-homedir v1.1.0
github.com/sevlyar/go-daemon v0.1.6
golang.org/x/exp v0.0.0-20231006140011-7918f672742d
golang.org/x/net v0.17.0
google.golang.org/genproto/googleapis/api v0.0.0-20231030173426-d783a09b4405
gopkg.in/square/go-jose.v2 v2.6.0
)

require (
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/mattn/go-sqlite3 v2.0.1+incompatible // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
modernc.org/libc v1.22.5 // indirect
modernc.org/mathutil v1.5.0 // indirect
modernc.org/memory v1.5.0 // indirect
modernc.org/sqlite v1.23.1 // indirect
)

require (
github.com/glebarez/go-sqlite v1.21.2 // indirect
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect
gorm.io/driver/sqlite v1.5.4 // indirect
)

require (
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect
github.com/AlecAivazis/survey/v2 v2.3.2 // indirect
Expand Down Expand Up @@ -148,6 +167,7 @@ require (
github.com/hashicorp/go-kms-wrapping/plugin/v2 v2.0.5 // indirect
github.com/hashicorp/go-plugin v1.5.2 // indirect
github.com/hashicorp/go-secure-stdlib/tlsutil v0.1.3 // indirect
github.com/hashicorp/mql v0.0.0-20230814234610-74af33a21d7f
github.com/hashicorp/vault/sdk v0.3.0 // indirect
github.com/hashicorp/yamux v0.1.1 // indirect
github.com/huandu/xstrings v1.4.0 // indirect
Expand All @@ -160,16 +180,14 @@ require (
github.com/jackc/pgtype v1.14.0 // indirect
github.com/jefferai/go-libsecret v0.0.0-20210525195240-b53481abef97 // indirect
github.com/jefferai/isbadcipher v0.0.0-20190226160619-51d2077c035f // indirect
github.com/jinzhu/gorm v1.9.12 // indirect
github.com/jinzhu/gorm v1.9.16 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
github.com/lib/pq v1.10.9 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-sqlite3 v2.0.1+incompatible // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/moby/term v0.5.0 // indirect
Expand Down Expand Up @@ -202,5 +220,4 @@ require (
google.golang.org/genproto/googleapis/rpc v0.0.0-20231030173426-d783a09b4405 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
gorm.io/driver/sqlite v1.5.4 // indirect
)
Loading

0 comments on commit fba9d1c

Please sign in to comment.