Skip to content

Commit

Permalink
Merge pull request #1437 from openziti/add-debug-admin
Browse files Browse the repository at this point in the history
Update Changelog/deps and add command to add debug admin
  • Loading branch information
plorenz authored Oct 13, 2023
2 parents 8d58228 + 10df7d9 commit c5a51df
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 56 deletions.
14 changes: 13 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
138 changes: 138 additions & 0 deletions ziti/cmd/database/add_debug_admin.go
Original file line number Diff line number Diff line change
@@ -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 </path/to/ziti-controller.db.file> <username> <password>",
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)
}
1 change: 1 addition & 0 deletions ziti/cmd/database/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
55 changes: 0 additions & 55 deletions ziti/internal/log/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

0 comments on commit c5a51df

Please sign in to comment.