package cmd import ( "bytes" "context" "crypto/fips140" _ "embed" "errors" "io" "strings" "github.com/spf13/cobra" "github.com/spf13/viper" "github.com/zitadel/zitadel/backend/v3/instrumentation/logging" "github.com/zitadel/zitadel/cmd/admin" "github.com/zitadel/zitadel/cmd/build" "github.com/zitadel/zitadel/cmd/initialise" "github.com/zitadel/zitadel/cmd/key" "github.com/zitadel/zitadel/cmd/mirror" "github.com/zitadel/zitadel/cmd/ready" "github.com/zitadel/zitadel/cmd/setup" "github.com/zitadel/zitadel/cmd/start" ) var ( configFiles []string //go:embed defaults.yaml defaultConfig []byte //go:embed defaults_fips.yaml defaultFipsConfig []byte ) func New(out io.Writer, in io.Reader, args []string, server chan<- *start.Server) *cobra.Command { cmd := &cobra.Command{ Use: "zitadel", Short: "The ZITADEL CLI lets you interact with ZITADEL", Long: `The ZITADEL CLI lets you interact with ZITADEL`, RunE: func(cmd *cobra.Command, args []string) error { return errors.New("no additional command provided") }, Version: build.Version(), SilenceUsage: true, } viper.AutomaticEnv() viper.SetEnvPrefix("ZITADEL") viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) viper.SetConfigType("yaml") err := loadDefaultConfig() logging.OnError(context.Background(), err).Fatal("unable to read default config") cobra.OnInitialize(initConfig) cmd.PersistentFlags().StringArrayVar(&configFiles, "config", nil, "path to config file to overwrite system defaults") cmd.AddCommand( admin.New(), //is now deprecated, remove later on initialise.New(), setup.New(), start.New(server), start.NewStartFromInit(server), start.NewStartFromSetup(server), mirror.New(&configFiles), key.New(), ready.New(), ) cmd.InitDefaultVersionFlag() return cmd } func loadDefaultConfig() error { return loadDefaultConfigInto(viper.GetViper()) } func loadDefaultConfigInto(v *viper.Viper) error { if err := v.ReadConfig(bytes.NewBuffer(defaultConfig)); err != nil { return err } return mergeFipsDefaultConfig(v) } func mergeFipsDefaultConfig(v *viper.Viper) error { if !fips140.Enabled() { return nil } return applyFipsDefaultOverlay(v) } func applyFipsDefaultOverlay(v *viper.Viper) error { return v.MergeConfig(bytes.NewBuffer(defaultFipsConfig)) } func initConfig() { for _, file := range configFiles { viper.SetConfigFile(file) err := viper.MergeInConfig() logging.OnError(context.Background(), err).Warn("unable to read config file", "file", file) } }