use cobra and koanf for command and config

This commit is contained in:
genofire 2022-08-10 21:02:07 +02:00
parent 98d3f88bfb
commit e27e6a26d9
44 changed files with 1184 additions and 551 deletions

14
cmd/dendrite/account.go Normal file
View file

@ -0,0 +1,14 @@
package main
import (
"github.com/spf13/cobra"
)
func init() {
rootCmd.AddCommand(accountCmd)
}
var accountCmd = &cobra.Command{
Use: "account",
Short: "Manage Account on this server",
}

View file

@ -20,7 +20,6 @@ import (
"crypto/sha1"
"encoding/hex"
"encoding/json"
"flag"
"fmt"
"io"
"net/http"
@ -32,11 +31,11 @@ import (
"github.com/tidwall/gjson"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"golang.org/x/term"
"github.com/matrix-org/dendrite/setup"
)
// TODO still needed, should be imported ?
const usage = `Usage: %s
Creates a new user account on the homeserver.
@ -58,65 +57,76 @@ Arguments:
`
var (
username = flag.String("username", "", "The username of the account to register (specify the localpart only, e.g. 'alice' for '@alice:domain.com')")
password = flag.String("password", "", "The password to associate with the account")
pwdFile = flag.String("passwordfile", "", "The file to use for the password (e.g. for automated account creation)")
pwdStdin = flag.Bool("passwordstdin", false, "Reads the password from stdin")
isAdmin = flag.Bool("admin", false, "Create an admin account")
resetPassword = flag.Bool("reset-password", false, "Deprecated")
serverURL = flag.String("url", "http://localhost:8008", "The URL to connect to.")
username string
password string
pwdFile string
pwdStdin bool
isAdmin bool
resetPassword bool
serverURL string
validUsernameRegex = regexp.MustCompile(`^[0-9a-z_\-=./]+$`)
timeout = flag.Duration("timeout", time.Second*30, "Timeout for the http client when connecting to the server")
timeout time.Duration
)
var cl = http.Client{
Timeout: time.Second * 30,
Transport: http.DefaultTransport,
}
func main() {
name := os.Args[0]
flag.Usage = func() {
_, _ = fmt.Fprintf(os.Stderr, usage, name, name, name, name, name, name)
flag.PrintDefaults()
}
cfg := setup.ParseFlags(true)
func init() {
createAccountCmd.Flags().StringVarP(&configPath, "config", "c", "", "config file")
if *resetPassword {
logrus.Fatalf("The reset-password flag has been replaced by the POST /_dendrite/admin/resetPassword/{localpart} admin API.")
}
createAccountCmd.Flags().StringVarP(&username, "username", "", "", "The username of the account to register (specify the localpart only, e.g. 'alice' for '@alice:domain.com')")
createAccountCmd.Flags().StringVarP(&password, "password", "", "", "The password to associate with the account")
createAccountCmd.Flags().StringVarP(&pwdFile, "passwordfile", "", "", "The file to use for the password (e.g. for automated account creation)")
createAccountCmd.Flags().BoolVarP(&pwdStdin, "passwordstdin", "", false, "Reads the password from stdin")
createAccountCmd.Flags().BoolVarP(&isAdmin, "admin", "", false, "Create an admin account")
createAccountCmd.Flags().StringVarP(&serverURL, "url", "", "http://localhost:8008", "The URL to connect to.")
createAccountCmd.Flags().DurationVar(&timeout, "timeout", time.Second*30, "Timeout for the http client when connecting to the server")
// maybe drop now?
createAccountCmd.Flags().BoolVarP(&resetPassword, "reset-password", "", false, "Deprecated")
if cfg.ClientAPI.RegistrationSharedSecret == "" {
logrus.Fatalln("Shared secret registration is not enabled, enable it by setting a shared secret in the config: 'client_api.registration_shared_secret'")
}
createAccountCmd.MarkFlagRequired("username")
if *username == "" {
flag.Usage()
os.Exit(1)
}
accountCmd.AddCommand(createAccountCmd)
}
if !validUsernameRegex.MatchString(*username) {
logrus.Warn("Username can only contain characters a-z, 0-9, or '_-./='")
os.Exit(1)
}
var createAccountCmd = &cobra.Command{
Use: "create",
Short: "Creates a new user account on the homeserver.",
Long: `Creates a new user account on the homeserver.`,
PreRun: readConfigCmd(true),
Run: func(cmd *cobra.Command, args []string) {
if resetPassword {
logrus.Fatalf("The reset-password flag has been replaced by the POST /_dendrite/admin/resetPassword/{localpart} admin API.")
}
if len(fmt.Sprintf("@%s:%s", *username, cfg.Global.ServerName)) > 255 {
logrus.Fatalf("Username can not be longer than 255 characters: %s", fmt.Sprintf("@%s:%s", *username, cfg.Global.ServerName))
}
if cfg.ClientAPI.RegistrationSharedSecret == "" {
logrus.Fatalln("Shared secret registration is not enabled, enable it by setting a shared secret in the config: 'client_api.registration_shared_secret'")
}
pass, err := getPassword(*password, *pwdFile, *pwdStdin, os.Stdin)
if err != nil {
logrus.Fatalln(err)
}
if !validUsernameRegex.MatchString(username) {
logrus.Warn("Username can only contain characters a-z, 0-9, or '_-./='")
os.Exit(1)
}
cl.Timeout = *timeout
if len(fmt.Sprintf("@%s:%s", username, cfg.Global.ServerName)) > 255 {
logrus.Fatalf("Username can not be longer than 255 characters: %s", fmt.Sprintf("@%s:%s", username, cfg.Global.ServerName))
}
accessToken, err := sharedSecretRegister(cfg.ClientAPI.RegistrationSharedSecret, *serverURL, *username, pass, *isAdmin)
if err != nil {
logrus.Fatalln("Failed to create the account:", err.Error())
}
pass, err := getPassword(password, pwdFile, pwdStdin, os.Stdin)
if err != nil {
logrus.Fatalln(err)
}
logrus.Infof("Created account: %s (AccessToken: %s)", *username, accessToken)
cl.Timeout = timeout
accessToken, err := sharedSecretRegister(cfg.ClientAPI.RegistrationSharedSecret, serverURL, username, pass, isAdmin)
if err != nil {
logrus.Fatalln("Failed to create the account:", err.Error())
}
logrus.Infof("Created account: %s (AccessToken: %s)", username, accessToken)
},
}
type sharedSecretRegistrationRequest struct {

View file

@ -6,7 +6,7 @@ import (
"testing"
)
func Test_getPassword(t *testing.T) {
func TestgetPassword(t *testing.T) {
type args struct {
password string
pwdFile string

View file

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package personalities
package components
import (
"github.com/matrix-org/dendrite/appservice"
@ -31,6 +31,6 @@ func Appservice(base *base.BaseDendrite, cfg *config.Dendrite) {
base.SetupAndServeHTTP(
base.Cfg.AppServiceAPI.InternalAPI.Listen, // internal listener
basepkg.NoListener, // external listener
nil, nil,
"", "",
)
}

View file

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package personalities
package components
import (
"github.com/matrix-org/dendrite/clientapi"
@ -39,6 +39,6 @@ func ClientAPI(base *basepkg.BaseDendrite, cfg *config.Dendrite) {
base.SetupAndServeHTTP(
base.Cfg.ClientAPI.InternalAPI.Listen,
base.Cfg.ClientAPI.ExternalAPI.Listen,
nil, nil,
"", "",
)
}

View file

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package personalities
package components
import (
"github.com/matrix-org/dendrite/federationapi"
@ -39,6 +39,6 @@ func FederationAPI(base *basepkg.BaseDendrite, cfg *config.Dendrite) {
base.SetupAndServeHTTP(
base.Cfg.FederationAPI.InternalAPI.Listen,
base.Cfg.FederationAPI.ExternalAPI.Listen,
nil, nil,
"", "",
)
}

View file

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package personalities
package components
import (
"github.com/matrix-org/dendrite/keyserver"
@ -30,6 +30,6 @@ func KeyServer(base *basepkg.BaseDendrite, cfg *config.Dendrite) {
base.SetupAndServeHTTP(
base.Cfg.KeyServer.InternalAPI.Listen, // internal listener
basepkg.NoListener, // external listener
nil, nil,
"", "",
)
}

View file

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package personalities
package components
import (
"github.com/matrix-org/dendrite/mediaapi"
@ -31,6 +31,6 @@ func MediaAPI(base *basepkg.BaseDendrite, cfg *config.Dendrite) {
base.SetupAndServeHTTP(
base.Cfg.MediaAPI.InternalAPI.Listen,
base.Cfg.MediaAPI.ExternalAPI.Listen,
nil, nil,
"", "",
)
}

View file

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package personalities
package components
import (
"github.com/matrix-org/dendrite/roomserver"
@ -31,6 +31,6 @@ func RoomServer(base *basepkg.BaseDendrite, cfg *config.Dendrite) {
base.SetupAndServeHTTP(
base.Cfg.RoomServer.InternalAPI.Listen, // internal listener
basepkg.NoListener, // external listener
nil, nil,
"", "",
)
}

View file

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package personalities
package components
import (
basepkg "github.com/matrix-org/dendrite/setup/base"
@ -34,6 +34,6 @@ func SyncAPI(base *basepkg.BaseDendrite, cfg *config.Dendrite) {
base.SetupAndServeHTTP(
base.Cfg.SyncAPI.InternalAPI.Listen,
base.Cfg.SyncAPI.ExternalAPI.Listen,
nil, nil,
"", "",
)
}

View file

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package personalities
package components
import (
basepkg "github.com/matrix-org/dendrite/setup/base"
@ -32,6 +32,6 @@ func UserAPI(base *basepkg.BaseDendrite, cfg *config.Dendrite) {
base.SetupAndServeHTTP(
base.Cfg.UserAPI.InternalAPI.Listen, // internal listener
basepkg.NoListener, // external listener
nil, nil,
"", "",
)
}

14
cmd/dendrite/config.go Normal file
View file

@ -0,0 +1,14 @@
package main
import (
"github.com/spf13/cobra"
)
func init() {
rootCmd.AddCommand(configCmd)
}
var configCmd = &cobra.Command{
Use: "config",
Short: "Configuration tools",
}

View file

@ -0,0 +1,66 @@
package main
import (
"fmt"
"io/ioutil"
"os"
"github.com/knadh/koanf"
"github.com/knadh/koanf/parsers/yaml"
"github.com/knadh/koanf/providers/structs"
"github.com/spf13/cobra"
)
var (
dirPath = "./"
)
func init() {
generateConfigCmd.Flags().StringVarP(&configPath, "config", "c", "", "write config to file if not set to print in yaml")
generateConfigCmd.Flags().StringVarP(&serverName, "server", "", "", "The domain name of the server if not 'localhost'")
generateConfigCmd.Flags().StringVarP(&dbURI, "db", "", "", "The DB URI to use for all components if not SQLite files")
generateConfigCmd.Flags().StringVarP(&dirPath, "dir", "", "./", "The folder to use for paths (like SQLite databases, media storage)")
generateConfigCmd.Flags().BoolVarP(&defaultsForCI, "ci", "", false, "Populate the configuration with sane defaults for use in CI")
generateConfigCmd.Flags().BoolVarP(&monolithic, "monolithic", "", true, "Generate a config that makes sense for monolith deployments")
configCmd.AddCommand(generateConfigCmd)
}
var generateConfigCmd = &cobra.Command{
Use: "generate",
Short: "generate configuration file",
Long: "generate default configuration (overwrite is possible by commandline arguments and enviroment variables",
Run: func(cmd *cobra.Command, args []string) {
k := koanf.New("/")
// "" <- do not read file - we like to write
readConfig(true, monolithic, "", dirPath)
k.Load(structs.Provider(cfg, "config"), nil)
var parser koanf.Parser
if configPath != "" {
var fileExt string
parser, fileExt = getParser(configPath)
if parser == nil {
fmt.Println("unsupported file extention:", fileExt)
os.Exit(1)
}
} else {
parser = yaml.Parser()
}
b, err := k.Marshal(parser)
if err != nil {
fmt.Println("unable to generate yaml", err)
os.Exit(1)
}
if configPath != "" {
ioutil.WriteFile(configPath, b, 0644)
fmt.Println("config file saved in:", configPath)
} else {
fmt.Println(string(b))
}
},
}

View file

@ -0,0 +1,37 @@
package main
import (
"fmt"
"os"
"github.com/knadh/koanf"
"github.com/knadh/koanf/parsers/yaml"
"github.com/knadh/koanf/providers/structs"
"github.com/spf13/cobra"
)
func init() {
verifyConfigCmd.Flags().StringVarP(&configPath, "config", "c", "", "write config to file if not set to print in yaml")
verifyConfigCmd.Flags().BoolVarP(&monolithic, "monolithic", "", true, "")
configCmd.AddCommand(verifyConfigCmd)
}
var verifyConfigCmd = &cobra.Command{
Use: "verify",
Short: "verify configuration",
Long: "verify configuration - read file+env and print result",
Run: func(cmd *cobra.Command, args []string) {
k := koanf.New("/")
readConfig(false, monolithic, configPath, "./")
k.Load(structs.Provider(cfg, "config"), nil)
b, err := k.Marshal(yaml.Parser())
if err != nil {
fmt.Println("unable to generate yaml", err)
os.Exit(1)
}
fmt.Println(string(b))
},
}

View file

@ -0,0 +1,150 @@
package main
import (
"fmt"
"golang.org/x/crypto/bcrypt"
"path/filepath"
"github.com/matrix-org/dendrite/setup/config"
"github.com/matrix-org/gomatrixserverlib"
"github.com/knadh/koanf"
"github.com/knadh/koanf/parsers/json"
"github.com/knadh/koanf/parsers/toml"
"github.com/knadh/koanf/parsers/yaml"
)
var (
configExtParser = map[string]koanf.Parser{
".json": json.Parser(),
".toml": toml.Parser(),
".yaml": yaml.Parser(),
".yml": yaml.Parser(),
}
)
func getParser(configPath string) (koanf.Parser, string) {
fileExt := filepath.Ext(configPath)
parser, ok := configExtParser[fileExt]
if !ok {
return nil, fileExt
}
return parser, fileExt
}
var (
serverName string
dbURI string
defaultsForCI = false
cfg = &config.Dendrite{}
)
func configDefaults(generate, monolithic bool, dirPath string) {
cfg.Version = config.Version
cfg.Defaults(config.DefaultOpts{
Generate: generate,
Monolithic: monolithic,
})
if generate {
if serverName != "" {
cfg.Global.ServerName = gomatrixserverlib.ServerName(serverName)
}
uri := config.DataSource(dbURI)
if monolithic || uri.IsSQLite() || uri == "" {
for name, db := range map[string]*config.DatabaseOptions{
"federationapi": &cfg.FederationAPI.Database,
"keyserver": &cfg.KeyServer.Database,
"mscs": &cfg.MSCs.Database,
"mediaapi": &cfg.MediaAPI.Database,
"roomserver": &cfg.RoomServer.Database,
"syncapi": &cfg.SyncAPI.Database,
"userapi": &cfg.UserAPI.AccountDatabase,
} {
if uri == "" {
path := filepath.Join(dirPath, fmt.Sprintf("dendrite_%s.db", name))
db.ConnectionString = config.DataSource(fmt.Sprintf("file:%s", path))
} else {
db.ConnectionString = uri
}
}
} else {
cfg.Global.DatabaseOptions.ConnectionString = uri
}
}
/* --
cfg.Global.TrustedIDServers = []string{
"matrix.org",
"vector.im",
}
*/
cfg.Logging = []config.LogrusHook{
{
Type: "file",
Level: "info",
Params: map[string]interface{}{
"path": filepath.Join(dirPath, "log"),
},
},
}
cfg.FederationAPI.KeyPerspectives = config.KeyPerspectives{
{
ServerName: "matrix.org",
Keys: []config.KeyPerspectiveTrustKey{
{
KeyID: "ed25519:auto",
PublicKey: "Noi6WqcDj0QmPxCNQqgezwTlBKrfqehY1u2FyWP9uYw",
},
{
KeyID: "ed25519:a_RXGa",
PublicKey: "l8Hft5qXKn1vfHrg3p4+W8gELQVo8N13JkluMfmn2sQ",
},
},
},
}
cfg.MediaAPI.ThumbnailSizes = []config.ThumbnailSize{
{
Width: 32,
Height: 32,
ResizeMethod: "crop",
},
{
Width: 96,
Height: 96,
ResizeMethod: "crop",
},
{
Width: 640,
Height: 480,
ResizeMethod: "scale",
},
}
if defaultsForCI {
cfg.AppServiceAPI.DisableTLSValidation = true
cfg.ClientAPI.RateLimiting.Enabled = false
cfg.FederationAPI.DisableTLSValidation = false
// don't hit matrix.org when running tests!!!
cfg.FederationAPI.KeyPerspectives = config.KeyPerspectives{}
cfg.MediaAPI.BasePath = config.Path(filepath.Join(dirPath, "media"))
cfg.MSCs.MSCs = []string{"msc2836", "msc2946", "msc2444", "msc2753"}
cfg.Logging[0].Level = "trace"
cfg.Logging[0].Type = "std"
cfg.UserAPI.BCryptCost = bcrypt.MinCost
cfg.Global.JetStream.InMemory = true
cfg.Global.JetStream.StoragePath = config.Path(dirPath)
cfg.ClientAPI.RegistrationDisabled = false
cfg.ClientAPI.OpenRegistrationWithoutVerificationEnabled = true
cfg.ClientAPI.RegistrationSharedSecret = "complement"
cfg.Global.Presence = config.PresenceOptions{
EnableInbound: true,
EnableOutbound: true,
}
cfg.SyncAPI.Fulltext = config.Fulltext{
Enabled: true,
IndexPath: config.Path(filepath.Join(dirPath, "searchindex")),
InMemory: true,
Language: "en",
}
}
}

View file

@ -0,0 +1,70 @@
package main
import (
"fmt"
"os"
"path/filepath"
"strings"
"github.com/knadh/koanf"
"github.com/knadh/koanf/providers/env"
"github.com/knadh/koanf/providers/file"
"github.com/spf13/cobra"
)
var (
configPath string
monolithic bool
enableRegistrationWithoutVerification = true
)
func readConfigCmd(monolithic bool) func(cmd *cobra.Command, args []string) {
return func(cmd *cobra.Command, args []string) {
readConfig(false, monolithic, configPath, "./")
}
}
func readConfig(generate bool, monolithic bool, configPath, dirPath string) {
configDefaults(generate, monolithic, dirPath)
k := koanf.New("/")
if configPath != "" {
parser, fileExt := getParser(configPath)
if parser == nil {
fmt.Println("unsupported file extention:", fileExt)
os.Exit(1)
}
if err := k.Load(file.Provider(configPath), parser); err != nil {
fmt.Println("read file config:", err)
os.Exit(1)
}
}
if err := k.Load(env.Provider("DENDRITE_", "/", func(s string) string {
return strings.Replace(strings.ToLower(
strings.TrimPrefix(s, "DENDRITE_")), "__", "/", -1)
}), nil); err != nil {
fmt.Println("read env config:", err)
os.Exit(1)
}
if err := k.UnmarshalWithConf("", &cfg, koanf.UnmarshalConf{Tag: "config"}); err != nil {
fmt.Println("Can't unmarshal config:", err)
os.Exit(1)
}
basePath, err := filepath.Abs(".")
if err != nil {
fmt.Println("Can't get working dir, for read files allocated by config:", err)
os.Exit(1)
}
if err := cfg.Load(basePath, monolithic); err != nil {
fmt.Println("Can't setup config:", err)
os.Exit(1)
}
cfg.ClientAPI.OpenRegistrationWithoutVerificationEnabled = enableRegistrationWithoutVerification
}

14
cmd/dendrite/keys.go Normal file
View file

@ -0,0 +1,14 @@
package main
import (
"github.com/spf13/cobra"
)
func init() {
rootCmd.AddCommand(keysCmd)
}
var keysCmd = &cobra.Command{
Use: "keys",
Short: "key tools",
}

View file

@ -0,0 +1,69 @@
package main
import (
"fmt"
"github.com/matrix-org/dendrite/test"
"github.com/spf13/cobra"
)
var (
tlsCertFile string
tlsKeyFile string
privateKeyFile string
authorityCertFile string
authorityKeyFile string
keySize int
// already in helper_config.go defined:
// serverName string
)
func init() {
generateKeysCmd.Flags().StringVarP(&tlsCertFile, "tls-cert", "", "", "An X509 certificate file to generate for use for TLS")
generateKeysCmd.Flags().StringVarP(&tlsKeyFile, "tls-key", "", "", "An RSA private key file to generate for use for TLS")
generateKeysCmd.MarkFlagsRequiredTogether("tls-cert", "tls-key")
generateKeysCmd.Flags().StringVarP(&privateKeyFile, "private-key", "", "", "An Ed25519 private key to generate for use for object signing")
generateKeysCmd.Flags().StringVarP(&authorityCertFile, "tls-authority-cert", "", "", "Optional: Create TLS certificate/keys based on this CA authority. Useful for integration testing.")
generateKeysCmd.Flags().StringVarP(&authorityKeyFile, "tls-authority-key", "", "", "Optional: Create TLS certificate/keys based on this CA authority. Useful for integration testing.")
generateKeysCmd.MarkFlagsRequiredTogether("tls-authority-cert", "tls-authority-key")
generateKeysCmd.Flags().StringVarP(&serverName, "server", "", "", "Optional: Create TLS certificate/keys with this domain name set. Useful for integration testing.")
generateKeysCmd.Flags().IntVarP(&keySize, "keysize", "", 4096, "Optional: Create TLS RSA private key with the given key size")
keysCmd.AddCommand(generateKeysCmd)
}
var generateKeysCmd = &cobra.Command{
Use: "generate",
Short: "Generate key files which are required by dendrite.",
Run: func(cmd *cobra.Command, args []string) {
if tlsCertFile == "" && tlsKeyFile == "" && privateKeyFile == "" {
fmt.Println("Nothing todo, please set argument.")
cmd.Usage()
return
}
if tlsKeyFile != "" {
if authorityKeyFile == "" {
if err := test.NewTLSKey(tlsKeyFile, tlsCertFile, keySize); err != nil {
panic(err)
}
} else {
// generate the TLS cert/key based on the authority given.
if err := test.NewTLSKeyWithAuthority(serverName, tlsKeyFile, tlsCertFile, authorityKeyFile, authorityCertFile, keySize); err != nil {
panic(err)
}
}
fmt.Printf("Created TLS cert file: %s\n", tlsCertFile)
fmt.Printf("Created TLS key file: %s\n", tlsKeyFile)
}
if privateKeyFile != "" {
if err := test.NewMatrixKey(privateKeyFile); err != nil {
panic(err)
}
fmt.Printf("Created private key file: %s\n", privateKeyFile)
}
},
}

25
cmd/dendrite/main.go Normal file
View file

@ -0,0 +1,25 @@
package main
import (
"fmt"
"os"
"github.com/matrix-org/dendrite/internal"
"github.com/spf13/cobra"
)
var rootCmd = &cobra.Command{
Use: "dendrite",
Short: "Dendrite is a second-generation Matrix homeserver written in Go! ",
Long: `Dendrite is a second-generation Matrix homeserver written in Go.
It intends to provide an efficient, reliable and scalable alternative to Synapse.`,
Version: internal.VersionString(),
}
func main() {
if err := rootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}

14
cmd/dendrite/server.go Normal file
View file

@ -0,0 +1,14 @@
package main
import (
"github.com/spf13/cobra"
)
func init() {
rootCmd.AddCommand(serverCmd)
}
var serverCmd = &cobra.Command{
Use: "server",
Short: "run the server",
}

189
cmd/dendrite/server_run.go Normal file
View file

@ -0,0 +1,189 @@
package main
import (
"os"
"github.com/spf13/cobra"
"github.com/matrix-org/dendrite/appservice"
"github.com/matrix-org/dendrite/federationapi"
"github.com/matrix-org/dendrite/keyserver"
"github.com/matrix-org/dendrite/roomserver"
"github.com/matrix-org/dendrite/roomserver/api"
"github.com/matrix-org/dendrite/setup"
basepkg "github.com/matrix-org/dendrite/setup/base"
"github.com/matrix-org/dendrite/setup/config"
"github.com/matrix-org/dendrite/setup/mscs"
"github.com/matrix-org/dendrite/userapi"
uapi "github.com/matrix-org/dendrite/userapi/api"
"github.com/sirupsen/logrus"
)
var (
// for monolith modus
httpBindAddr string
httpsBindAddr string
apiBindAddr string
certFile string
keyFile string
enableHTTPAPIs bool
traceInternal = os.Getenv("DENDRITE_TRACE_INTERNAL") == "1"
)
func init() {
// - for all server setups
// runServerCmd.PersistentFlags().StringVarP(&configPath, "config", "c", "dendrite-config.yaml", "config file")
runServerCmd.PersistentFlags().StringVarP(&configPath, "config", "c", "", "config file")
// - for monolith modus only
runServerCmd.Flags().BoolVarP(&enableRegistrationWithoutVerification, "really-enable-open-registration", "", false, "This allows open registration without secondary verification (reCAPTCHA). This is NOT RECOMMENDED and will SIGNIFICANTLY increase the risk that your server will be used to send spam or conduct attacks, which may result in your server being banned from rooms.")
runServerCmd.Flags().StringVarP(&httpBindAddr, "http-bind-address", "", ":8008", "The HTTP listening port for the server")
runServerCmd.Flags().StringVarP(&httpsBindAddr, "https-bind-address", "", ":8448", "The HTTPS listening port for the server")
runServerCmd.Flags().StringVarP(&apiBindAddr, "api-bind-address", "", "localhost:18008", "The HTTP listening port for the internal HTTP APIs (if -api is enabled)")
runServerCmd.Flags().StringVarP(&certFile, "tls-cert", "", "", "The PEM formatted X509 certificate to use for TLS")
runServerCmd.Flags().StringVarP(&keyFile, "tls-key", "", "", "The PEM private key to use for TLS")
runServerCmd.Flags().BoolVarP(&enableHTTPAPIs, "api", "", false, "Use HTTP APIs instead of short-circuiting (warning: exposes API endpoints!)")
serverCmd.AddCommand(runServerCmd)
}
var runServerCmd = &cobra.Command{
Use: "run",
Short: "Run dendrite server",
Long: `Run dendrite server in monolith modus (if no component called)`,
PreRun: readConfigCmd(true),
// just run monolith modus:
Run: func(cmd *cobra.Command, args []string) {
httpAddr := config.HTTPAddress("http://" + httpBindAddr)
httpsAddr := config.HTTPAddress("https://" + httpsBindAddr)
httpAPIAddr := httpAddr
options := []basepkg.BaseDendriteOptions{}
if enableHTTPAPIs {
logrus.Warnf("DANGER! The -api option is enabled, exposing internal APIs on %q!", apiBindAddr)
httpAPIAddr = config.HTTPAddress("http://" + apiBindAddr)
// If the HTTP APIs are enabled then we need to update the Listen
// statements in the configuration so that we know where to find
// the API endpoints. They'll listen on the same port as the monolith
// itself.
cfg.AppServiceAPI.InternalAPI.Connect = httpAPIAddr
cfg.ClientAPI.InternalAPI.Connect = httpAPIAddr
cfg.FederationAPI.InternalAPI.Connect = httpAPIAddr
cfg.KeyServer.InternalAPI.Connect = httpAPIAddr
cfg.MediaAPI.InternalAPI.Connect = httpAPIAddr
cfg.RoomServer.InternalAPI.Connect = httpAPIAddr
cfg.SyncAPI.InternalAPI.Connect = httpAPIAddr
cfg.UserAPI.InternalAPI.Connect = httpAPIAddr
options = append(options, basepkg.UseHTTPAPIs)
}
base := basepkg.NewBaseDendrite(cfg, "Monolith", options...)
defer base.Close() // nolint: errcheck
federation := base.CreateFederationClient()
rsImpl := roomserver.NewInternalAPI(base)
// call functions directly on the impl unless running in HTTP mode
rsAPI := rsImpl
if base.UseHTTPAPIs {
roomserver.AddInternalRoutes(base.InternalAPIMux, rsImpl)
rsAPI = base.RoomserverHTTPClient()
}
if traceInternal {
rsAPI = &api.RoomserverInternalAPITrace{
Impl: rsAPI,
}
}
fsAPI := federationapi.NewInternalAPI(
base, federation, rsAPI, base.Caches, nil, false,
)
fsImplAPI := fsAPI
if base.UseHTTPAPIs {
federationapi.AddInternalRoutes(base.InternalAPIMux, fsAPI)
fsAPI = base.FederationAPIHTTPClient()
}
keyRing := fsAPI.KeyRing()
keyImpl := keyserver.NewInternalAPI(base, &base.Cfg.KeyServer, fsAPI)
keyAPI := keyImpl
if base.UseHTTPAPIs {
keyserver.AddInternalRoutes(base.InternalAPIMux, keyAPI)
keyAPI = base.KeyServerHTTPClient()
}
pgClient := base.PushGatewayHTTPClient()
userImpl := userapi.NewInternalAPI(base, &cfg.UserAPI, cfg.Derived.ApplicationServices, keyAPI, rsAPI, pgClient)
userAPI := userImpl
if base.UseHTTPAPIs {
userapi.AddInternalRoutes(base.InternalAPIMux, userAPI)
userAPI = base.UserAPIClient()
}
if traceInternal {
userAPI = &uapi.UserInternalAPITrace{
Impl: userAPI,
}
}
// TODO: This should use userAPI, not userImpl, but the appservice setup races with
// the listeners and panics at startup if it tries to create appservice accounts
// before the listeners are up.
asAPI := appservice.NewInternalAPI(base, userImpl, rsAPI)
if base.UseHTTPAPIs {
appservice.AddInternalRoutes(base.InternalAPIMux, asAPI)
asAPI = base.AppserviceHTTPClient()
}
// The underlying roomserver implementation needs to be able to call the fedsender.
// This is different to rsAPI which can be the http client which doesn't need this
// dependency. Other components also need updating after their dependencies are up.
rsImpl.SetFederationAPI(fsAPI, keyRing)
rsImpl.SetAppserviceAPI(asAPI)
rsImpl.SetUserAPI(userAPI)
keyImpl.SetUserAPI(userAPI)
monolith := setup.Monolith{
Config: base.Cfg,
Client: base.CreateClient(),
FedClient: federation,
KeyRing: keyRing,
AppserviceAPI: asAPI,
// always use the concrete impl here even in -http mode because adding public routes
// must be done on the concrete impl not an HTTP client else fedapi will call itself
FederationAPI: fsImplAPI,
RoomserverAPI: rsAPI,
UserAPI: userAPI,
KeyAPI: keyAPI,
}
monolith.AddAllPublicRoutes(base)
if len(base.Cfg.MSCs.MSCs) > 0 {
if err := mscs.Enable(base, &monolith); err != nil {
logrus.WithError(err).Fatalf("Failed to enable MSCs")
}
}
// Expose the matrix APIs directly rather than putting them under a /api path.
go func() {
base.SetupAndServeHTTP(
httpAPIAddr, // internal API
httpAddr, // external API
"", "", // TLS settings
)
}()
// Handle HTTPS if certificate and key are provided
if certFile != "" && keyFile != "" {
go func() {
base.SetupAndServeHTTP(
basepkg.NoListener, // internal API
httpsAddr, // external API
certFile, keyFile, // TLS settings
)
}()
}
// We want to block forever to let the HTTP and HTTPS handler serve the APIs
base.WaitForShutdown()
},
}

View file

@ -0,0 +1,58 @@
// Copyright 2020 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package main
import (
"fmt"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/matrix-org/dendrite/cmd/dendrite/components"
"github.com/matrix-org/dendrite/setup/base"
"github.com/matrix-org/dendrite/setup/config"
)
type entrypoint func(base *base.BaseDendrite, cfg *config.Dendrite)
var allComponents = map[string]entrypoint{
"appservice": components.Appservice,
"clientapi": components.ClientAPI,
"federationapi": components.FederationAPI,
"keyserver": components.KeyServer,
"mediaapi": components.MediaAPI,
"roomserver": components.RoomServer,
"syncapi": components.SyncAPI,
"userapi": components.UserAPI,
}
func init() {
for component, start := range allComponents {
runServerCmd.AddCommand(&cobra.Command{
Use: component,
Short: fmt.Sprintf("Run dendrite server polylith component: %s", component),
PreRun: readConfigCmd(false),
Run: func(cmd *cobra.Command, args []string) {
logrus.Infof("Starting %q component", component)
base := base.NewBaseDendrite(cfg, component, base.PolylithMode) // TODO
defer base.Close() // nolint: errcheck
go start(base, cfg)
base.WaitForShutdown()
},
})
}
}

View file

@ -9,16 +9,15 @@ import (
)
// This is an instrumented main, used when running integration tests (sytest) with code coverage.
// Compile: go test -c -race -cover -covermode=atomic -o monolith.debug -coverpkg "github.com/matrix-org/..." ./cmd/dendrite-monolith-server
// Compile: go test -c -race -cover -covermode=atomic -o monolith.debug -coverpkg "github.com/matrix-org/..." ./cmd/dendrite
// Run the monolith: ./monolith.debug -test.coverprofile=/somewhere/to/dump/integrationcover.out DEVEL --config dendrite.yaml
// Generate HTML with coverage: go tool cover -html=/somewhere/where/there/is/integrationcover.out -o cover.html
// Source: https://dzone.com/articles/measuring-integration-test-coverage-rate-in-pouchc
func TestMain(_ *testing.T) {
var (
args []string
)
args := []string{"server", "run"}
originArgs := len(args)
for _, arg := range os.Args {
for _, arg := range os.Args[1:] {
switch {
case strings.HasPrefix(arg, "DEVEL"):
case strings.HasPrefix(arg, "-test"):
@ -27,7 +26,7 @@ func TestMain(_ *testing.T) {
}
}
// only run the tests if there are args to be passed
if len(args) <= 1 {
if len(args) <= originArgs {
return
}

View file

@ -1,106 +0,0 @@
package main
import (
"flag"
"fmt"
"path/filepath"
"github.com/matrix-org/gomatrixserverlib"
"golang.org/x/crypto/bcrypt"
"gopkg.in/yaml.v2"
"github.com/matrix-org/dendrite/setup/config"
)
func main() {
defaultsForCI := flag.Bool("ci", false, "Populate the configuration with sane defaults for use in CI")
serverName := flag.String("server", "", "The domain name of the server if not 'localhost'")
dbURI := flag.String("db", "", "The DB URI to use for all components (PostgreSQL only)")
dirPath := flag.String("dir", "./", "The folder to use for paths (like SQLite databases, media storage)")
normalise := flag.String("normalise", "", "Normalise an existing configuration file by adding new/missing options and defaults")
polylith := flag.Bool("polylith", false, "Generate a config that makes sense for polylith deployments")
flag.Parse()
var cfg *config.Dendrite
if *normalise == "" {
cfg = &config.Dendrite{
Version: config.Version,
}
cfg.Defaults(config.DefaultOpts{
Generate: true,
Monolithic: !*polylith,
})
if *serverName != "" {
cfg.Global.ServerName = gomatrixserverlib.ServerName(*serverName)
}
uri := config.DataSource(*dbURI)
if *polylith || uri.IsSQLite() || uri == "" {
for name, db := range map[string]*config.DatabaseOptions{
"federationapi": &cfg.FederationAPI.Database,
"keyserver": &cfg.KeyServer.Database,
"mscs": &cfg.MSCs.Database,
"mediaapi": &cfg.MediaAPI.Database,
"roomserver": &cfg.RoomServer.Database,
"syncapi": &cfg.SyncAPI.Database,
"userapi": &cfg.UserAPI.AccountDatabase,
} {
if uri == "" {
path := filepath.Join(*dirPath, fmt.Sprintf("dendrite_%s.db", name))
db.ConnectionString = config.DataSource(fmt.Sprintf("file:%s", path))
} else {
db.ConnectionString = uri
}
}
} else {
cfg.Global.DatabaseOptions.ConnectionString = uri
}
cfg.Logging = []config.LogrusHook{
{
Type: "file",
Level: "info",
Params: map[string]interface{}{
"path": filepath.Join(*dirPath, "log"),
},
},
}
if *defaultsForCI {
cfg.AppServiceAPI.DisableTLSValidation = true
cfg.ClientAPI.RateLimiting.Enabled = false
cfg.FederationAPI.DisableTLSValidation = false
// don't hit matrix.org when running tests!!!
cfg.FederationAPI.KeyPerspectives = config.KeyPerspectives{}
cfg.MediaAPI.BasePath = config.Path(filepath.Join(*dirPath, "media"))
cfg.MSCs.MSCs = []string{"msc2836", "msc2946", "msc2444", "msc2753"}
cfg.Logging[0].Level = "trace"
cfg.Logging[0].Type = "std"
cfg.UserAPI.BCryptCost = bcrypt.MinCost
cfg.Global.JetStream.InMemory = true
cfg.Global.JetStream.StoragePath = config.Path(*dirPath)
cfg.ClientAPI.RegistrationDisabled = false
cfg.ClientAPI.OpenRegistrationWithoutVerificationEnabled = true
cfg.ClientAPI.RegistrationSharedSecret = "complement"
cfg.Global.Presence = config.PresenceOptions{
EnableInbound: true,
EnableOutbound: true,
}
cfg.SyncAPI.Fulltext = config.Fulltext{
Enabled: true,
IndexPath: config.Path(filepath.Join(*dirPath, "searchindex")),
InMemory: true,
Language: "en",
}
}
} else {
var err error
if cfg, err = config.Load(*normalise, !*polylith); err != nil {
panic(err)
}
}
j, err := yaml.Marshal(cfg)
if err != nil {
panic(err)
}
fmt.Println(string(j))
}

View file

@ -1,81 +0,0 @@
// Copyright 2017 Vector Creations Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package main
import (
"flag"
"fmt"
"log"
"os"
"github.com/matrix-org/dendrite/test"
)
const usage = `Usage: %s
Generate key files which are required by dendrite.
Arguments:
`
var (
tlsCertFile = flag.String("tls-cert", "", "An X509 certificate file to generate for use for TLS")
tlsKeyFile = flag.String("tls-key", "", "An RSA private key file to generate for use for TLS")
privateKeyFile = flag.String("private-key", "", "An Ed25519 private key to generate for use for object signing")
authorityCertFile = flag.String("tls-authority-cert", "", "Optional: Create TLS certificate/keys based on this CA authority. Useful for integration testing.")
authorityKeyFile = flag.String("tls-authority-key", "", "Optional: Create TLS certificate/keys based on this CA authority. Useful for integration testing.")
serverName = flag.String("server", "", "Optional: Create TLS certificate/keys with this domain name set. Useful for integration testing.")
keySize = flag.Int("keysize", 4096, "Optional: Create TLS RSA private key with the given key size")
)
func main() {
flag.Usage = func() {
fmt.Fprintf(os.Stderr, usage, os.Args[0])
flag.PrintDefaults()
}
flag.Parse()
if *tlsCertFile == "" && *tlsKeyFile == "" && *privateKeyFile == "" {
flag.Usage()
return
}
if *tlsCertFile != "" || *tlsKeyFile != "" {
if *tlsCertFile == "" || *tlsKeyFile == "" {
log.Fatal("Zero or both of --tls-key and --tls-cert must be supplied")
}
if *authorityCertFile == "" && *authorityKeyFile == "" {
if err := test.NewTLSKey(*tlsKeyFile, *tlsCertFile, *keySize); err != nil {
panic(err)
}
} else {
// generate the TLS cert/key based on the authority given.
if err := test.NewTLSKeyWithAuthority(*serverName, *tlsKeyFile, *tlsCertFile, *authorityKeyFile, *authorityCertFile, *keySize); err != nil {
panic(err)
}
}
fmt.Printf("Created TLS cert file: %s\n", *tlsCertFile)
fmt.Printf("Created TLS key file: %s\n", *tlsKeyFile)
}
if *privateKeyFile != "" {
if err := test.NewMatrixKey(*privateKeyFile); err != nil {
panic(err)
}
fmt.Printf("Created private key file: %s\n", *privateKeyFile)
}
}

9
go.mod
View file

@ -81,6 +81,8 @@ require (
github.com/docker/distribution v2.8.1+incompatible // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/dustin/go-humanize v1.0.0 // indirect
github.com/fatih/structs v1.1.0 // indirect
github.com/fsnotify/fsnotify v1.4.9 // indirect
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/geo v0.0.0-20210211234256-740aa86cb551 // indirect
@ -90,10 +92,12 @@ require (
github.com/golang/snappy v0.0.4 // indirect
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect
github.com/h2non/filetype v1.1.3 // indirect
github.com/inconshreveable/mousetrap v1.0.1 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/juju/errors v1.0.0 // indirect
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
github.com/klauspost/compress v1.15.11 // indirect
github.com/knadh/koanf v1.4.4 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/lucas-clemente/quic-go v0.30.0 // indirect
github.com/marten-seemann/qtls-go1-18 v0.1.3 // indirect
@ -101,6 +105,9 @@ require (
github.com/mattn/go-isatty v0.0.16 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
github.com/minio/highwayhash v1.0.2 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
@ -118,6 +125,8 @@ require (
github.com/prometheus/common v0.37.0 // indirect
github.com/prometheus/procfs v0.8.0 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20220927061507-ef77025ab5aa // indirect
github.com/spf13/cobra v1.6.1 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.0 // indirect
go.etcd.io/bbolt v1.3.6 // indirect

155
go.sum
View file

@ -70,11 +70,27 @@ github.com/anacrolix/missinggo v1.2.1 h1:0IE3TqX5y5D0IxeMwTyIgqdDew4QrzcXaaEnJQy
github.com/anacrolix/missinggo v1.2.1/go.mod h1:J5cMhif8jPmFoC3+Uvob3OXXNIhOUikzMt+uUjeM21Y=
github.com/anacrolix/missinggo/perf v1.0.0/go.mod h1:ljAFWkBuzkO12MQclXzZrosP5urunoLS0Cbvb4V0uMQ=
github.com/anacrolix/tagflag v0.0.0-20180109131632-2146c8d41bf0/go.mod h1:1m2U/K6ZT+JZG0+bdMK6qauP49QT4wE5pmhJXOKKCHw=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/aws/aws-sdk-go-v2 v1.9.2/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4=
github.com/aws/aws-sdk-go-v2/config v1.8.3/go.mod h1:4AEiLtAb8kLs7vgw2ZV3p2VZ1+hBavOc84hqxVNpCyw=
github.com/aws/aws-sdk-go-v2/credentials v1.4.3/go.mod h1:FNNC6nQZQUuyhq5aE5c7ata8o9e4ECGmS4lAXC7o1mQ=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.6.0/go.mod h1:gqlclDEZp4aqJOancXK6TN24aKhT0W0Ae9MHk3wzTMM=
github.com/aws/aws-sdk-go-v2/internal/ini v1.2.4/go.mod h1:ZcBrrI3zBKlhGFNYWvju0I3TR93I7YIgAfy82Fh4lcQ=
github.com/aws/aws-sdk-go-v2/service/appconfig v1.4.2/go.mod h1:FZ3HkCe+b10uFZZkFdvf98LHW21k49W8o8J366lqVKY=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.3.2/go.mod h1:72HRZDLMtmVQiLG2tLfQcaWLCssELvGl+Zf2WVxMmR8=
github.com/aws/aws-sdk-go-v2/service/sso v1.4.2/go.mod h1:NBvT9R1MEF+Ud6ApJKM0G+IkPchKS7p7c2YPKwHmBOk=
github.com/aws/aws-sdk-go-v2/service/sts v1.7.2/go.mod h1:8EzeIqfWt2wWT4rJVu3f21TfrhJ8AEMzVybRNSb/b4g=
github.com/aws/smithy-go v1.8.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
github.com/bits-and-blooms/bitset v1.3.3 h1:R1XWiopGiXf66xygsiLpzLo67xEYvMkHw3w+rCOSAwg=
github.com/bits-and-blooms/bitset v1.3.3/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
@ -128,14 +144,18 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5P
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/codeclysm/extract v2.2.0+incompatible h1:q3wyckoA30bhUSiwdQezMqVhwd8+WGE64/GL//LtUhI=
github.com/codeclysm/extract v2.2.0+incompatible/go.mod h1:2nhFMPHiU9At61hz+12bfrlpXSUrOnK+wR+KlGO4Uks=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/couchbase/ghistogram v0.1.0/go.mod h1:s1Jhy76zqfEecpNWJfWUiKZookAFaiGOEoyzgHt9i7k=
github.com/couchbase/moss v0.2.0/go.mod h1:9MaHIaRuy9pvLPUJxB8sh8OrLfyDczECVL37grCIubs=
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@ -160,13 +180,21 @@ github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25Kn
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
github.com/frankban/quicktest v1.0.0/go.mod h1:R98jIehRai+d1/3Hv2//jOVCTJhW1VBavT6B6CuGq2k=
github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/getsentry/sentry-go v0.14.0 h1:rlOBkuFZRKKdUnKO+0U3JclRDQKlRu5vVQtkWSQvC70=
github.com/getsentry/sentry-go v0.14.0/go.mod h1:RZPJKSw+adu8PBNygiri/A98FqVr2HtRckJk9XVxJ9I=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
@ -181,6 +209,7 @@ github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
github.com/go-ldap/ldap v3.0.2+incompatible/go.mod h1:qfd9rJvER9Q0/D/Sqn1DfHRoBp40uXYvFoEVrNEPqRc=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
@ -195,6 +224,7 @@ github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJ
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0=
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo=
github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8=
@ -202,6 +232,7 @@ github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6Wezm
github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo=
github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM=
github.com/goccy/go-json v0.9.11 h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
@ -258,6 +289,8 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
@ -274,6 +307,7 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE=
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
@ -284,18 +318,56 @@ github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB7
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/h2non/filetype v1.1.3 h1:FKkx9QbD7HR/zjK1Ia5XiBsq9zdLi5Kf3zGyFTAFkGg=
github.com/h2non/filetype v1.1.3/go.mod h1:319b3zT68BvV+WRj7cwy856M2ehB3HqNOt6sy1HndBY=
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw=
github.com/hashicorp/consul/api v1.13.0/go.mod h1:ZlVrynguJKcYr54zGaDbaL3fOvKC9m72FhPvA8T35KQ=
github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI=
github.com/hashicorp/go-hclog v0.8.0/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA=
github.com/hashicorp/go-plugin v1.0.1/go.mod h1:++UyYGoz3o5w9ZzAdZxtQKrWWP+iqPBn3cQptSMzBuY=
github.com/hashicorp/go-retryablehttp v0.5.4/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
github.com/hashicorp/go-rootcerts v1.0.1/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A=
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc=
github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4=
github.com/hashicorp/vault/api v1.0.4/go.mod h1:gDcqh3WGcR1cpF5AJz/B1UFheUEneMoIospckxBxk6Q=
github.com/hashicorp/vault/sdk v0.1.13/go.mod h1:B+hVj7TpuQY1Y/GPbCpffmgd+tSEwvhkWnjtSYCaS2M=
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/hjson/hjson-go/v4 v4.0.0/go.mod h1:KaYt3bTw3zhBjYqnXkYywcYctk0A2nxeEFTse3rH13E=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/huandu/xstrings v1.0.0 h1:pO2K/gKgKaat5LdpAhxhluX2GPQMaI3W5FUz/I/UnWk=
github.com/huandu/xstrings v1.0.0/go.mod h1:4qWG/gcEcfX4z/mBDHJ++3ReCw9ibxbsNJbcucJdbSo=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc=
github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
github.com/json-iterator/go v0.0.0-20171115153421-f7279a603ede/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
@ -321,10 +393,13 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o
github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.15.11 h1:Lcadnb3RKGin4FYM/orgq0qde+nc15E5Cbqg4B9Sx9c=
github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM=
github.com/knadh/koanf v1.4.4 h1:d2jY5nCCeoaiqvEKSBW9rEc93EfNy/XWgWsSB3j7JEA=
github.com/knadh/koanf v1.4.4/go.mod h1:Hgyjp4y8v44hpZtPzs7JZfRAW5AhN7KfZcwv1RYggDs=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
@ -354,6 +429,13 @@ github.com/matrix-org/pinecone v0.0.0-20221103125849-37f2e9b9ba37 h1:CQWFrgH9TJO
github.com/matrix-org/pinecone v0.0.0-20221103125849-37f2e9b9ba37/go.mod h1:F3GHppRuHCTDeoOmmgjZMeJdbql91+RSGGsATWfC7oc=
github.com/matrix-org/util v0.0.0-20200807132607-55161520e1d4 h1:eCEHXWDv9Rm335MSuB49mFUK44bwZPFSDde3ORE3syk=
github.com/matrix-org/util v0.0.0-20200807132607-55161520e1d4/go.mod h1:vVQlW/emklohkZnOPwD3LrZUBqdfsbiyO3p1lNV8F6U=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
@ -362,11 +444,27 @@ github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI=
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA=
github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g=
github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI=
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae h1:O4SWKdcHVCvYqyDV+9CJA1fcDN2L11Bule0iFy3YlAI=
github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@ -400,6 +498,8 @@ github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S
github.com/ngrok/sqlmw v0.0.0-20220520173518-97c9c04efc79 h1:Dmx8g2747UTVPzSkmohk84S3g/uWqd6+f4SSLPhLcfA=
github.com/ngrok/sqlmw v0.0.0-20220520173518-97c9c04efc79/go.mod h1:E26fwEtRNigBfFfHDWsklmo0T7Ixbg0XXgck+Hq4O9k=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/npillmayer/nestext v0.1.3/go.mod h1:h2lrijH8jpicr25dFY+oAJLyzlya6jhnuG+zWp9L0Uk=
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo/v2 v2.3.0 h1:kUMoxMoQG3ogk/QWyKh3zibV7BKZ+xBpWil1cTylVqc=
@ -413,12 +513,16 @@ github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 h1:rc3
github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE=
github.com/pelletier/go-toml/v2 v2.0.5 h1:ipoSadvV8oGUjnUbMub59IDPPwfxF694nG/jwbMiyQg=
github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@ -427,10 +531,13 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
github.com/prometheus/client_golang v1.13.0 h1:b71QUfeo5M8gq2+evJdTPfZhYMAU0uKPkyPJ7TPsloU=
github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ=
@ -455,11 +562,18 @@ github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0ua
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/remyoudompheng/bigfft v0.0.0-20220927061507-ef77025ab5aa h1:tEkEyxYeZ43TR55QU/hsIt9aRGBxbgGuz9CGykjvogY=
github.com/remyoudompheng/bigfft v0.0.0-20220927061507-ef77025ab5aa/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rhnvrm/simples3 v0.6.1/go.mod h1:Y+3vYm2V7Y4VijFoJHHTrja6OgPrJ2cBti8dPGkC3sA=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
github.com/ryszard/goskiplist v0.0.0-20150312221310-2dfbae5fcf46/go.mod h1:uAQ5PCi+MFsC7HjREoAz1BU+Mq60+05gifQSsHSDG/8=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
@ -471,8 +585,12 @@ github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:X
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA=
github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@ -521,20 +639,27 @@ github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5t
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU=
go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4=
go.etcd.io/etcd/api/v3 v3.5.4/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A=
go.etcd.io/etcd/client/pkg/v3 v3.5.4/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
go.etcd.io/etcd/client/v3 v3.5.4/go.mod h1:ZaRkVgBZC+L+dLCjTcF1hRXpgZXQPOvnA/Ak/gq3kiY=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
golang.org/x/crypto v0.0.0-20180723164146-c126467f60eb/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
@ -572,6 +697,7 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mobile v0.0.0-20221020085226-b36e6246172e h1:zSgtO19fpg781xknwqiQPmOHaASr6E7ZVlTseLd9Fx4=
@ -601,6 +727,7 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@ -618,6 +745,7 @@ golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81R
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
@ -643,15 +771,19 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181221143128-b4a75ba826a6/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -659,7 +791,11 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -667,6 +803,7 @@ golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -685,7 +822,9 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@ -706,8 +845,10 @@ golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
@ -733,6 +874,7 @@ golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgw
golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
@ -764,6 +906,7 @@ golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.2.0 h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE=
golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA=
@ -799,6 +942,7 @@ google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCID
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
@ -820,15 +964,19 @@ google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfG
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
@ -838,6 +986,8 @@ google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKa
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@ -853,6 +1003,7 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@ -865,9 +1016,11 @@ gopkg.in/h2non/bimg.v1 v1.1.9/go.mod h1:PgsZL7dLwUbsGm1NYps320GxGgvQNTnecMCZqxV1
gopkg.in/h2non/gock.v1 v1.1.2 h1:jBbHXgGBK/AoPVfJh5x4r/WxIrElvbLel8TCZkkZJoY=
gopkg.in/macaroon.v2 v2.1.0 h1:HZcsjBCzq9t0eBPMKqTN/uSN6JOm78ZJ2INbqcBQOUI=
gopkg.in/macaroon.v2 v2.1.0/go.mod h1:OUb+TQP/OP0WOerC2Jp/3CwhIKyIa9kQjuc7H24e6/o=
gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
@ -875,6 +1028,7 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
@ -917,3 +1071,4 @@ rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=

View file

@ -38,8 +38,8 @@ import (
// BasicAuth is used for authorization on /metrics handlers
type BasicAuth struct {
Username string `yaml:"username"`
Password string `yaml:"password"`
Username string `config:"username"`
Password string `config:"password"`
}
// MakeAuthAPI turns a util.JSONRequestHandler function into an http.Handler which authenticates the request.

View file

@ -418,7 +418,7 @@ func (b *BaseDendrite) configureHTTPErrors() {
// ApiMux under /api/ and adds a prometheus handler under /metrics.
func (b *BaseDendrite) SetupAndServeHTTP(
internalHTTPAddr, externalHTTPAddr config.HTTPAddress,
certFile, keyFile *string,
certFile, keyFile string,
) {
// Manually unlocked right before actually serving requests,
// as we don't return from this method (defer doesn't work).
@ -518,8 +518,8 @@ func (b *BaseDendrite) SetupAndServeHTTP(
logrus.Infof("Stopped internal HTTP listener")
}
})
if certFile != nil && keyFile != nil {
if err := internalServ.ListenAndServeTLS(*certFile, *keyFile); err != nil {
if certFile != "" && keyFile != "" {
if err := internalServ.ListenAndServeTLS(certFile, keyFile); err != nil {
if err != http.ErrServerClosed {
logrus.WithError(err).Fatal("failed to serve HTTPS")
}
@ -546,8 +546,8 @@ func (b *BaseDendrite) SetupAndServeHTTP(
logrus.Infof("Stopped external HTTP listener")
}
})
if certFile != nil && keyFile != nil {
if err := externalServ.ListenAndServeTLS(*certFile, *keyFile); err != nil {
if certFile != "" && keyFile != "" {
if err := externalServ.ListenAndServeTLS(certFile, keyFile); err != nil {
if err != http.ErrServerClosed {
logrus.WithError(err).Fatal("failed to serve HTTPS")
}

View file

@ -29,7 +29,6 @@ import (
"github.com/matrix-org/gomatrixserverlib"
"github.com/sirupsen/logrus"
"golang.org/x/crypto/ed25519"
yaml "gopkg.in/yaml.v2"
jaegerconfig "github.com/uber/jaeger-client-go/config"
jaegermetrics "github.com/uber/jaeger-lib/metrics"
@ -51,35 +50,35 @@ type Dendrite struct {
// to update their config file to the current version.
// The version of the file should only be different if there has
// been a breaking change to the config file format.
Version int `yaml:"version"`
Version int `config:"version"`
Global Global `yaml:"global"`
AppServiceAPI AppServiceAPI `yaml:"app_service_api"`
ClientAPI ClientAPI `yaml:"client_api"`
FederationAPI FederationAPI `yaml:"federation_api"`
KeyServer KeyServer `yaml:"key_server"`
MediaAPI MediaAPI `yaml:"media_api"`
RoomServer RoomServer `yaml:"room_server"`
SyncAPI SyncAPI `yaml:"sync_api"`
UserAPI UserAPI `yaml:"user_api"`
Global Global `config:"global"`
AppServiceAPI AppServiceAPI `config:"app_service_api"`
ClientAPI ClientAPI `config:"client_api"`
FederationAPI FederationAPI `config:"federation_api"`
KeyServer KeyServer `config:"key_server"`
MediaAPI MediaAPI `config:"media_api"`
RoomServer RoomServer `config:"room_server"`
SyncAPI SyncAPI `config:"sync_api"`
UserAPI UserAPI `config:"user_api"`
MSCs MSCs `yaml:"mscs"`
MSCs MSCs `config:"mscs"`
// The config for tracing the dendrite servers.
Tracing struct {
// Set to true to enable tracer hooks. If false, no tracing is set up.
Enabled bool `yaml:"enabled"`
Enabled bool `config:"enabled"`
// The config for the jaeger opentracing reporter.
Jaeger jaegerconfig.Configuration `yaml:"jaeger"`
} `yaml:"tracing"`
Jaeger jaegerconfig.Configuration `config:"jaeger"`
} `config:"tracing"`
// The config for logging informations. Each hook will be added to logrus.
Logging []LogrusHook `yaml:"logging"`
Logging []LogrusHook `config:"logging"`
// Any information derived from the configuration options for later use.
Derived Derived `yaml:"-"`
Derived Derived `config:"-"`
IsMonolith bool `yaml:"-"`
IsMonolith bool `config:"-"`
}
// TODO: Kill Derived
@ -114,12 +113,12 @@ type Derived struct {
}
type InternalAPIOptions struct {
Listen HTTPAddress `yaml:"listen"`
Connect HTTPAddress `yaml:"connect"`
Listen HTTPAddress `config:"listen"`
Connect HTTPAddress `config:"connect"`
}
type ExternalAPIOptions struct {
Listen HTTPAddress `yaml:"listen"`
Listen HTTPAddress `config:"listen"`
}
// A Path on the filesystem.
@ -161,13 +160,13 @@ type FileSizeBytes int64
// ThumbnailSize contains a single thumbnail size configuration
type ThumbnailSize struct {
// Maximum width of the thumbnail image
Width int `yaml:"width"`
Width int `config:"width"`
// Maximum height of the thumbnail image
Height int `yaml:"height"`
Height int `config:"height"`
// ResizeMethod is one of crop or scale.
// crop scales to fill the requested dimensions and crops the excess.
// scale scales to fit the requested dimensions and one dimension may be smaller than requested.
ResizeMethod string `yaml:"method,omitempty"`
ResizeMethod string `config:"method,omitempty"`
}
// LogrusHook represents a single logrus hook. At this point, only parsing and
@ -175,60 +174,35 @@ type ThumbnailSize struct {
// Validity/integrity checks on the parameters are done when configuring logrus.
type LogrusHook struct {
// The type of hook, currently only "file" is supported.
Type string `yaml:"type"`
Type string `config:"type"`
// The level of the logs to produce. Will output only this level and above.
Level string `yaml:"level"`
Level string `config:"level"`
// The parameters for this hook.
Params map[string]interface{} `yaml:"params"`
Params map[string]interface{} `config:"params"`
}
// ConfigErrors stores problems encountered when parsing a config file.
// It implements the error interface.
type ConfigErrors []string
// Load a yaml config file for a server run as multiple processes or as a monolith.
// Checks the config to ensure that it is valid.
func Load(configPath string, monolith bool) (*Dendrite, error) {
configData, err := os.ReadFile(configPath)
if err != nil {
return nil, err
}
basePath, err := filepath.Abs(".")
if err != nil {
return nil, err
}
// Pass the current working directory and os.ReadFile so that they can
// be mocked in the tests
return loadConfig(basePath, configData, os.ReadFile, monolith)
}
func loadConfig(
func (c *Dendrite) Load(
basePath string,
configData []byte,
readFile func(string) ([]byte, error),
monolithic bool,
) (*Dendrite, error) {
var c Dendrite
c.Defaults(DefaultOpts{
Generate: false,
Monolithic: monolithic,
})
c.IsMonolith = monolithic
var err error
if err = yaml.Unmarshal(configData, &c); err != nil {
return nil, err
}
) (err error) {
if err = c.check(monolithic); err != nil {
return nil, err
return err
}
privateKeyPath := absPath(basePath, c.Global.PrivateKeyPath)
if c.Global.KeyID, c.Global.PrivateKey, err = LoadMatrixKey(privateKeyPath, readFile); err != nil {
return nil, err
privateKeyData, err := os.ReadFile(privateKeyPath)
if err != nil {
return err
}
if c.Global.KeyID, c.Global.PrivateKey, err = readKeyPEM(privateKeyPath, privateKeyData, true); err != nil {
return err
}
for _, key := range c.Global.OldVerifyKeys {
@ -236,9 +210,9 @@ func loadConfig(
case key.PrivateKeyPath != "":
var oldPrivateKeyData []byte
oldPrivateKeyPath := absPath(basePath, key.PrivateKeyPath)
oldPrivateKeyData, err = readFile(oldPrivateKeyPath)
oldPrivateKeyData, err = os.ReadFile(oldPrivateKeyPath)
if err != nil {
return nil, fmt.Errorf("failed to read %q: %w", oldPrivateKeyPath, err)
return fmt.Errorf("failed to read %q: %w", oldPrivateKeyPath, err)
}
// NOTSPEC: Ordinarily we should enforce key ID formatting, but since there are
@ -246,7 +220,7 @@ func loadConfig(
// to lack of validation in Synapse, we won't enforce that for old verify keys.
keyID, privateKey, perr := readKeyPEM(oldPrivateKeyPath, oldPrivateKeyData, false)
if perr != nil {
return nil, fmt.Errorf("failed to parse %q: %w", oldPrivateKeyPath, perr)
return fmt.Errorf("failed to parse %q: %w", oldPrivateKeyPath, perr)
}
key.KeyID = keyID
@ -254,16 +228,16 @@ func loadConfig(
key.PublicKey = gomatrixserverlib.Base64Bytes(privateKey.Public().(ed25519.PublicKey))
case key.KeyID == "":
return nil, fmt.Errorf("'key_id' must be specified if 'public_key' is specified")
return fmt.Errorf("'key_id' must be specified if 'public_key' is specified")
case len(key.PublicKey) == ed25519.PublicKeySize:
continue
case len(key.PublicKey) > 0:
return nil, fmt.Errorf("the supplied 'public_key' is the wrong length")
return fmt.Errorf("the supplied 'public_key' is the wrong length")
default:
return nil, fmt.Errorf("either specify a 'private_key' path or supply both 'public_key' and 'key_id'")
return fmt.Errorf("either specify a 'private_key' path or supply both 'public_key' and 'key_id'")
}
}
@ -272,11 +246,11 @@ func loadConfig(
// Generate data from config options
err = c.Derive()
if err != nil {
return nil, err
return err
}
c.Wiring()
return &c, nil
return nil
}
func LoadMatrixKey(privateKeyPath string, readFile func(string) ([]byte, error)) (gomatrixserverlib.KeyID, ed25519.PrivateKey, error) {

View file

@ -16,26 +16,28 @@ package config
import (
"fmt"
"os"
"path/filepath"
"regexp"
"strings"
"github.com/knadh/koanf"
"github.com/knadh/koanf/parsers/yaml"
"github.com/knadh/koanf/providers/file"
log "github.com/sirupsen/logrus"
yaml "gopkg.in/yaml.v2"
)
type AppServiceAPI struct {
Matrix *Global `yaml:"-"`
Derived *Derived `yaml:"-"` // TODO: Nuke Derived from orbit
Matrix *Global `config:"-"`
Derived *Derived `config:"-"` // TODO: Nuke Derived from orbit
InternalAPI InternalAPIOptions `yaml:"internal_api,omitempty"`
InternalAPI InternalAPIOptions `config:"internal_api,omitempty"`
// DisableTLSValidation disables the validation of X.509 TLS certs
// on appservice endpoints. This is not recommended in production!
DisableTLSValidation bool `yaml:"disable_tls_validation"`
DisableTLSValidation bool `config:"disable_tls_validation"`
ConfigFiles []string `yaml:"config_files"`
ConfigFiles []string `config:"config_files"`
}
func (c *AppServiceAPI) Defaults(opts DefaultOpts) {
@ -57,9 +59,9 @@ func (c *AppServiceAPI) Verify(configErrs *ConfigErrors, isMonolith bool) {
// service has management over.
type ApplicationServiceNamespace struct {
// Whether or not the namespace is managed solely by this application service
Exclusive bool `yaml:"exclusive"`
Exclusive bool `config:"exclusive"`
// A regex pattern that represents the namespace
Regex string `yaml:"regex"`
Regex string `config:"regex"`
// The ID of an existing group that all users of this application service will
// be added to. This field is only relevant to the `users` namespace.
// Note that users who are joined to this group through an application service
@ -67,7 +69,7 @@ type ApplicationServiceNamespace struct {
// group should be listed when querying an application service user's groups.
// This is to prevent making spamming all users of an application service
// trivial.
GroupID string `yaml:"group_id"`
GroupID string `config:"group_id"`
// Regex object representing our pattern. Saves having to recompile every time
RegexpObject *regexp.Regexp
}
@ -76,22 +78,22 @@ type ApplicationServiceNamespace struct {
// https://matrix.org/docs/spec/application_service/unstable.html
type ApplicationService struct {
// User-defined, unique, persistent ID of the application service
ID string `yaml:"id"`
ID string `config:"id"`
// Base URL of the application service
URL string `yaml:"url"`
URL string `config:"url"`
// Application service token provided in requests to a homeserver
ASToken string `yaml:"as_token"`
ASToken string `config:"as_token"`
// Homeserver token provided in requests to an application service
HSToken string `yaml:"hs_token"`
HSToken string `config:"hs_token"`
// Localpart of application service user
SenderLocalpart string `yaml:"sender_localpart"`
SenderLocalpart string `config:"sender_localpart"`
// Information about an application service's namespaces. Key is either
// "users", "aliases" or "rooms"
NamespaceMap map[string][]ApplicationServiceNamespace `yaml:"namespaces"`
NamespaceMap map[string][]ApplicationServiceNamespace `config:"namespaces"`
// Whether rate limiting is applied to each application service user
RateLimited bool `yaml:"rate_limited"`
RateLimited bool `config:"rate_limited"`
// Any custom protocols that this application service provides (e.g. IRC)
Protocols []string `yaml:"protocols"`
Protocols []string `config:"protocols"`
}
// IsInterestedInRoomID returns a bool on whether an application service's
@ -174,13 +176,13 @@ func loadAppServices(config *AppServiceAPI, derived *Derived) error {
}
// Read the application service's config file
configData, err := os.ReadFile(absPath)
if err != nil {
k := koanf.New("/")
if err := k.Load(file.Provider(absPath), yaml.Parser()); err != nil {
return err
}
// Load the config data into our struct
if err = yaml.Unmarshal(configData, &appservice); err != nil {
if err = k.UnmarshalWithConf("", &appservice, koanf.UnmarshalConf{Tag: "config"}); err != nil {
return err
}

View file

@ -6,55 +6,55 @@ import (
)
type ClientAPI struct {
Matrix *Global `yaml:"-"`
Derived *Derived `yaml:"-"` // TODO: Nuke Derived from orbit
Matrix *Global `config:"-"`
Derived *Derived `config:"-"` // TODO: Nuke Derived from orbit
InternalAPI InternalAPIOptions `yaml:"internal_api,omitempty"`
ExternalAPI ExternalAPIOptions `yaml:"external_api,omitempty"`
InternalAPI InternalAPIOptions `config:"internal_api,omitempty"`
ExternalAPI ExternalAPIOptions `config:"external_api,omitempty"`
// If set disables new users from registering (except via shared
// secrets)
RegistrationDisabled bool `yaml:"registration_disabled"`
RegistrationDisabled bool `config:"registration_disabled"`
// Enable registration without captcha verification or shared secret.
// This option is populated by the -really-enable-open-registration
// command line parameter as it is not recommended.
OpenRegistrationWithoutVerificationEnabled bool `yaml:"-"`
OpenRegistrationWithoutVerificationEnabled bool `config:"-"`
// If set, allows registration by anyone who also has the shared
// secret, even if registration is otherwise disabled.
RegistrationSharedSecret string `yaml:"registration_shared_secret"`
RegistrationSharedSecret string `config:"registration_shared_secret"`
// If set, prevents guest accounts from being created. Only takes
// effect if registration is enabled, otherwise guests registration
// is forbidden either way.
GuestsDisabled bool `yaml:"guests_disabled"`
GuestsDisabled bool `config:"guests_disabled"`
// Boolean stating whether catpcha registration is enabled
// and required
RecaptchaEnabled bool `yaml:"enable_registration_captcha"`
RecaptchaEnabled bool `config:"enable_registration_captcha"`
// Recaptcha api.js Url, for compatible with hcaptcha.com, etc.
RecaptchaApiJsUrl string `yaml:"recaptcha_api_js_url"`
RecaptchaApiJsUrl string `config:"recaptcha_api_js_url"`
// Recaptcha div class for sitekey, for compatible with hcaptcha.com, etc.
RecaptchaSitekeyClass string `yaml:"recaptcha_sitekey_class"`
RecaptchaSitekeyClass string `config:"recaptcha_sitekey_class"`
// Recaptcha form field, for compatible with hcaptcha.com, etc.
RecaptchaFormField string `yaml:"recaptcha_form_field"`
RecaptchaFormField string `config:"recaptcha_form_field"`
// This Home Server's ReCAPTCHA public key.
RecaptchaPublicKey string `yaml:"recaptcha_public_key"`
RecaptchaPublicKey string `config:"recaptcha_public_key"`
// This Home Server's ReCAPTCHA private key.
RecaptchaPrivateKey string `yaml:"recaptcha_private_key"`
RecaptchaPrivateKey string `config:"recaptcha_private_key"`
// Secret used to bypass the captcha registration entirely
RecaptchaBypassSecret string `yaml:"recaptcha_bypass_secret"`
RecaptchaBypassSecret string `config:"recaptcha_bypass_secret"`
// HTTP API endpoint used to verify whether the captcha response
// was successful
RecaptchaSiteVerifyAPI string `yaml:"recaptcha_siteverify_api"`
RecaptchaSiteVerifyAPI string `config:"recaptcha_siteverify_api"`
// TURN options
TURN TURN `yaml:"turn"`
TURN TURN `config:"turn"`
// Rate-limiting options
RateLimiting RateLimiting `yaml:"rate_limiting"`
RateLimiting RateLimiting `config:"rate_limiting"`
MSCs *MSCs `yaml:"-"`
MSCs *MSCs `config:"-"`
}
func (c *ClientAPI) Defaults(opts DefaultOpts) {
@ -118,20 +118,20 @@ func (c *ClientAPI) Verify(configErrs *ConfigErrors, isMonolith bool) {
type TURN struct {
// TODO Guest Support
// Whether or not guests can request TURN credentials
// AllowGuests bool `yaml:"turn_allow_guests"`
// AllowGuests bool `config:"turn_allow_guests"`
// How long the authorization should last
UserLifetime string `yaml:"turn_user_lifetime"`
UserLifetime string `config:"turn_user_lifetime"`
// The list of TURN URIs to pass to clients
URIs []string `yaml:"turn_uris"`
URIs []string `config:"turn_uris"`
// Authorization via Shared Secret
// The shared secret from coturn
SharedSecret string `yaml:"turn_shared_secret"`
SharedSecret string `config:"turn_shared_secret"`
// Authorization via Static Username & Password
// Hardcoded Username and Password
Username string `yaml:"turn_username"`
Password string `yaml:"turn_password"`
Username string `config:"turn_username"`
Password string `config:"turn_password"`
}
func (c *TURN) Verify(configErrs *ConfigErrors) {
@ -145,19 +145,19 @@ func (c *TURN) Verify(configErrs *ConfigErrors) {
type RateLimiting struct {
// Is rate limiting enabled or disabled?
Enabled bool `yaml:"enabled"`
Enabled bool `config:"enabled"`
// How many "slots" a user can occupy sending requests to a rate-limited
// endpoint before we apply rate-limiting
Threshold int64 `yaml:"threshold"`
Threshold int64 `config:"threshold"`
// The cooloff period in milliseconds after a request before the "slot"
// is freed again
CooloffMS int64 `yaml:"cooloff_ms"`
CooloffMS int64 `config:"cooloff_ms"`
// A list of users that are exempt from rate limiting, i.e. if you want
// to run Mjolnir or other bots.
ExemptUserIDs []string `yaml:"exempt_user_ids"`
ExemptUserIDs []string `config:"exempt_user_ids"`
}
func (r *RateLimiting) Verify(configErrs *ConfigErrors) {

View file

@ -3,24 +3,24 @@ package config
import "github.com/matrix-org/gomatrixserverlib"
type FederationAPI struct {
Matrix *Global `yaml:"-"`
Matrix *Global `config:"-"`
InternalAPI InternalAPIOptions `yaml:"internal_api,omitempty"`
ExternalAPI ExternalAPIOptions `yaml:"external_api,omitempty"`
InternalAPI InternalAPIOptions `config:"internal_api,omitempty"`
ExternalAPI ExternalAPIOptions `config:"external_api,omitempty"`
// The database stores information used by the federation destination queues to
// send transactions to remote servers.
Database DatabaseOptions `yaml:"database,omitempty"`
Database DatabaseOptions `config:"database,omitempty"`
// Federation failure threshold. How many consecutive failures that we should
// tolerate when sending federation requests to a specific server. The backoff
// is 2**x seconds, so 1 = 2 seconds, 2 = 4 seconds, 3 = 8 seconds, etc.
// The default value is 16 if not specified, which is circa 18 hours.
FederationMaxRetries uint32 `yaml:"send_max_retries"`
FederationMaxRetries uint32 `config:"send_max_retries"`
// FederationDisableTLSValidation disables the validation of X.509 TLS certs
// on remote federation endpoints. This is not recommended in production!
DisableTLSValidation bool `yaml:"disable_tls_validation"`
DisableTLSValidation bool `config:"disable_tls_validation"`
// DisableHTTPKeepalives prevents Dendrite from keeping HTTP connections
// open for reuse for future requests. Connections will be closed quicker
@ -29,10 +29,10 @@ type FederationAPI struct {
// Perspective keyservers, to use as a backup when direct key fetch
// requests don't succeed
KeyPerspectives KeyPerspectives `yaml:"key_perspectives"`
KeyPerspectives KeyPerspectives `config:"key_perspectives"`
// Should we prefer direct key fetches over perspective ones?
PreferDirectFetch bool `yaml:"prefer_direct_fetch"`
PreferDirectFetch bool `config:"prefer_direct_fetch"`
}
func (c *FederationAPI) Defaults(opts DefaultOpts) {
@ -82,13 +82,13 @@ func (c *FederationAPI) Verify(configErrs *ConfigErrors, isMonolith bool) {
// The config for setting a proxy to use for server->server requests
type Proxy struct {
// Is the proxy enabled?
Enabled bool `yaml:"enabled"`
Enabled bool `config:"enabled"`
// The protocol for the proxy (http / https / socks5)
Protocol string `yaml:"protocol"`
Protocol string `config:"protocol"`
// The host where the proxy is listening
Host string `yaml:"host"`
Host string `config:"host"`
// The port on which the proxy is listening
Port uint16 `yaml:"port"`
Port uint16 `config:"port"`
}
func (c *Proxy) Defaults() {
@ -107,15 +107,15 @@ type KeyPerspectives []KeyPerspective
type KeyPerspective struct {
// The server name of the perspective key server
ServerName gomatrixserverlib.ServerName `yaml:"server_name"`
ServerName gomatrixserverlib.ServerName `config:"server_name"`
// Server keys for the perspective user, used to verify the
// keys have been signed by the perspective server
Keys []KeyPerspectiveTrustKey `yaml:"keys"`
Keys []KeyPerspectiveTrustKey `config:"keys"`
}
type KeyPerspectiveTrustKey struct {
// The key ID, e.g. ed25519:auto
KeyID gomatrixserverlib.KeyID `yaml:"key_id"`
KeyID gomatrixserverlib.KeyID `config:"key_id"`
// The public key in base64 unpadded format
PublicKey string `yaml:"public_key"`
PublicKey string `config:"public_key"`
}

View file

@ -12,78 +12,78 @@ import (
type Global struct {
// The name of the server. This is usually the domain name, e.g 'matrix.org', 'localhost'.
ServerName gomatrixserverlib.ServerName `yaml:"server_name"`
ServerName gomatrixserverlib.ServerName `config:"server_name"`
// The secondary server names, used for virtual hosting.
SecondaryServerNames []gomatrixserverlib.ServerName `yaml:"-"`
// Path to the private key which will be used to sign requests and events.
PrivateKeyPath Path `yaml:"private_key"`
PrivateKeyPath Path `config:"private_key"`
// The private key which will be used to sign requests and events.
PrivateKey ed25519.PrivateKey `yaml:"-"`
PrivateKey ed25519.PrivateKey `config:"-"`
// An arbitrary string used to uniquely identify the PrivateKey. Must start with the
// prefix "ed25519:".
KeyID gomatrixserverlib.KeyID `yaml:"-"`
KeyID gomatrixserverlib.KeyID `config:"-"`
// Information about old private keys that used to be used to sign requests and
// events on this domain. They will not be used but will be advertised to other
// servers that ask for them to help verify old events.
OldVerifyKeys []*OldVerifyKeys `yaml:"old_private_keys"`
OldVerifyKeys []*OldVerifyKeys `config:"old_private_keys"`
// How long a remote server can cache our server key for before requesting it again.
// Increasing this number will reduce the number of requests made by remote servers
// for our key, but increases the period a compromised key will be considered valid
// by remote servers.
// Defaults to 24 hours.
KeyValidityPeriod time.Duration `yaml:"key_validity_period"`
KeyValidityPeriod time.Duration `config:"key_validity_period"`
// Global pool of database connections, which is used only in monolith mode. If a
// component does not specify any database options of its own, then this pool of
// connections will be used instead. This way we don't have to manage connection
// counts on a per-component basis, but can instead do it for the entire monolith.
// In a polylith deployment, this will be ignored.
DatabaseOptions DatabaseOptions `yaml:"database,omitempty"`
DatabaseOptions DatabaseOptions `config:"database,omitempty"`
// The server name to delegate server-server communications to, with optional port
WellKnownServerName string `yaml:"well_known_server_name"`
WellKnownServerName string `config:"well_known_server_name"`
// The server name to delegate client-server communications to, with optional port
WellKnownClientName string `yaml:"well_known_client_name"`
WellKnownClientName string `config:"well_known_client_name"`
// Disables federation. Dendrite will not be able to make any outbound HTTP requests
// to other servers and the federation API will not be exposed.
DisableFederation bool `yaml:"disable_federation"`
DisableFederation bool `config:"disable_federation"`
// Configures the handling of presence events.
Presence PresenceOptions `yaml:"presence"`
Presence PresenceOptions `config:"presence"`
// List of domains that the server will trust as identity servers to
// verify third-party identifiers.
// Defaults to an empty array.
TrustedIDServers []string `yaml:"trusted_third_party_id_servers"`
TrustedIDServers []string `config:"trusted_third_party_id_servers"`
// JetStream configuration
JetStream JetStream `yaml:"jetstream"`
JetStream JetStream `config:"jetstream"`
// Metrics configuration
Metrics Metrics `yaml:"metrics"`
Metrics Metrics `config:"metrics"`
// Sentry configuration
Sentry Sentry `yaml:"sentry"`
Sentry Sentry `config:"sentry"`
// DNS caching options for all outbound HTTP requests
DNSCache DNSCacheOptions `yaml:"dns_cache"`
DNSCache DNSCacheOptions `config:"dns_cache"`
// ServerNotices configuration used for sending server notices
ServerNotices ServerNotices `yaml:"server_notices"`
ServerNotices ServerNotices `config:"server_notices"`
// ReportStats configures opt-in phone-home statistics reporting.
ReportStats ReportStats `yaml:"report_stats"`
ReportStats ReportStats `config:"report_stats"`
// Configuration for the caches.
Cache Cache `yaml:"cache"`
Cache Cache `config:"cache"`
}
func (c *Global) Defaults(opts DefaultOpts) {
@ -137,33 +137,33 @@ func (c *Global) IsLocalServerName(serverName gomatrixserverlib.ServerName) bool
type OldVerifyKeys struct {
// Path to the private key.
PrivateKeyPath Path `yaml:"private_key"`
PrivateKeyPath Path `config:"private_key"`
// The private key itself.
PrivateKey ed25519.PrivateKey `yaml:"-"`
PrivateKey ed25519.PrivateKey `config:"-"`
// The public key, in case only that part is known.
PublicKey gomatrixserverlib.Base64Bytes `yaml:"public_key"`
// The key ID of the private key.
KeyID gomatrixserverlib.KeyID `yaml:"key_id"`
KeyID gomatrixserverlib.KeyID `config:"key_id"`
// When the private key was designed as "expired", as a UNIX timestamp
// in millisecond precision.
ExpiredAt gomatrixserverlib.Timestamp `yaml:"expired_at"`
ExpiredAt gomatrixserverlib.Timestamp `config:"expired_at"`
}
// The configuration to use for Prometheus metrics
type Metrics struct {
// Whether or not the metrics are enabled
Enabled bool `yaml:"enabled"`
Enabled bool `config:"enabled"`
// Use BasicAuth for Authorization
BasicAuth struct {
// Authorization via Static Username & Password
// Hardcoded Username and Password
Username string `yaml:"username"`
Password string `yaml:"password"`
} `yaml:"basic_auth"`
Username string `config:"username"`
Password string `config:"password"`
} `config:"basic_auth"`
}
func (c *Metrics) Defaults(opts DefaultOpts) {
@ -179,15 +179,15 @@ func (c *Metrics) Verify(configErrs *ConfigErrors, isMonolith bool) {
// ServerNotices defines the configuration used for sending server notices
type ServerNotices struct {
Enabled bool `yaml:"enabled"`
Enabled bool `config:"enabled"`
// The localpart to be used when sending notices
LocalPart string `yaml:"local_part"`
LocalPart string `config:"local_part"`
// The displayname to be used when sending notices
DisplayName string `yaml:"display_name"`
DisplayName string `config:"display_name"`
// The avatar of this user
AvatarURL string `yaml:"avatar_url"`
AvatarURL string `config:"avatar_url"`
// The roomname to be used when creating messages
RoomName string `yaml:"room_name"`
RoomName string `config:"room_name"`
}
func (c *ServerNotices) Defaults(opts DefaultOpts) {
@ -203,8 +203,8 @@ func (c *ServerNotices) Defaults(opts DefaultOpts) {
func (c *ServerNotices) Verify(errors *ConfigErrors, isMonolith bool) {}
type Cache struct {
EstimatedMaxSize DataUnit `yaml:"max_size_estimated"`
MaxAge time.Duration `yaml:"max_age"`
EstimatedMaxSize DataUnit `config:"max_size_estimated"`
MaxAge time.Duration `config:"max_age"`
}
func (c *Cache) Defaults() {
@ -219,10 +219,10 @@ func (c *Cache) Verify(errors *ConfigErrors, isMonolith bool) {
// ReportStats configures opt-in phone-home statistics reporting.
type ReportStats struct {
// Enabled configures phone-home statistics of the server
Enabled bool `yaml:"enabled"`
Enabled bool `config:"enabled"`
// Endpoint the endpoint to report stats to
Endpoint string `yaml:"endpoint"`
Endpoint string `config:"endpoint"`
}
func (c *ReportStats) Defaults() {
@ -238,13 +238,13 @@ func (c *ReportStats) Verify(configErrs *ConfigErrors, isMonolith bool) {
// The configuration to use for Sentry error reporting
type Sentry struct {
Enabled bool `yaml:"enabled"`
Enabled bool `config:"enabled"`
// The DSN to connect to e.g "https://examplePublicKey@o0.ingest.sentry.io/0"
// See https://docs.sentry.io/platforms/go/configuration/options/
DSN string `yaml:"dsn"`
DSN string `config:"dsn"`
// The environment e.g "production"
// See https://docs.sentry.io/platforms/go/configuration/environments/
Environment string `yaml:"environment"`
Environment string `config:"environment"`
}
func (c *Sentry) Defaults() {
@ -256,13 +256,13 @@ func (c *Sentry) Verify(configErrs *ConfigErrors, isMonolith bool) {
type DatabaseOptions struct {
// The connection string, file:filename.db or postgres://server....
ConnectionString DataSource `yaml:"connection_string"`
ConnectionString DataSource `config:"connection_string"`
// Maximum open connections to the DB (0 = use default, negative means unlimited)
MaxOpenConnections int `yaml:"max_open_conns"`
MaxOpenConnections int `config:"max_open_conns"`
// Maximum idle connections to the DB (0 = use default, negative means unlimited)
MaxIdleConnections int `yaml:"max_idle_conns"`
MaxIdleConnections int `config:"max_idle_conns"`
// maximum amount of time (in seconds) a connection may be reused (<= 0 means unlimited)
ConnMaxLifetimeSeconds int `yaml:"conn_max_lifetime"`
ConnMaxLifetimeSeconds int `config:"conn_max_lifetime"`
}
func (c *DatabaseOptions) Defaults(conns int) {
@ -291,11 +291,11 @@ func (c DatabaseOptions) ConnMaxLifetime() time.Duration {
type DNSCacheOptions struct {
// Whether the DNS cache is enabled or not
Enabled bool `yaml:"enabled"`
Enabled bool `config:"enabled"`
// How many entries to store in the DNS cache at a given time
CacheSize int `yaml:"cache_size"`
CacheSize int `config:"cache_size"`
// How long a cache entry should be considered valid for
CacheLifetime time.Duration `yaml:"cache_lifetime"`
CacheLifetime time.Duration `config:"cache_lifetime"`
}
func (c *DNSCacheOptions) Defaults() {
@ -312,9 +312,9 @@ func (c *DNSCacheOptions) Verify(configErrs *ConfigErrors, isMonolith bool) {
// PresenceOptions defines possible configurations for presence events.
type PresenceOptions struct {
// Whether inbound presence events are allowed
EnableInbound bool `yaml:"enable_inbound"`
EnableInbound bool `config:"enable_inbound"`
// Whether outbound presence events are allowed
EnableOutbound bool `yaml:"enable_outbound"`
EnableOutbound bool `config:"enable_outbound"`
}
type DataUnit int64

View file

@ -5,22 +5,22 @@ import (
)
type JetStream struct {
Matrix *Global `yaml:"-"`
Matrix *Global `config:"-"`
// Persistent directory to store JetStream streams in.
StoragePath Path `yaml:"storage_path"`
StoragePath Path `config:"storage_path"`
// A list of NATS addresses to connect to. If none are specified, an
// internal NATS server will be used when running in monolith mode only.
Addresses []string `yaml:"addresses"`
Addresses []string `config:"addresses"`
// The prefix to use for stream names for this homeserver - really only
// useful if running more than one Dendrite on the same NATS deployment.
TopicPrefix string `yaml:"topic_prefix"`
TopicPrefix string `config:"topic_prefix"`
// Keep all storage in memory. This is mostly useful for unit tests.
InMemory bool `yaml:"in_memory"`
InMemory bool `config:"in_memory"`
// Disable logging. This is mostly useful for unit tests.
NoLog bool `yaml:"-"`
NoLog bool `config:"-"`
// Disables TLS validation. This should NOT be used in production
DisableTLSValidation bool `yaml:"disable_tls_validation"`
DisableTLSValidation bool `config:"disable_tls_validation"`
}
func (c *JetStream) Prefixed(name string) string {

View file

@ -1,11 +1,11 @@
package config
type KeyServer struct {
Matrix *Global `yaml:"-"`
Matrix *Global `config:"-"`
InternalAPI InternalAPIOptions `yaml:"internal_api,omitempty"`
InternalAPI InternalAPIOptions `config:"internal_api,omitempty"`
Database DatabaseOptions `yaml:"database,omitempty"`
Database DatabaseOptions `config:"database,omitempty"`
}
func (c *KeyServer) Defaults(opts DefaultOpts) {

View file

@ -5,34 +5,34 @@ import (
)
type MediaAPI struct {
Matrix *Global `yaml:"-"`
Matrix *Global `config:"-"`
InternalAPI InternalAPIOptions `yaml:"internal_api,omitempty"`
ExternalAPI ExternalAPIOptions `yaml:"external_api,omitempty"`
InternalAPI InternalAPIOptions `config:"internal_api,omitempty"`
ExternalAPI ExternalAPIOptions `config:"external_api,omitempty"`
// The MediaAPI database stores information about files uploaded and downloaded
// by local users. It is only accessed by the MediaAPI.
Database DatabaseOptions `yaml:"database,omitempty"`
Database DatabaseOptions `config:"database,omitempty"`
// The base path to where the media files will be stored. May be relative or absolute.
BasePath Path `yaml:"base_path"`
BasePath Path `config:"base_path"`
// The absolute base path to where media files will be stored.
AbsBasePath Path `yaml:"-"`
AbsBasePath Path `config:"-"`
// The maximum file size in bytes that is allowed to be stored on this server.
// Note: if max_file_size_bytes is set to 0, the size is unlimited.
// Note: if max_file_size_bytes is not set, it will default to 10485760 (10MB)
MaxFileSizeBytes FileSizeBytes `yaml:"max_file_size_bytes,omitempty"`
MaxFileSizeBytes FileSizeBytes `config:"max_file_size_bytes,omitempty"`
// Whether to dynamically generate thumbnails on-the-fly if the requested resolution is not already generated
DynamicThumbnails bool `yaml:"dynamic_thumbnails"`
DynamicThumbnails bool `config:"dynamic_thumbnails"`
// The maximum number of simultaneous thumbnail generators. default: 10
MaxThumbnailGenerators int `yaml:"max_thumbnail_generators"`
MaxThumbnailGenerators int `config:"max_thumbnail_generators"`
// A list of thumbnail sizes to be pre-generated for downloaded remote / uploaded content
ThumbnailSizes []ThumbnailSize `yaml:"thumbnail_sizes"`
ThumbnailSizes []ThumbnailSize `config:"thumbnail_sizes"`
}
// DefaultMaxFileSizeBytes defines the default file size allowed in transfers

View file

@ -1,16 +1,16 @@
package config
type MSCs struct {
Matrix *Global `yaml:"-"`
Matrix *Global `config:"-"`
// The MSCs to enable. Supported MSCs include:
// 'msc2444': Peeking over federation - https://github.com/matrix-org/matrix-doc/pull/2444
// 'msc2753': Peeking via /sync - https://github.com/matrix-org/matrix-doc/pull/2753
// 'msc2836': Threading - https://github.com/matrix-org/matrix-doc/pull/2836
// 'msc2946': Spaces Summary - https://github.com/matrix-org/matrix-doc/pull/2946
MSCs []string `yaml:"mscs"`
MSCs []string `config:"mscs"`
Database DatabaseOptions `yaml:"database,omitempty"`
Database DatabaseOptions `config:"database,omitempty"`
}
func (c *MSCs) Defaults(opts DefaultOpts) {

View file

@ -1,11 +1,11 @@
package config
type RoomServer struct {
Matrix *Global `yaml:"-"`
Matrix *Global `config:"-"`
InternalAPI InternalAPIOptions `yaml:"internal_api,omitempty"`
InternalAPI InternalAPIOptions `config:"internal_api,omitempty"`
Database DatabaseOptions `yaml:"database,omitempty"`
Database DatabaseOptions `config:"database,omitempty"`
}
func (c *RoomServer) Defaults(opts DefaultOpts) {

View file

@ -1,16 +1,16 @@
package config
type SyncAPI struct {
Matrix *Global `yaml:"-"`
Matrix *Global `config:"-"`
InternalAPI InternalAPIOptions `yaml:"internal_api,omitempty"`
ExternalAPI ExternalAPIOptions `yaml:"external_api,omitempty"`
InternalAPI InternalAPIOptions `config:"internal_api,omitempty"`
ExternalAPI ExternalAPIOptions `config:"external_api,omitempty"`
Database DatabaseOptions `yaml:"database,omitempty"`
Database DatabaseOptions `config:"database,omitempty"`
RealIPHeader string `yaml:"real_ip_header"`
RealIPHeader string `config:"real_ip_header"`
Fulltext Fulltext `yaml:"search"`
Fulltext Fulltext `config:"search"`
}
func (c *SyncAPI) Defaults(opts DefaultOpts) {

View file

@ -18,9 +18,12 @@ import (
"fmt"
"testing"
"gopkg.in/yaml.v2"
"github.com/knadh/koanf"
"github.com/knadh/koanf/parsers/yaml"
"github.com/knadh/koanf/providers/rawbytes"
)
/* - TODO
func TestLoadConfigRelative(t *testing.T) {
_, err := loadConfig("/my/config/dir", []byte(testConfig),
mockReadFile{
@ -33,6 +36,7 @@ func TestLoadConfigRelative(t *testing.T) {
t.Error("failed to load config:", err)
}
}
*/
const testConfig = `
version: 2
@ -274,16 +278,20 @@ ANAf5kxmMsM0zlN2hkxl0H6o7wKlBSw3RI3cjfilXiMWRPJrzlc4
func TestUnmarshalDataUnit(t *testing.T) {
target := struct {
Got DataUnit `yaml:"value"`
Got DataUnit `config:"value"`
}{}
for input, expect := range map[string]DataUnit{
"value: 0.6tb": 659706976665,
"value: 1.2gb": 1288490188,
"value: 256mb": 268435456,
"value: 128kb": 131072,
"value: 128": 128,
`value: "0.6tb"`: 659706976665,
`value: "1.2Gb"`: 1288490188,
`value: "256MB"`: 268435456,
`value: 128kb`: 131072,
`value: "128"`: 128,
} {
if err := yaml.Unmarshal([]byte(input), &target); err != nil {
k := koanf.New("/")
if err := k.Load(rawbytes.Provider([]byte(input)), yaml.Parser()); err != nil {
t.Fatal(err)
}
if err := k.UnmarshalWithConf("", &target, koanf.UnmarshalConf{Tag: "config"}); err != nil {
t.Fatal(err)
} else if target.Got != expect {
t.Fatalf("expected value %d but got %d", expect, target.Got)

View file

@ -3,26 +3,26 @@ package config
import "golang.org/x/crypto/bcrypt"
type UserAPI struct {
Matrix *Global `yaml:"-"`
Matrix *Global `config:"-"`
InternalAPI InternalAPIOptions `yaml:"internal_api,omitempty"`
InternalAPI InternalAPIOptions `config:"internal_api,omitempty"`
// The cost when hashing passwords.
BCryptCost int `yaml:"bcrypt_cost"`
BCryptCost int `config:"bcrypt_cost"`
// The length of time an OpenID token is condidered valid in milliseconds
OpenIDTokenLifetimeMS int64 `yaml:"openid_token_lifetime_ms"`
OpenIDTokenLifetimeMS int64 `config:"openid_token_lifetime_ms"`
// Disable TLS validation on HTTPS calls to push gatways. NOT RECOMMENDED!
PushGatewayDisableTLSValidation bool `yaml:"push_gateway_disable_tls_validation"`
PushGatewayDisableTLSValidation bool `config:"push_gateway_disable_tls_validation"`
// The Account database stores the login details and account information
// for local users. It is accessed by the UserAPI.
AccountDatabase DatabaseOptions `yaml:"account_database,omitempty"`
AccountDatabase DatabaseOptions `config:"account_database,omitempty"`
// Users who register on this homeserver will automatically
// be joined to the rooms listed under this option.
AutoJoinRooms []string `yaml:"auto_join_rooms"`
AutoJoinRooms []string `config:"auto_join_rooms"`
}
const DefaultOpenIDTokenLifetimeMS = 3600000 // 60 minutes

View file

@ -1,57 +0,0 @@
// Copyright 2020 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package setup
import (
"flag"
"fmt"
"os"
"github.com/matrix-org/dendrite/internal"
"github.com/matrix-org/dendrite/setup/config"
"github.com/sirupsen/logrus"
)
var (
configPath = flag.String("config", "dendrite.yaml", "The path to the config file. For more information, see the config file in this repository.")
version = flag.Bool("version", false, "Shows the current version and exits immediately.")
enableRegistrationWithoutVerification = flag.Bool("really-enable-open-registration", false, "This allows open registration without secondary verification (reCAPTCHA). This is NOT RECOMMENDED and will SIGNIFICANTLY increase the risk that your server will be used to send spam or conduct attacks, which may result in your server being banned from rooms.")
)
// ParseFlags parses the commandline flags and uses them to create a config.
func ParseFlags(monolith bool) *config.Dendrite {
flag.Parse()
if *version {
fmt.Println(internal.VersionString())
os.Exit(0)
}
if *configPath == "" {
logrus.Fatal("--config must be supplied")
}
cfg, err := config.Load(*configPath, monolith)
if err != nil {
logrus.Fatalf("Invalid config file: %s", err)
}
if *enableRegistrationWithoutVerification {
cfg.ClientAPI.OpenRegistrationWithoutVerificationEnabled = true
}
return cfg
}