Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 24 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,32 +54,14 @@ the library focuses on offering a toolset for "human teaming": that is, treating
are either _teamclients_ or _teamservers_ of others, within a defined -generally restricted- team of
users, which shall generally be strictly and securely authenticated.

-----
## Components & Terms

The result consists in 2 Go packages (`client` and `server`) for programs needing to act as:
- A **Team client**: a program, or one of its components, that needs to rely on a "remote" program peer
to serve some functionality that is available to a team of users' tools. The program acting as a
_teamclient_ may do so for things as simple as sending a message to the team, or as complicated as a
compiler backend with which multiple client programs can send data to process and build.
- A **Team server**: The remote, server-side counterpart of the software teamclient. Again, the
teamserver can be doing anything, from simply notifying users' teamclient connections to all the team
all the way to handling very complex and resource-hungry tasks that can only be ran on a server host.

Throughout this library and its documentation, various words are repeatedly employed:
- _teamclient_ refers to either the client-specific toolset provided by this library
(`team/client.Client` core type) or the software making use of this teamclient code.
- _teamserver_ refers to either the server-specific toolset provided to make a program serve its
functionality remotely, or to the tools embedding this code in order to do so.
- _team tool/s_ might be used to refer to programs using either or all of the library components at
large.

-----
## CLI (Users)

The following extracts assume a program binary named `teamserver`, which is simply the root command
of the server-side team code. In this case therefore, the binary program only purpose its to be a
teamserver, with no application-specific logic, (and is therefore quite useless on its own):
teamserver, with no application-specific logic, (and is therefore quite useless on its own).
For example, if your application `cracker` makes use of a teamserver/client, all the following
commands would look like `cracker teamserver daemon`, `cracker teamserver client users`, etc:
```
$ teamserver
Manage the application server-side teamserver and users
Expand Down Expand Up @@ -156,6 +138,26 @@ teamclient users
teamclient version
```

-----
## Components & Terms

The result consists in 2 Go packages (`client` and `server`) for programs needing to act as:
- A **Team client**: a program, or one of its components, that needs to rely on a "remote" program peer
to serve some functionality that is available to a team of users' tools. The program acting as a
_teamclient_ may do so for things as simple as sending a message to the team, or as complicated as a
compiler backend with which multiple client programs can send data to process and build.
- A **Team server**: The remote, server-side counterpart of the software teamclient. Again, the
teamserver can be doing anything, from simply notifying users' teamclient connections to all the team
all the way to handling very complex and resource-hungry tasks that can only be ran on a server host.

Throughout this library and its documentation, various words are repeatedly employed:
- _teamclient_ refers to either the client-specific toolset provided by this library
(`team/client.Client` core type) or the software making use of this teamclient code.
- _teamserver_ refers to either the server-specific toolset provided to make a program serve its
functionality remotely, or to the tools embedding this code in order to do so.
- _team tool/s_ might be used to refer to programs using either or all of the library components at
large.

-----
## API (Developers)

Expand Down Expand Up @@ -341,13 +343,12 @@ This teamserver library aims to remain small, with a precise behavior and role.
Overall, contributions and ideas should revolve around strenghening its core/transport code
or around enhancing its interoperability with as much Go code/programs as possible.

- [ ] Use viper for configs.
- [ ] Use afero filesystem.
- [ ] Add support for encrypted sqlite by default.
- [ ] Encrypt in-memory channels, or add option for it.
- [ ] Simpler/different listener/dialer backend interfaces, if it appears needed.
- [ ] Abstract away the client-side authentication, for pluggable auth/credential models.
- [ ] Replace logrus entirely and restructure behind a single package used by both client/server.
- [ ] Review/refine/strenghen the dialer/listener init/close/start process, if it appears needed.
- [ ] `teamclient update` downloads latest version of the server binary + method to `team.Client` for it.
- [ ] Implement tests for most sensitive paths (certificates management, database functioning, etc)

10 changes: 3 additions & 7 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,14 @@ package client
*/

import (
"os/user"
"path/filepath"
"runtime"
"sync"

"github.com/sirupsen/logrus"

"github.com/reeflective/team"
"github.com/reeflective/team/internal/assets"
"github.com/reeflective/team/internal/version"
"github.com/sirupsen/logrus"
)

// Client is the core driver of an application teamclient.
Expand Down Expand Up @@ -122,15 +121,12 @@ func New(app string, client team.Client, options ...Options) (*Client, error) {
client: client,
connect: &sync.Once{},
mutex: &sync.RWMutex{},
fs: &assets.FS{},
}

teamclient.apply(options...)

// Filesystem (in-memory or on disk)
user, _ := user.Current()
root := filepath.Join(user.HomeDir, "."+teamclient.name)
teamclient.fs = assets.NewFileSystem(root, teamclient.opts.inMemory)
teamclient.fs = assets.NewFileSystem(teamclient.opts.inMemory)

// Logging (if allowed)
if err := teamclient.initLogging(); err != nil {
Expand Down
9 changes: 5 additions & 4 deletions client/commands/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,13 @@ import (
"path/filepath"
"strings"

"github.com/reeflective/team/client"
"github.com/reeflective/team/internal/command"
"github.com/rsteube/carapace"
"github.com/rsteube/carapace/pkg/style"
"github.com/carapace-sh/carapace"
"github.com/carapace-sh/carapace/pkg/style"
"github.com/spf13/cobra"
"github.com/spf13/pflag"

"github.com/reeflective/team/client"
"github.com/reeflective/team/internal/command"
)

// Generate returns a command tree to embed in client applications connecting
Expand Down
5 changes: 3 additions & 2 deletions client/commands/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,11 @@ import (
"encoding/json"
"fmt"

"github.com/reeflective/team/client"
"github.com/reeflective/team/internal/command"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"

"github.com/reeflective/team/client"
"github.com/reeflective/team/internal/command"
)

func importCmd(cli *client.Client) func(cmd *cobra.Command, args []string) {
Expand Down
5 changes: 3 additions & 2 deletions client/commands/users.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,11 @@ import (
"time"

"github.com/jedib0t/go-pretty/v6/table"
"github.com/reeflective/team/client"
"github.com/reeflective/team/internal/command"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"

"github.com/reeflective/team/client"
"github.com/reeflective/team/internal/command"
)

func usersCmd(cli *client.Client) func(cmd *cobra.Command, args []string) error {
Expand Down
5 changes: 3 additions & 2 deletions client/commands/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,11 @@ import (
"fmt"
"time"

"github.com/reeflective/team/client"
"github.com/reeflective/team/internal/command"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"

"github.com/reeflective/team/client"
"github.com/reeflective/team/internal/command"
)

func versionCmd(cli *client.Client) func(cmd *cobra.Command, args []string) error {
Expand Down
17 changes: 8 additions & 9 deletions client/directories.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package client
*/

import (
"os"
"os/user"
"path/filepath"

Expand All @@ -33,15 +34,11 @@ func (tc *Client) HomeDir() string {
var dir string

// Note: very important not to combine the nested if here.
if !tc.opts.inMemory {
if tc.homeDir == "" {
user, _ := user.Current()
dir = filepath.Join(user.HomeDir, "."+tc.name)
} else {
dir = tc.homeDir
}
if tc.homeDir == "" {
user, _ := user.Current()
dir = filepath.Join(user.HomeDir, "."+tc.name)
} else {
dir = "." + tc.name
dir = tc.homeDir
}

err := tc.fs.MkdirAll(dir, assets.DirPerm)
Expand Down Expand Up @@ -82,11 +79,13 @@ func (tc *Client) LogsDir() string {
// ConfigsDir returns the path to the remote teamserver configs directory
// for this application (~/.app/teamclient/configs), creating the directory
// if needed, or logging a fatal event if failing to create it.
//
// This uses the on-disk filesystem even if the teamclient is in memory mode.
func (tc *Client) ConfigsDir() string {
rootDir, _ := filepath.Abs(tc.TeamDir())
dir := filepath.Join(rootDir, assets.DirConfigs)

err := tc.fs.MkdirAll(dir, assets.DirPerm)
err := os.MkdirAll(dir, assets.DirPerm)
if err != nil {
tc.log().Errorf("cannot write to %s configs dir: %s", dir, err)
}
Expand Down
3 changes: 2 additions & 1 deletion client/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ import (
"io"
"path/filepath"

"github.com/reeflective/team/internal/log"
"github.com/sirupsen/logrus"

"github.com/reeflective/team/internal/log"
)

// NamedLogger returns a new logging "thread" with two fields (optional)
Expand Down
8 changes: 4 additions & 4 deletions client/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ package client
*/

import (
"fmt"
"io"
"os"
"strings"

"github.com/reeflective/team/internal/assets"
"github.com/sirupsen/logrus"

"github.com/reeflective/team/internal/assets"
)

const noTeamdir = "no team subdirectory"
Expand Down Expand Up @@ -69,7 +69,7 @@ func (tc *Client) apply(options ...Options) {
// set once when created.
tc.initOpts.Do(func() {
// Application home directory.
homeDir := os.Getenv(fmt.Sprintf("%s_ROOT_DIR", strings.ToUpper(tc.name)))
homeDir := os.Getenv(strings.ToUpper(tc.name) + "_ROOT_DIR")
if homeDir != "" {
tc.homeDir = homeDir
} else {
Expand Down Expand Up @@ -114,7 +114,7 @@ func WithInMemory() Options {
// to connect to, instead of using default on-disk user/application configurations.
// This function will be very useful to library users who wish to implement specific
// remote teamserver selection & connection strategies, depending on the domains and
// and use cases of these tools.
// use cases of these tools.
func WithConfig(config *Config) Options {
return func(opts *opts) {
opts.config = config
Expand Down
36 changes: 21 additions & 15 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,38 +1,43 @@
module github.com/reeflective/team

go 1.21
go 1.23.0

toolchain go1.24.2

require (
github.com/AlecAivazis/survey/v2 v2.3.7
github.com/carapace-sh/carapace v1.8.1
github.com/gofrs/uuid v4.4.0+incompatible
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0
github.com/jedib0t/go-pretty/v6 v6.4.6
github.com/lib/pq v1.10.9
github.com/ncruces/go-sqlite3 v0.8.4
github.com/ncruces/go-sqlite3/gormlite v0.8.4
github.com/psanford/memfs v0.0.0-20230130182539-4dbf7e3e865e
github.com/rsteube/carapace v0.47.4
github.com/sirupsen/logrus v1.9.3
github.com/spf13/cobra v1.8.1
github.com/spf13/afero v1.14.0
github.com/spf13/cobra v1.9.1
github.com/spf13/pflag v1.0.6
google.golang.org/grpc v1.56.1
google.golang.org/protobuf v1.31.0
gorm.io/driver/mysql v1.5.1
gorm.io/driver/postgres v1.5.2
gorm.io/driver/sqlite v1.5.2
gorm.io/gorm v1.25.2
gorm.io/driver/mysql v1.5.7
gorm.io/driver/postgres v1.5.9
gorm.io/driver/sqlite v1.5.5
gorm.io/gorm v1.25.10
modernc.org/sqlite v1.23.1
)

require (
github.com/carapace-sh/carapace-shlex v1.0.1 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/go-sql-driver/mysql v1.7.0 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
github.com/jackc/pgx/v5 v5.3.1 // indirect
github.com/jackc/pgx/v5 v5.5.5 // indirect
github.com/jackc/puddle/v2 v2.2.1 // 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
Expand All @@ -48,13 +53,14 @@ require (
github.com/rsteube/carapace-shlex v0.1.1 // indirect
github.com/stretchr/testify v1.8.2 // indirect
github.com/tetratelabs/wazero v1.4.0 // indirect
golang.org/x/crypto v0.8.0 // indirect
golang.org/x/mod v0.11.0 // indirect
golang.org/x/net v0.9.0 // indirect
golang.org/x/sys v0.11.0 // indirect
golang.org/x/term v0.7.0 // indirect
golang.org/x/text v0.12.0 // indirect
golang.org/x/tools v0.6.0 // indirect
golang.org/x/crypto v0.37.0 // indirect
golang.org/x/mod v0.17.0 // indirect
golang.org/x/net v0.39.0 // indirect
golang.org/x/sync v0.13.0 // indirect
golang.org/x/sys v0.32.0 // indirect
golang.org/x/term v0.31.0 // indirect
golang.org/x/text v0.24.0 // indirect
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
lukechampine.com/uint128 v1.2.0 // indirect
Expand Down
Loading