mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 20:27:32 +00:00
works
This commit is contained in:
@@ -1,9 +1,9 @@
|
|||||||
package configure
|
package configure
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/Masterminds/semver/v3"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
"github.com/zitadel/zitadel/backend/cmd/config"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -70,24 +70,21 @@ func (s sub) Fields() []Updater {
|
|||||||
return []Updater{
|
return []Updater{
|
||||||
Field[string]{
|
Field[string]{
|
||||||
FieldName: "f1",
|
FieldName: "f1",
|
||||||
Value: &s.F1,
|
Value: "",
|
||||||
Default: "",
|
|
||||||
Description: "field 1",
|
Description: "field 1",
|
||||||
Version: config.V3,
|
Version: semver.MustParse("3"),
|
||||||
},
|
},
|
||||||
Field[int]{
|
Field[int]{
|
||||||
FieldName: "f2",
|
FieldName: "f2",
|
||||||
Value: &s.F2,
|
Value: 0,
|
||||||
Default: 0,
|
|
||||||
Description: "field 2",
|
Description: "field 2",
|
||||||
Version: config.V3,
|
Version: semver.MustParse("3"),
|
||||||
},
|
},
|
||||||
Field[*bool]{
|
Field[*bool]{
|
||||||
FieldName: "f3",
|
FieldName: "f3",
|
||||||
Value: &s.F3,
|
Value: nil,
|
||||||
Default: nil,
|
|
||||||
Description: "field 3",
|
Description: "field 3",
|
||||||
Version: config.V3,
|
Version: semver.MustParse("3"),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -101,10 +98,9 @@ func (t test) Fields() []Updater {
|
|||||||
return []Updater{
|
return []Updater{
|
||||||
Field[string]{
|
Field[string]{
|
||||||
FieldName: "f1",
|
FieldName: "f1",
|
||||||
Value: &t.F1,
|
Value: "",
|
||||||
Default: "",
|
|
||||||
Description: "field 1",
|
Description: "field 1",
|
||||||
Version: config.V3,
|
Version: semver.MustParse("3"),
|
||||||
},
|
},
|
||||||
Struct{
|
Struct{
|
||||||
FieldName: "sub",
|
FieldName: "sub",
|
||||||
|
@@ -1,246 +0,0 @@
|
|||||||
package configure
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"reflect"
|
|
||||||
|
|
||||||
"github.com/manifoldco/promptui"
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
"github.com/spf13/viper"
|
|
||||||
"github.com/zitadel/zitadel/backend/cmd/config"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Update(name, description string, fields []Updater) func(cmd *cobra.Command, args []string) {
|
|
||||||
return func(cmd *cobra.Command, args []string) {
|
|
||||||
u := Struct{
|
|
||||||
FieldName: name,
|
|
||||||
Description: description,
|
|
||||||
SubFields: fields,
|
|
||||||
}
|
|
||||||
fields := viper.AllSettings()
|
|
||||||
updateStruct(u, fields, 1)
|
|
||||||
|
|
||||||
fmt.Println("Using config file:", viper.ConfigFileUsed(), "fields:", fields)
|
|
||||||
// viper.MergeConfigMap(fields)
|
|
||||||
// if err := viper.WriteConfig(); err != nil {
|
|
||||||
// panic(err)
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func updateStruct(updater StructUpdater, fields map[string]any, depth int) {
|
|
||||||
for _, field := range updater.Fields() {
|
|
||||||
// fmt.Printf("field: %s.%s\n %s\n", parent, field.Name(), field.Describe())
|
|
||||||
setField(field, fields, depth)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func setField(field Updater, fields map[string]any, depth int) {
|
|
||||||
if !field.ShouldUpdate(config.V3) {
|
|
||||||
prompt := promptui.Prompt{
|
|
||||||
Label: field.Name() + " did not change since last configure, skip?",
|
|
||||||
IsConfirm: true,
|
|
||||||
}
|
|
||||||
if _, err := prompt.Run(); err == nil {
|
|
||||||
fmt.Println("skip")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
fmt.Println(field.Name(), field.Describe())
|
|
||||||
switch f := field.(type) {
|
|
||||||
case StructUpdater:
|
|
||||||
if fields[f.Name()] == nil {
|
|
||||||
fields[f.Name()] = map[string]any{}
|
|
||||||
}
|
|
||||||
fmt.Printf("%.*s %s: %s\n", depth*2, "-", f.Name(), f.Describe())
|
|
||||||
updateStruct(f, fields[f.Name()].(map[string]any), depth+1)
|
|
||||||
case FieldUpdater:
|
|
||||||
prompt := promptui.Prompt{
|
|
||||||
Label: fmt.Sprintf("%s (%s) (%T)", f.Name(), f.Describe(), f.DefaultValue()),
|
|
||||||
Default: fmt.Sprintf("%v", f.DefaultValue()),
|
|
||||||
Validate: func(s string) error {
|
|
||||||
if isConfirm(reflect.TypeOf(f.DefaultValue())) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return f.Set(s)
|
|
||||||
},
|
|
||||||
IsConfirm: isConfirm(reflect.TypeOf(f.DefaultValue())),
|
|
||||||
}
|
|
||||||
val, err := prompt.Run()
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
fields[f.Name()] = f.Set(val)
|
|
||||||
case OneOfUpdater:
|
|
||||||
var possibilities []string
|
|
||||||
for _, subField := range f.Fields() {
|
|
||||||
possibilities = append(possibilities, subField.Name())
|
|
||||||
fields[subField.Name()] = subField
|
|
||||||
}
|
|
||||||
|
|
||||||
prompt := promptui.Select{
|
|
||||||
Label: fmt.Sprintf("Select one of %s: (%s)", f.Name(), f.Describe()),
|
|
||||||
Items: possibilities,
|
|
||||||
}
|
|
||||||
i, value, err := prompt.Run()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("panic", err)
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
fv := fields[value]
|
|
||||||
// TODO: fv is result of decoder (postgres.config in this case)
|
|
||||||
setField(f.Fields()[i], fv.(map[string]any), depth+1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func isConfirm(t reflect.Type) bool {
|
|
||||||
if t.Kind() == reflect.Ptr {
|
|
||||||
return isConfirm(t.Elem())
|
|
||||||
}
|
|
||||||
return t.Kind() == reflect.Bool
|
|
||||||
}
|
|
||||||
|
|
||||||
type Updater interface {
|
|
||||||
Name() string
|
|
||||||
Describe() string
|
|
||||||
ShouldUpdate(version config.Version) bool
|
|
||||||
}
|
|
||||||
|
|
||||||
type FieldUpdater interface {
|
|
||||||
Updater
|
|
||||||
DefaultValue() any
|
|
||||||
Set(value string) error
|
|
||||||
_field()
|
|
||||||
}
|
|
||||||
|
|
||||||
type StructUpdater interface {
|
|
||||||
Updater
|
|
||||||
Fields() []Updater
|
|
||||||
_struct()
|
|
||||||
}
|
|
||||||
|
|
||||||
type OneOfUpdater interface {
|
|
||||||
Updater
|
|
||||||
Fields() []Updater
|
|
||||||
_oneOf()
|
|
||||||
}
|
|
||||||
|
|
||||||
var _ FieldUpdater = (*Field[string])(nil)
|
|
||||||
|
|
||||||
type Field[T any] struct {
|
|
||||||
FieldName string
|
|
||||||
Default T
|
|
||||||
Value *T
|
|
||||||
Description string
|
|
||||||
Version config.Version
|
|
||||||
}
|
|
||||||
|
|
||||||
// DefaultValue implements [FieldUpdater].
|
|
||||||
func (uf Field[T]) DefaultValue() any {
|
|
||||||
return uf.Default
|
|
||||||
}
|
|
||||||
|
|
||||||
// Describe implements [FieldUpdater].
|
|
||||||
func (uf Field[T]) Describe() string {
|
|
||||||
return uf.Description
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set implements [FieldUpdater].
|
|
||||||
func (uf Field[T]) Set(value string) error {
|
|
||||||
var v T
|
|
||||||
if err := json.Unmarshal([]byte(value), &v); err != nil {
|
|
||||||
return fmt.Errorf("failed to unmarshal value: %v", err)
|
|
||||||
}
|
|
||||||
*uf.Value = v
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field implements [FieldUpdater].
|
|
||||||
func (uf Field[T]) Name() string {
|
|
||||||
return uf.FieldName
|
|
||||||
}
|
|
||||||
|
|
||||||
// ShouldUpdate implements [FieldUpdater].
|
|
||||||
func (uf Field[T]) ShouldUpdate(version config.Version) bool {
|
|
||||||
return uf.Version <= version
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f Field[T]) _field() {}
|
|
||||||
|
|
||||||
var _ StructUpdater = (*Struct)(nil)
|
|
||||||
|
|
||||||
type Struct struct {
|
|
||||||
FieldName string
|
|
||||||
Description string
|
|
||||||
SubFields []Updater
|
|
||||||
}
|
|
||||||
|
|
||||||
// Describe implements [StructUpdater].
|
|
||||||
func (us Struct) Describe() string {
|
|
||||||
return us.Description
|
|
||||||
}
|
|
||||||
|
|
||||||
func (us Struct) Name() string {
|
|
||||||
return us.FieldName
|
|
||||||
}
|
|
||||||
|
|
||||||
func (us Struct) Fields() []Updater {
|
|
||||||
return us.SubFields
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f Struct) _struct() {}
|
|
||||||
|
|
||||||
type OneOf struct {
|
|
||||||
FieldName string
|
|
||||||
Description string
|
|
||||||
SubFields []Updater
|
|
||||||
}
|
|
||||||
|
|
||||||
// Describe implements [OneOfUpdater].
|
|
||||||
func (o OneOf) Describe() string {
|
|
||||||
return o.Description
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fields implements [OneOfUpdater].
|
|
||||||
func (o OneOf) Fields() []Updater {
|
|
||||||
return o.SubFields
|
|
||||||
}
|
|
||||||
|
|
||||||
// Name implements [FieldUpdater].
|
|
||||||
func (o OneOf) Name() string {
|
|
||||||
return o.FieldName
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f OneOf) _oneOf() {}
|
|
||||||
|
|
||||||
// ShouldUpdate implements [OneOfUpdater].
|
|
||||||
func (o OneOf) ShouldUpdate(version config.Version) bool {
|
|
||||||
for _, field := range o.SubFields {
|
|
||||||
if !field.ShouldUpdate(version) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
var _ OneOfUpdater = (*OneOf)(nil)
|
|
||||||
|
|
||||||
func (us Struct) ShouldUpdate(version config.Version) bool {
|
|
||||||
for _, field := range us.SubFields {
|
|
||||||
if !field.ShouldUpdate(version) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func FieldName(parent, field string) string {
|
|
||||||
if parent == "" {
|
|
||||||
return field
|
|
||||||
}
|
|
||||||
return parent + "." + field
|
|
||||||
}
|
|
@@ -1,109 +0,0 @@
|
|||||||
package configure
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"reflect"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/manifoldco/promptui"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Update2(config any) {
|
|
||||||
// Print the intro
|
|
||||||
printIntro()
|
|
||||||
|
|
||||||
// Start the interactive CLI
|
|
||||||
interactiveCLI(reflect.ValueOf(config), 0)
|
|
||||||
fmt.Println(config)
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
ExitValue = "<Exit>"
|
|
||||||
BackValue = "⬅ Back"
|
|
||||||
Prefix = "📁 "
|
|
||||||
)
|
|
||||||
|
|
||||||
var introTemplate = `
|
|
||||||
+----------------------------------------+
|
|
||||||
| 🛠 Config Interactive CLI 🛠 |
|
|
||||||
+----------------------------------------+
|
|
||||||
| |
|
|
||||||
| %5s : Dive into nested config |
|
|
||||||
| %6s : Return to previous menu |
|
|
||||||
| %6s : Exit application |
|
|
||||||
| |
|
|
||||||
| Choose an option to explore! |
|
|
||||||
| |
|
|
||||||
+----------------------------------------+
|
|
||||||
`
|
|
||||||
|
|
||||||
func printIntro() {
|
|
||||||
fmt.Printf(introTemplate, Prefix, BackValue, ExitValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
// interactiveCLI handles the interactive CLI
|
|
||||||
func interactiveCLI(v reflect.Value, depth int) {
|
|
||||||
for {
|
|
||||||
var items []string
|
|
||||||
|
|
||||||
// If depth is greater than 0, we are in a nested struct and should add a "Back" option
|
|
||||||
if depth > 0 {
|
|
||||||
items = append(items, BackValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add all the field names
|
|
||||||
items = append(items, getFieldNames(v)...)
|
|
||||||
|
|
||||||
// Add an "Exit" option
|
|
||||||
items = append(items, ExitValue)
|
|
||||||
|
|
||||||
prompt := promptui.Select{
|
|
||||||
Label: "Select Field",
|
|
||||||
Items: items,
|
|
||||||
}
|
|
||||||
|
|
||||||
_, result, err := prompt.Run()
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("Prompt failed %v\n", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
switch result {
|
|
||||||
case BackValue:
|
|
||||||
return
|
|
||||||
case ExitValue:
|
|
||||||
// Exit the entire application
|
|
||||||
os.Exit(0)
|
|
||||||
default:
|
|
||||||
fieldName := strings.TrimPrefix(result, Prefix)
|
|
||||||
selectedField := v.FieldByName(fieldName)
|
|
||||||
if selectedField.Kind() == reflect.Struct {
|
|
||||||
interactiveCLI(selectedField, depth+1)
|
|
||||||
} else {
|
|
||||||
prompt := promptui.Prompt{
|
|
||||||
Label: fmt.Sprintf("Field %s (%s)", result, selectedField.Kind()),
|
|
||||||
Default: fmt.Sprintf("%v", selectedField.Interface()),
|
|
||||||
}
|
|
||||||
res, err := prompt.Run()
|
|
||||||
fmt.Println(res, err)
|
|
||||||
// fmt.Printf("%s: %v\n", result, selectedField.Interface())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// getFieldNames returns all the field names
|
|
||||||
func getFieldNames(v reflect.Value) []string {
|
|
||||||
t := v.Type()
|
|
||||||
var fieldNames []string
|
|
||||||
for i := 0; i < v.NumField(); i++ {
|
|
||||||
fieldName := t.Field(i).Name
|
|
||||||
if v.Field(i).Kind() == reflect.Struct {
|
|
||||||
fieldName = Prefix + fieldName
|
|
||||||
}
|
|
||||||
fieldNames = append(fieldNames, fieldName)
|
|
||||||
}
|
|
||||||
return fieldNames
|
|
||||||
}
|
|
449
backend/cmd/configure/update_config3.go
Normal file
449
backend/cmd/configure/update_config3.go
Normal file
@@ -0,0 +1,449 @@
|
|||||||
|
package configure
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/Masterminds/semver/v3"
|
||||||
|
"github.com/manifoldco/promptui"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
|
"github.com/zitadel/zitadel/backend/cmd/info"
|
||||||
|
)
|
||||||
|
|
||||||
|
var lastConfiguredVersion *semver.Version
|
||||||
|
|
||||||
|
func Update(name, description string, fields []Updater) func(cmd *cobra.Command, args []string) {
|
||||||
|
return func(cmd *cobra.Command, args []string) {
|
||||||
|
configVersion := viper.GetString("configuredVersion")
|
||||||
|
if configVersion != "" {
|
||||||
|
lastConfiguredVersion, _ = semver.NewVersion(configVersion)
|
||||||
|
}
|
||||||
|
for _, field := range fields {
|
||||||
|
if err := setField(field, "", 1); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Using config file:", viper.ConfigFileUsed(), "fields:", fields)
|
||||||
|
fmt.Println(viper.AllSettings())
|
||||||
|
viper.Set("configuredVersion", info.Version().String())
|
||||||
|
// viper.MergeConfigMap(fields)
|
||||||
|
// if err := viper.WriteConfig(); err != nil {
|
||||||
|
// panic(err)
|
||||||
|
// }
|
||||||
|
if err := viper.WriteConfig(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func setField(field Updater, parentPath string, depth int) error {
|
||||||
|
if !field.ShouldUpdate(lastConfiguredVersion) {
|
||||||
|
prompt := promptui.Prompt{
|
||||||
|
Label: field.Name() + " did not change since last configure, skip?",
|
||||||
|
IsConfirm: true,
|
||||||
|
}
|
||||||
|
if _, err := prompt.Run(); err == nil {
|
||||||
|
fmt.Println("skip")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fieldPath := path(parentPath, field.Name())
|
||||||
|
switch f := field.(type) {
|
||||||
|
case StructUpdater:
|
||||||
|
fmt.Printf("\n%.*s %s: %s\n\n", depth*2, "-", f.Name(), f.Describe())
|
||||||
|
for _, subField := range f.Fields() {
|
||||||
|
err := setField(subField, fieldPath, depth+1)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case FieldUpdater:
|
||||||
|
value := viper.Get(fieldPath)
|
||||||
|
if value == nil {
|
||||||
|
value = f.ValueOrDefault()
|
||||||
|
}
|
||||||
|
prompt := promptui.Prompt{
|
||||||
|
Label: fmt.Sprintf("%s (%s) (%T)", f.Name(), f.Describe(), f.ValueOrDefault()),
|
||||||
|
Default: fmt.Sprintf("%v", value),
|
||||||
|
Validate: func(s string) error {
|
||||||
|
if isConfirm(reflect.TypeOf(value)) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return f.Set(s)
|
||||||
|
},
|
||||||
|
HideEntered: f.ShouldHide(),
|
||||||
|
IsConfirm: isConfirm(reflect.TypeOf(value)),
|
||||||
|
}
|
||||||
|
_, err := prompt.Run()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
viper.Set(fieldPath, f.ValueOrDefault())
|
||||||
|
case OneOfUpdater:
|
||||||
|
var possibilities []string
|
||||||
|
for _, subField := range f.Fields() {
|
||||||
|
possibility := subField.Name()
|
||||||
|
if possibility == "" {
|
||||||
|
possibility = subField.Describe()
|
||||||
|
}
|
||||||
|
possibilities = append(possibilities, possibility)
|
||||||
|
}
|
||||||
|
|
||||||
|
prompt := promptui.Select{
|
||||||
|
Label: fmt.Sprintf("Select one of %s: (%s)", f.Name(), f.Describe()),
|
||||||
|
Items: possibilities,
|
||||||
|
}
|
||||||
|
i, _, err := prompt.Run()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("panic", err)
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
setField(f.Fields()[i], fieldPath, depth-1)
|
||||||
|
// TODO: fv is result of decoder (postgres.config in this case)
|
||||||
|
case ConstantUpdater:
|
||||||
|
viper.Set(fieldPath, f.Value())
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func path(parent, field string) string {
|
||||||
|
if parent == "" {
|
||||||
|
return field
|
||||||
|
}
|
||||||
|
if strings.HasSuffix(parent, field) {
|
||||||
|
return parent
|
||||||
|
}
|
||||||
|
if field == "" {
|
||||||
|
return parent
|
||||||
|
}
|
||||||
|
return parent + "." + field
|
||||||
|
}
|
||||||
|
|
||||||
|
func isConfirm(t reflect.Type) bool {
|
||||||
|
if t == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if t.Kind() == reflect.Ptr {
|
||||||
|
return isConfirm(t.Elem())
|
||||||
|
}
|
||||||
|
return t.Kind() == reflect.Bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type Updater interface {
|
||||||
|
Name() string
|
||||||
|
Describe() string
|
||||||
|
ShouldUpdate(version *semver.Version) bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type FieldUpdater interface {
|
||||||
|
Updater
|
||||||
|
// DefaultValue() any
|
||||||
|
Set(value any) error
|
||||||
|
ValueOrDefault() any
|
||||||
|
_field()
|
||||||
|
ShouldHide() bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type StructUpdater interface {
|
||||||
|
Updater
|
||||||
|
Fields() []Updater
|
||||||
|
_struct()
|
||||||
|
}
|
||||||
|
|
||||||
|
type OneOfUpdater interface {
|
||||||
|
Updater
|
||||||
|
Fields() []Updater
|
||||||
|
_oneOf()
|
||||||
|
}
|
||||||
|
|
||||||
|
type ConstantUpdater interface {
|
||||||
|
Updater
|
||||||
|
Value() any
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ FieldUpdater = (*Field[string])(nil)
|
||||||
|
|
||||||
|
type Field[T any] struct {
|
||||||
|
FieldName string
|
||||||
|
Value T
|
||||||
|
HideInput bool
|
||||||
|
Description string
|
||||||
|
Version *semver.Version
|
||||||
|
Validate func(T) error
|
||||||
|
}
|
||||||
|
|
||||||
|
// Describe implements [FieldUpdater].
|
||||||
|
func (f Field[T]) Describe() string {
|
||||||
|
return f.Description
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set implements [FieldUpdater].
|
||||||
|
func (f *Field[T]) Set(value any) (err error) {
|
||||||
|
switch v := value.(type) {
|
||||||
|
case string:
|
||||||
|
f.Value, err = mapString[T](v)
|
||||||
|
case map[string]any:
|
||||||
|
f.Value, err = mapMap[T](v)
|
||||||
|
case T:
|
||||||
|
f.Value = v
|
||||||
|
default:
|
||||||
|
err = fmt.Errorf("unsupported type %T", v)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil || f.Validate == nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return f.Validate(f.Value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f Field[T]) ValueOrDefault() any {
|
||||||
|
return f.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
func mapMap[T any](value map[string]any) (t T, err error) {
|
||||||
|
jsonValue, err := json.Marshal(value)
|
||||||
|
if err != nil {
|
||||||
|
return t, err
|
||||||
|
}
|
||||||
|
return t, json.Unmarshal(jsonValue, &t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func mapString[T any](value string) (t T, err error) {
|
||||||
|
var v any
|
||||||
|
switch reflect.TypeFor[T]().Kind() {
|
||||||
|
case reflect.Bool:
|
||||||
|
v, err = strconv.ParseBool(value)
|
||||||
|
if err != nil {
|
||||||
|
return t, err
|
||||||
|
}
|
||||||
|
case reflect.Int:
|
||||||
|
i, err := strconv.ParseInt(value, 10, 0)
|
||||||
|
if err != nil {
|
||||||
|
return t, err
|
||||||
|
}
|
||||||
|
v = int(i)
|
||||||
|
case reflect.Int8:
|
||||||
|
i, err := strconv.ParseInt(value, 10, 8)
|
||||||
|
if err != nil {
|
||||||
|
return t, err
|
||||||
|
}
|
||||||
|
v = int8(i)
|
||||||
|
case reflect.Int16:
|
||||||
|
i, err := strconv.ParseInt(value, 10, 16)
|
||||||
|
if err != nil {
|
||||||
|
return t, err
|
||||||
|
}
|
||||||
|
v = int16(i)
|
||||||
|
case reflect.Int32:
|
||||||
|
i, err := strconv.ParseInt(value, 10, 32)
|
||||||
|
if err != nil {
|
||||||
|
return t, err
|
||||||
|
}
|
||||||
|
v = int32(i)
|
||||||
|
case reflect.Int64:
|
||||||
|
i, err := strconv.ParseInt(value, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return t, err
|
||||||
|
}
|
||||||
|
v = int64(i)
|
||||||
|
case reflect.Uint:
|
||||||
|
i, err := strconv.ParseUint(value, 10, 0)
|
||||||
|
if err != nil {
|
||||||
|
return t, err
|
||||||
|
}
|
||||||
|
v = uint(i)
|
||||||
|
case reflect.Uint8:
|
||||||
|
i, err := strconv.ParseUint(value, 10, 8)
|
||||||
|
if err != nil {
|
||||||
|
return t, err
|
||||||
|
}
|
||||||
|
v = uint8(i)
|
||||||
|
case reflect.Uint16:
|
||||||
|
i, err := strconv.ParseUint(value, 10, 16)
|
||||||
|
if err != nil {
|
||||||
|
return t, err
|
||||||
|
}
|
||||||
|
v = uint16(i)
|
||||||
|
case reflect.Uint32:
|
||||||
|
i, err := strconv.ParseUint(value, 10, 32)
|
||||||
|
if err != nil {
|
||||||
|
return t, err
|
||||||
|
}
|
||||||
|
v = uint32(i)
|
||||||
|
case reflect.Uint64:
|
||||||
|
i, err := strconv.ParseUint(value, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return t, err
|
||||||
|
}
|
||||||
|
v = uint64(i)
|
||||||
|
case reflect.Float32:
|
||||||
|
i, err := strconv.ParseFloat(value, 32)
|
||||||
|
if err != nil {
|
||||||
|
return t, err
|
||||||
|
}
|
||||||
|
v = float32(i)
|
||||||
|
case reflect.Float64:
|
||||||
|
i, err := strconv.ParseFloat(value, 64)
|
||||||
|
if err != nil {
|
||||||
|
return t, err
|
||||||
|
}
|
||||||
|
v = float64(i)
|
||||||
|
case reflect.Complex64:
|
||||||
|
i, err := strconv.ParseComplex(value, 64)
|
||||||
|
if err != nil {
|
||||||
|
return t, err
|
||||||
|
}
|
||||||
|
v = complex64(i)
|
||||||
|
case reflect.Complex128:
|
||||||
|
v, err = strconv.ParseComplex(value, 128)
|
||||||
|
case reflect.String:
|
||||||
|
v = value
|
||||||
|
default:
|
||||||
|
k := reflect.TypeFor[T]().Kind()
|
||||||
|
_ = k
|
||||||
|
return t, errors.New("not implemented")
|
||||||
|
}
|
||||||
|
return v.(T), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Field implements [FieldUpdater].
|
||||||
|
func (f Field[T]) Name() string {
|
||||||
|
return f.FieldName
|
||||||
|
}
|
||||||
|
|
||||||
|
// ShouldUpdate implements [FieldUpdater].
|
||||||
|
func (f Field[T]) ShouldUpdate(version *semver.Version) bool {
|
||||||
|
if version == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return f.Version.GreaterThan(version)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ShouldHide implements [FieldUpdater].
|
||||||
|
func (f Field[T]) ShouldHide() bool {
|
||||||
|
return f.HideInput
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f Field[T]) _field() {}
|
||||||
|
|
||||||
|
var _ StructUpdater = (*Struct)(nil)
|
||||||
|
|
||||||
|
type Struct struct {
|
||||||
|
FieldName string
|
||||||
|
Description string
|
||||||
|
SubFields []Updater
|
||||||
|
}
|
||||||
|
|
||||||
|
// Describe implements [StructUpdater].
|
||||||
|
func (s Struct) Describe() string {
|
||||||
|
return s.Description
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s Struct) Name() string {
|
||||||
|
return s.FieldName
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s Struct) Fields() []Updater {
|
||||||
|
return s.SubFields
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s Struct) ShouldUpdate(version *semver.Version) bool {
|
||||||
|
if version == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
for _, field := range s.SubFields {
|
||||||
|
if !field.ShouldUpdate(version) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (Struct) _struct() {}
|
||||||
|
|
||||||
|
type OneOf struct {
|
||||||
|
FieldName string
|
||||||
|
Description string
|
||||||
|
SubFields []Updater
|
||||||
|
}
|
||||||
|
|
||||||
|
// Describe implements [OneOfUpdater].
|
||||||
|
func (o OneOf) Describe() string {
|
||||||
|
return o.Description
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fields implements [OneOfUpdater].
|
||||||
|
func (o OneOf) Fields() []Updater {
|
||||||
|
return o.SubFields
|
||||||
|
}
|
||||||
|
|
||||||
|
// Name implements [FieldUpdater].
|
||||||
|
func (o OneOf) Name() string {
|
||||||
|
return o.FieldName
|
||||||
|
}
|
||||||
|
|
||||||
|
func (OneOf) _oneOf() {}
|
||||||
|
|
||||||
|
// ShouldUpdate implements [OneOfUpdater].
|
||||||
|
func (o OneOf) ShouldUpdate(version *semver.Version) bool {
|
||||||
|
if version == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, field := range o.SubFields {
|
||||||
|
if !field.ShouldUpdate(version) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ OneOfUpdater = (*OneOf)(nil)
|
||||||
|
|
||||||
|
func FieldName(parent, field string) string {
|
||||||
|
if parent == "" {
|
||||||
|
return field
|
||||||
|
}
|
||||||
|
return parent + "." + field
|
||||||
|
}
|
||||||
|
|
||||||
|
type Constant[T any] struct {
|
||||||
|
Description string
|
||||||
|
Constant T
|
||||||
|
Version *semver.Version
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ ConstantUpdater = (*Constant[any])(nil)
|
||||||
|
|
||||||
|
// Describe implements [ConstantUpdater].
|
||||||
|
func (c Constant[T]) Describe() string {
|
||||||
|
return c.Description
|
||||||
|
}
|
||||||
|
|
||||||
|
// Name implements [ConstantUpdater].
|
||||||
|
func (c Constant[T]) Name() string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// ShouldUpdate implements [ConstantUpdater].
|
||||||
|
func (c Constant[T]) ShouldUpdate(version *semver.Version) bool {
|
||||||
|
if version == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return c.Version.GreaterThan(version)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Value implements [ConstantUpdater].
|
||||||
|
func (c Constant[T]) Value() any {
|
||||||
|
return c.Constant
|
||||||
|
}
|
36
backend/cmd/info/config.go
Normal file
36
backend/cmd/info/config.go
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
package info
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/Masterminds/semver/v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
version string
|
||||||
|
commit string
|
||||||
|
date string
|
||||||
|
)
|
||||||
|
|
||||||
|
func Version() *semver.Version {
|
||||||
|
v, _ := semver.NewVersion(version)
|
||||||
|
if v != nil {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
return semver.New(uint64(Date().Year()), uint64(Date().Month()), uint64(Date().Day()), "", "")
|
||||||
|
}
|
||||||
|
|
||||||
|
func Commit() string {
|
||||||
|
return commit
|
||||||
|
}
|
||||||
|
|
||||||
|
func Date() time.Time {
|
||||||
|
if date == "" {
|
||||||
|
return time.Now()
|
||||||
|
}
|
||||||
|
d, err := time.Parse(time.RFC3339, date)
|
||||||
|
if err != nil {
|
||||||
|
return time.Now()
|
||||||
|
}
|
||||||
|
return d
|
||||||
|
}
|
@@ -5,7 +5,8 @@ import (
|
|||||||
"embed"
|
"embed"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/backend/cmd/config"
|
"github.com/Masterminds/semver/v3"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/backend/cmd/configure"
|
"github.com/zitadel/zitadel/backend/cmd/configure"
|
||||||
"github.com/zitadel/zitadel/backend/storage/database"
|
"github.com/zitadel/zitadel/backend/storage/database"
|
||||||
)
|
)
|
||||||
@@ -18,26 +19,24 @@ var (
|
|||||||
type Step001 struct {
|
type Step001 struct {
|
||||||
Database database.Pool `mapstructure:"-"`
|
Database database.Pool `mapstructure:"-"`
|
||||||
|
|
||||||
DatabaseName string `configure:"added:"v3",default:"zitadel"`
|
DatabaseName string
|
||||||
Username string `configure:"added:"v3",default:"zitadel"`
|
Username string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fields implements configure.StructUpdater.
|
// Fields implements configure.StructUpdater.
|
||||||
func (v Step001) Fields() []configure.Updater {
|
func (v Step001) Fields() []configure.Updater {
|
||||||
return []configure.Updater{
|
return []configure.Updater{
|
||||||
configure.Field[string]{
|
&configure.Field[string]{
|
||||||
FieldName: "databaseName",
|
FieldName: "databaseName",
|
||||||
Default: "zitadel",
|
Value: "zitadel",
|
||||||
Value: &v.DatabaseName,
|
|
||||||
Description: "The name of the database Zitadel will store its data in",
|
Description: "The name of the database Zitadel will store its data in",
|
||||||
Version: config.V3,
|
Version: semver.MustParse("3"),
|
||||||
},
|
},
|
||||||
configure.Field[string]{
|
&configure.Field[string]{
|
||||||
FieldName: "username",
|
FieldName: "username",
|
||||||
Default: "zitadel",
|
Value: "zitadel",
|
||||||
Value: &v.Username,
|
|
||||||
Description: "The username Zitadel will use to connect to the database",
|
Description: "The username Zitadel will use to connect to the database",
|
||||||
Version: config.V3,
|
Version: semver.MustParse("3"),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
package prepare
|
package prepare
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/Masterminds/semver/v3"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
@@ -65,7 +66,10 @@ func (c *Config) Name() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ShouldUpdate implements configure.StructUpdater.
|
// ShouldUpdate implements configure.StructUpdater.
|
||||||
func (c *Config) ShouldUpdate(version config.Version) bool {
|
func (c *Config) ShouldUpdate(version *semver.Version) bool {
|
||||||
|
if version == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
for _, field := range c.Fields() {
|
for _, field := range c.Fields() {
|
||||||
if field.ShouldUpdate(version) {
|
if field.ShouldUpdate(version) {
|
||||||
return true
|
return true
|
||||||
@@ -77,12 +81,12 @@ func (c *Config) ShouldUpdate(version config.Version) bool {
|
|||||||
// Fields implements configure.UpdateConfig.
|
// Fields implements configure.UpdateConfig.
|
||||||
func (c Config) Fields() []configure.Updater {
|
func (c Config) Fields() []configure.Updater {
|
||||||
return []configure.Updater{
|
return []configure.Updater{
|
||||||
configure.Struct{
|
&configure.Struct{
|
||||||
FieldName: "step001",
|
FieldName: "step001",
|
||||||
Description: "The configuration for the first step of the prepare command",
|
Description: "The configuration for the first step of the prepare command",
|
||||||
SubFields: c.Step001.Fields(),
|
SubFields: c.Step001.Fields(),
|
||||||
},
|
},
|
||||||
configure.Struct{
|
&configure.Struct{
|
||||||
FieldName: "database",
|
FieldName: "database",
|
||||||
Description: "The configuration for the database connection",
|
Description: "The configuration for the database connection",
|
||||||
SubFields: c.Database.Fields(),
|
SubFields: c.Database.Fields(),
|
||||||
|
@@ -2,6 +2,7 @@ package prepare
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
step001 "github.com/zitadel/zitadel/backend/cmd/prepare/001"
|
step001 "github.com/zitadel/zitadel/backend/cmd/prepare/001"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@@ -1,19 +1,6 @@
|
|||||||
|
configuredversion: 2025.2.23
|
||||||
database:
|
database:
|
||||||
cockroach:
|
postgres: host=local
|
||||||
host: localhost
|
|
||||||
port: 26257
|
|
||||||
gosql:
|
|
||||||
fieldname: gosql
|
|
||||||
default: null
|
|
||||||
value: null
|
|
||||||
description: Configuration for connection string for gosql
|
|
||||||
version: 1
|
|
||||||
postgres:
|
|
||||||
fieldname: postgres
|
|
||||||
default: null
|
|
||||||
value: null
|
|
||||||
description: Configuration for connection string for postgres
|
|
||||||
version: 1
|
|
||||||
step001:
|
step001:
|
||||||
databasename: zitadel
|
databasename: zita
|
||||||
username: zitadel
|
username: adel
|
||||||
|
@@ -20,6 +20,7 @@ type Hook struct {
|
|||||||
Match func(string) bool
|
Match func(string) bool
|
||||||
Decode func(name string, config any) (database.Connector, error)
|
Decode func(name string, config any) (database.Connector, error)
|
||||||
Name string
|
Name string
|
||||||
|
Field configure.Updater
|
||||||
}
|
}
|
||||||
|
|
||||||
var hooks = make([]Hook, 0)
|
var hooks = make([]Hook, 0)
|
||||||
@@ -30,11 +31,13 @@ func init() {
|
|||||||
Match: postgres.NameMatcher,
|
Match: postgres.NameMatcher,
|
||||||
Decode: postgres.DecodeConfig,
|
Decode: postgres.DecodeConfig,
|
||||||
Name: postgres.Name,
|
Name: postgres.Name,
|
||||||
|
Field: postgres.Field,
|
||||||
},
|
},
|
||||||
Hook{
|
Hook{
|
||||||
Match: gosql.NameMatcher,
|
Match: gosql.NameMatcher,
|
||||||
Decode: gosql.DecodeConfig,
|
Decode: gosql.DecodeConfig,
|
||||||
Name: gosql.Name,
|
Name: gosql.Name,
|
||||||
|
Field: gosql.Field,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -48,18 +51,17 @@ type Config struct {
|
|||||||
// Fields implements [configure.StructUpdater].
|
// Fields implements [configure.StructUpdater].
|
||||||
func (c *Config) Fields() []configure.Updater {
|
func (c *Config) Fields() []configure.Updater {
|
||||||
dialects := configure.OneOf{
|
dialects := configure.OneOf{
|
||||||
FieldName: "dialect",
|
|
||||||
Description: "The database dialect Zitadel connects to",
|
Description: "The database dialect Zitadel connects to",
|
||||||
SubFields: []configure.Updater{},
|
SubFields: []configure.Updater{},
|
||||||
}
|
}
|
||||||
for _, hook := range hooks {
|
for _, hook := range hooks {
|
||||||
value := c.Dialects[hook.Name]
|
if hook.Field == nil {
|
||||||
dialects.SubFields = append(dialects.SubFields, &configure.Field[any]{
|
panic("hook must configure its config fields")
|
||||||
|
}
|
||||||
|
dialects.SubFields = append(dialects.SubFields, &configure.Struct{
|
||||||
FieldName: hook.Name,
|
FieldName: hook.Name,
|
||||||
Default: nil,
|
Description: fmt.Sprintf("Configuration for %s", hook.Name),
|
||||||
Description: fmt.Sprintf("Configuration for connection string for %s", hook.Name),
|
SubFields: []configure.Updater{hook.Field},
|
||||||
Version: config.V3,
|
|
||||||
Value: &value,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -6,12 +6,25 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/Masterminds/semver/v3"
|
||||||
|
"github.com/jackc/pgx/v5/pgxpool"
|
||||||
|
|
||||||
|
"github.com/zitadel/zitadel/backend/cmd/configure"
|
||||||
"github.com/zitadel/zitadel/backend/storage/database"
|
"github.com/zitadel/zitadel/backend/storage/database"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
_ database.Connector = (*Config)(nil)
|
_ database.Connector = (*Config)(nil)
|
||||||
|
|
||||||
Name = "gosql"
|
Name = "gosql"
|
||||||
|
Field = &configure.Field[string]{
|
||||||
|
Description: "Connection string",
|
||||||
|
Version: semver.MustParse("v3"),
|
||||||
|
Validate: func(s string) error {
|
||||||
|
_, err := pgxpool.ParseConfig(s)
|
||||||
|
return err
|
||||||
|
},
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
|
@@ -6,14 +6,91 @@ import (
|
|||||||
"slices"
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/Masterminds/semver/v3"
|
||||||
"github.com/jackc/pgx/v5/pgxpool"
|
"github.com/jackc/pgx/v5/pgxpool"
|
||||||
|
|
||||||
|
"github.com/zitadel/zitadel/backend/cmd/configure"
|
||||||
"github.com/zitadel/zitadel/backend/storage/database"
|
"github.com/zitadel/zitadel/backend/storage/database"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
_ database.Connector = (*Config)(nil)
|
_ database.Connector = (*Config)(nil)
|
||||||
Name = "postgres"
|
Name = "postgres"
|
||||||
|
|
||||||
|
Field = &configure.OneOf{
|
||||||
|
Description: "Configuring postgres using one of the following options",
|
||||||
|
SubFields: []configure.Updater{
|
||||||
|
&configure.Field[string]{
|
||||||
|
Description: "Connection string",
|
||||||
|
Version: semver.MustParse("v3"),
|
||||||
|
Validate: func(s string) error {
|
||||||
|
_, err := pgxpool.ParseConfig(s)
|
||||||
|
return err
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&configure.Struct{
|
||||||
|
Description: "Configuration for the connection",
|
||||||
|
SubFields: []configure.Updater{
|
||||||
|
&configure.Field[string]{
|
||||||
|
FieldName: "host",
|
||||||
|
Value: "localhost",
|
||||||
|
Description: "The host to connect to",
|
||||||
|
Version: semver.MustParse("3"),
|
||||||
|
},
|
||||||
|
&configure.Field[uint32]{
|
||||||
|
FieldName: "port",
|
||||||
|
Value: 5432,
|
||||||
|
Description: "The port to connect to",
|
||||||
|
Version: semver.MustParse("3"),
|
||||||
|
},
|
||||||
|
&configure.Field[string]{
|
||||||
|
FieldName: "database",
|
||||||
|
Value: "zitadel",
|
||||||
|
Description: "The database to connect to",
|
||||||
|
Version: semver.MustParse("3"),
|
||||||
|
},
|
||||||
|
&configure.Field[string]{
|
||||||
|
FieldName: "user",
|
||||||
|
Description: "The user to connect as",
|
||||||
|
Value: "zitadel",
|
||||||
|
Version: semver.MustParse("3"),
|
||||||
|
},
|
||||||
|
&configure.Field[string]{
|
||||||
|
FieldName: "password",
|
||||||
|
Description: "The password to connect with",
|
||||||
|
Version: semver.MustParse("3"),
|
||||||
|
HideInput: true,
|
||||||
|
},
|
||||||
|
&configure.OneOf{
|
||||||
|
FieldName: "sslMode",
|
||||||
|
Description: "The SSL mode to use",
|
||||||
|
SubFields: []configure.Updater{
|
||||||
|
&configure.Constant[string]{
|
||||||
|
Description: "Disable",
|
||||||
|
Constant: "disable",
|
||||||
|
Version: semver.MustParse("3"),
|
||||||
|
},
|
||||||
|
&configure.Constant[string]{
|
||||||
|
Description: "Require",
|
||||||
|
Constant: "require",
|
||||||
|
Version: semver.MustParse("3"),
|
||||||
|
},
|
||||||
|
&configure.Constant[string]{
|
||||||
|
Description: "Verify CA",
|
||||||
|
Constant: "verify-ca",
|
||||||
|
Version: semver.MustParse("3"),
|
||||||
|
},
|
||||||
|
&configure.Constant[string]{
|
||||||
|
Description: "Verify Full",
|
||||||
|
Constant: "verify-full",
|
||||||
|
Version: semver.MustParse("3"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
type Config struct{ *pgxpool.Config }
|
type Config struct{ *pgxpool.Config }
|
||||||
|
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/jackc/pgx/v5/pgxpool"
|
"github.com/jackc/pgx/v5/pgxpool"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/backend/storage/database"
|
"github.com/zitadel/zitadel/backend/storage/database"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/jackc/pgx/v5/pgxpool"
|
"github.com/jackc/pgx/v5/pgxpool"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/backend/storage/database"
|
"github.com/zitadel/zitadel/backend/storage/database"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@@ -2,6 +2,7 @@ package postgres
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/jackc/pgx/v5"
|
"github.com/jackc/pgx/v5"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/backend/storage/database"
|
"github.com/zitadel/zitadel/backend/storage/database"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/jackc/pgx/v5"
|
"github.com/jackc/pgx/v5"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/backend/storage/database"
|
"github.com/zitadel/zitadel/backend/storage/database"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
1
go.mod
1
go.mod
@@ -100,6 +100,7 @@ require (
|
|||||||
cloud.google.com/go/auth v0.6.1 // indirect
|
cloud.google.com/go/auth v0.6.1 // indirect
|
||||||
cloud.google.com/go/auth/oauth2adapt v0.2.2 // indirect
|
cloud.google.com/go/auth/oauth2adapt v0.2.2 // indirect
|
||||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.48.0 // indirect
|
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.48.0 // indirect
|
||||||
|
github.com/Masterminds/semver/v3 v3.3.1 // indirect
|
||||||
github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a // indirect
|
github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a // indirect
|
||||||
github.com/bmatcuk/doublestar/v4 v4.7.1 // indirect
|
github.com/bmatcuk/doublestar/v4 v4.7.1 // indirect
|
||||||
github.com/chzyer/readline v1.5.1 // indirect
|
github.com/chzyer/readline v1.5.1 // indirect
|
||||||
|
2
go.sum
2
go.sum
@@ -38,6 +38,8 @@ github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0
|
|||||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.48.0 h1:ng6QH9Z4bAXCf0Z1cjR5hKESyc1BUiOrfIOhN+nHfRU=
|
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.48.0 h1:ng6QH9Z4bAXCf0Z1cjR5hKESyc1BUiOrfIOhN+nHfRU=
|
||||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.48.0/go.mod h1:ZC7rjqRzdhRKDK223jQ7Tsz89ZtrSSLH/VFzf7k5Sb0=
|
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.48.0/go.mod h1:ZC7rjqRzdhRKDK223jQ7Tsz89ZtrSSLH/VFzf7k5Sb0=
|
||||||
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
|
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
|
||||||
|
github.com/Masterminds/semver/v3 v3.3.1 h1:QtNSWtVZ3nBfk8mAOu/B6v7FMJ+NHTIgUPi7rj+4nv4=
|
||||||
|
github.com/Masterminds/semver/v3 v3.3.1/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
|
||||||
github.com/Masterminds/squirrel v1.5.4 h1:uUcX/aBc8O7Fg9kaISIUsHXdKuqehiXAMQTYX8afzqM=
|
github.com/Masterminds/squirrel v1.5.4 h1:uUcX/aBc8O7Fg9kaISIUsHXdKuqehiXAMQTYX8afzqM=
|
||||||
github.com/Masterminds/squirrel v1.5.4/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10=
|
github.com/Masterminds/squirrel v1.5.4/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10=
|
||||||
github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
|
github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
|
||||||
|
Reference in New Issue
Block a user