diff --git a/CHANGELOG.md b/CHANGELOG.md index 4145f82f2..81c14be56 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,13 +23,25 @@ Currently only HTTP Connect proxies which don't require authentication are suppo ## Component Updates and Bug Fixes -* github.com/openziti/storage: [v0.2.18 -> v0.2.19](https://github.com/openziti/storage/compare/v0.2.18...v0.2.19) +* github.com/openziti/channel/v2: [v2.0.99 -> v2.0.101](https://github.com/openziti/channel/compare/v2.0.99...v2.0.101) +* github.com/openziti/edge-api: [v0.25.37 -> v0.25.38](https://github.com/openziti/edge-api/compare/v0.25.37...v0.25.38) +* github.com/openziti/foundation/v2: [v2.0.32 -> v2.0.33](https://github.com/openziti/foundation/compare/v2.0.32...v2.0.33) +* github.com/openziti/identity: [v1.0.63 -> v1.0.64](https://github.com/openziti/identity/compare/v1.0.63...v1.0.64) +* github.com/openziti/metrics: [v1.2.35 -> v1.2.36](https://github.com/openziti/metrics/compare/v1.2.35...v1.2.36) +* github.com/openziti/runzmd: [v1.0.32 -> v1.0.33](https://github.com/openziti/runzmd/compare/v1.0.32...v1.0.33) +* github.com/openziti/sdk-golang: [v0.20.116 -> v0.20.122](https://github.com/openziti/sdk-golang/compare/v0.20.116...v0.20.122) + * [Issue #436](https://github.com/openziti/sdk-golang/issues/436) - HTTP calls should respect environment proxy settings + +* github.com/openziti/storage: [v0.2.18 -> v0.2.20](https://github.com/openziti/storage/compare/v0.2.18...v0.2.20) * [Issue #52](https://github.com/openziti/storage/issues/52) - Grammar should expect single valid query followed by EOF +* github.com/openziti/transport/v2: [v2.0.107 -> v2.0.109](https://github.com/openziti/transport/compare/v2.0.107...v2.0.109) * github.com/openziti/ziti: [v0.30.4 -> v0.30.5](https://github.com/openziti/ziti/compare/v0.30.4...v0.30.5) * [Issue #1336](https://github.com/openziti/ziti/issues/1336) - `ziti edge quickstart` did not create the usual edge router/service edge router policy. * [Issue #1397](https://github.com/openziti/ziti/issues/1397) - HTTP Proxy suport for host.v1/host.v2 config types + * [Issue #1423](https://github.com/openziti/ziti/issues/1423) - Controller crashes when edge router reconnects (Client Hello) + * [Issue #1414](https://github.com/openziti/ziti/issues/1414) - Race condition in xgress_edge_tunnel tunneller at start but not seen in pre-compiled binary * [Issue #1406](https://github.com/openziti/ziti/issues/1406) - Entity change event dispatcher isn't shutting down properly when controller shuts down * [Issue #1382](https://github.com/openziti/ziti/issues/1382) - service failure costs are not shrinking over time diff --git a/ziti/cmd/database/add_debug_admin.go b/ziti/cmd/database/add_debug_admin.go new file mode 100644 index 000000000..09009df2c --- /dev/null +++ b/ziti/cmd/database/add_debug_admin.go @@ -0,0 +1,138 @@ +/* + Copyright NetFoundry Inc. + + 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 + + https://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 database + +import ( + "fmt" + "github.com/google/uuid" + "github.com/openziti/storage/boltz" + "github.com/openziti/ziti/common/eid" + "github.com/openziti/ziti/controller/change" + "github.com/openziti/ziti/controller/command" + "github.com/openziti/ziti/controller/db" + "github.com/openziti/ziti/controller/model" + "github.com/openziti/ziti/controller/network" + "github.com/openziti/ziti/controller/persistence" + "github.com/spf13/cobra" +) + +func NewAddDebugAdminAction() *cobra.Command { + action := &addDebugAdminAction{} + return &cobra.Command{ + Use: "add-debug-admin ", + Short: "Adds an admin user to the given database file for debugging purposes", + Args: cobra.ExactArgs(3), + Run: func(cmd *cobra.Command, args []string) { + action.run(args[0], args[1], args[2]) + }, + } +} + +type addDebugAdminAction struct { + db boltz.Db + stores *db.Stores + managers *network.Managers +} + +func (action *addDebugAdminAction) GetDb() boltz.Db { + return action.db +} + +func (action *addDebugAdminAction) GetStores() *db.Stores { + return action.stores +} + +func (action *addDebugAdminAction) GetManagers() *network.Managers { + return action.managers +} + +func (action *addDebugAdminAction) noError(err error) { + if err != nil { + panic(err) + } +} + +func (action *addDebugAdminAction) run(dbFile, username, password string) { + boltDb, err := db.Open(dbFile) + action.noError(err) + + fabricStores, err := db.InitStores(boltDb) + action.noError(err) + + dispatcher := &command.LocalDispatcher{ + EncodeDecodeCommands: false, + } + controllers := network.NewManagers(nil, dispatcher, boltDb, fabricStores, nil) + + dbProvider := &addDebugAdminAction{ + db: boltDb, + stores: fabricStores, + managers: controllers, + } + + stores, err := persistence.NewBoltStores(dbProvider) + action.noError(err) + + id := "debug-admin" + name := fmt.Sprintf("debug admin (%v)", uuid.NewString()) + ctx := change.New().SetChangeAuthorType("cli.debug-db").NewMutateContext() + err = dbProvider.GetDb().Update(ctx, func(ctx boltz.MutateContext) error { + tx := ctx.Tx() + identity, _ := stores.Identity.LoadOneById(tx, id) + if identity != nil { + if err = stores.Identity.DeleteById(ctx, id); err != nil { + return err + } + fmt.Printf("removing existing identity with id '%v'\n", id) + } + + identity = &persistence.Identity{ + BaseExtEntity: boltz.BaseExtEntity{Id: id}, + Name: name, + IdentityTypeId: persistence.DefaultIdentityType, + IsDefaultAdmin: false, + IsAdmin: true, + } + if err = stores.Identity.Create(ctx, identity); err != nil { + return err + } + + authHandler := model.AuthenticatorManager{} + result := authHandler.HashPassword(password) + authenticator := &persistence.AuthenticatorUpdb{ + Authenticator: persistence.Authenticator{ + BaseExtEntity: boltz.BaseExtEntity{ + Id: eid.New(), + }, + Type: "updb", + IdentityId: id, + }, + Username: username, + Password: result.Password, + Salt: result.Salt, + } + authenticator.SubType = authenticator + + if err = stores.Authenticator.Create(ctx, &authenticator.Authenticator); err != nil { + return err + } + + fmt.Printf("added debug admin with username '%v'\n", username) + return nil + }) + action.noError(err) +} diff --git a/ziti/cmd/database/cmd.go b/ziti/cmd/database/cmd.go index f26bfe68d..79bc89e2a 100644 --- a/ziti/cmd/database/cmd.go +++ b/ziti/cmd/database/cmd.go @@ -25,6 +25,7 @@ func NewCmdDb(out io.Writer, errOut io.Writer) *cobra.Command { cmd.AddCommand(exploreCmd) cmd.AddCommand(NewCompactAction()) cmd.AddCommand(NewDiskUsageAction()) + cmd.AddCommand(NewAddDebugAdminAction()) return cmd } diff --git a/ziti/internal/log/log.go b/ziti/internal/log/log.go index 0d905d629..48182ec06 100644 --- a/ziti/internal/log/log.go +++ b/ziti/internal/log/log.go @@ -61,58 +61,3 @@ func Fatalf(msg string, args ...interface{}) { func Fatal(msg string) { color.Red(msg) } - -func Success(msg string) { - color.Green(msg) -} - -func Successf(msg string, args ...interface{}) { - Success(fmt.Sprintf(msg, args...)) -} - -func Failure(msg string) { - color.Red(msg) -} - -func Failuref(msg string, args ...interface{}) { - Failure(fmt.Sprintf(msg, args...)) -} - -// AskForConfirmation uses Scanln to parse user input. A user must type in "yes" or "no" and -// then press enter. It has fuzzy matching, so "y", "Y", "yes", "YES", and "Yes" all count as -// confirmations. If the input is not recognized, it will ask again. The function does not return -// until it gets a valid response from the user. Typically, you should use fmt to print out a question -// before calling askForConfirmation. E.g. fmt.Println("WARNING: Are you sure? (yes/no)") -func AskForConfirmation(def bool) bool { - var response string - fmt.Scanln(&response) - if len(response) == 0 { - return def - } - okayResponses := []string{"y", "Y", "yes", "Yes", "YES"} - nokayResponses := []string{"n", "N", "no", "No", "NO"} - if containsString(okayResponses, response) { - return true - } else if containsString(nokayResponses, response) { - return false - } else { - Warn("Please type y or n & press enter: ") - return AskForConfirmation(def) - } -} - -// posString returns the first index of element in slice. -// If slice does not contain element, returns -1. -func posString(slice []string, element string) int { - for index, elem := range slice { - if elem == element { - return index - } - } - return -1 -} - -// containsString returns true iff slice contains element -func containsString(slice []string, element string) bool { - return !(posString(slice, element) == -1) -}