mirror of
https://github.com/openziti/ziti.git
synced 2026-10-12 07:18:36 +00:00
Add 'add-debug-admin' command. Fixes #1436
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
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 (
|
||||
"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>",
|
||||
Short: "Adds an admin (username: admin, password: admin) to the given database file for debugging purposes",
|
||||
Args: cobra.ExactArgs(1),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
action.run(args[0])
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
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 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 := "7dbd3fc9-e4c8-489a-ab8f-4bbb3d768f57"
|
||||
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 {
|
||||
identity = &persistence.Identity{
|
||||
BaseExtEntity: boltz.BaseExtEntity{Id: id},
|
||||
Name: "DebugAdmin",
|
||||
IdentityTypeId: "Default",
|
||||
IsDefaultAdmin: false,
|
||||
IsAdmin: true,
|
||||
}
|
||||
if err = stores.Identity.Create(ctx, identity); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
authHandler := model.AuthenticatorManager{}
|
||||
result := authHandler.HashPassword("admin")
|
||||
authenticator := &persistence.AuthenticatorUpdb{
|
||||
Authenticator: persistence.Authenticator{
|
||||
BaseExtEntity: boltz.BaseExtEntity{
|
||||
Id: eid.New(),
|
||||
},
|
||||
Type: "updb",
|
||||
IdentityId: id,
|
||||
},
|
||||
Username: "admin",
|
||||
Password: result.Password,
|
||||
Salt: result.Salt,
|
||||
}
|
||||
authenticator.SubType = authenticator
|
||||
|
||||
if err = stores.Authenticator.Create(ctx, &authenticator.Authenticator); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
action.noError(err)
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user