mirror of
https://github.com/photoprism/photoprism.git
synced 2025-12-12 00:34:13 +01:00
CLI: Improve output of "photoprism config" command #5285
Signed-off-by: Michael Mayer <michael@photoprism.app>
This commit is contained in:
@@ -115,9 +115,7 @@ func (c *Config) normalizeDatabaseDSN() {
|
|||||||
|
|
||||||
// DatabaseDSN returns the database data source name (DSN).
|
// DatabaseDSN returns the database data source name (DSN).
|
||||||
func (c *Config) DatabaseDSN() string {
|
func (c *Config) DatabaseDSN() string {
|
||||||
c.normalizeDatabaseDSN()
|
if c.NoDatabaseDSN() {
|
||||||
|
|
||||||
if c.options.DatabaseDSN == "" {
|
|
||||||
switch c.DatabaseDriver() {
|
switch c.DatabaseDriver() {
|
||||||
case MySQL, MariaDB:
|
case MySQL, MariaDB:
|
||||||
databaseServer := c.DatabaseServer()
|
databaseServer := c.DatabaseServer()
|
||||||
@@ -159,11 +157,33 @@ func (c *Config) DatabaseDSN() string {
|
|||||||
return c.options.DatabaseDSN
|
return c.options.DatabaseDSN
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParseDatabaseDSN parses the database dsn and extracts user, password, database server, and name.
|
// NoDatabaseDSN checks if no manual database data source name (DSN) configuration is set.
|
||||||
func (c *Config) ParseDatabaseDSN() {
|
func (c *Config) NoDatabaseDSN() bool {
|
||||||
c.normalizeDatabaseDSN()
|
c.normalizeDatabaseDSN()
|
||||||
|
|
||||||
if c.options.DatabaseDSN == "" || c.options.DatabaseServer != "" {
|
return c.options.DatabaseDSN == ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasDatabaseDSN checks if a manual database data source name (DSN) configuration is set.
|
||||||
|
func (c *Config) HasDatabaseDSN() bool {
|
||||||
|
return !c.NoDatabaseDSN()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReportDatabaseDSN checks if the database data source name (DSN) should be reported
|
||||||
|
// instead of database name, server, user, and password.
|
||||||
|
func (c *Config) ReportDatabaseDSN() bool {
|
||||||
|
if c.DatabaseDriver() == SQLite3 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.HasDatabaseDSN()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseDatabaseDSN parses the database dsn and extracts user, password, database server, and name.
|
||||||
|
func (c *Config) ParseDatabaseDSN() {
|
||||||
|
if c.NoDatabaseDSN() {
|
||||||
|
return
|
||||||
|
} else if c.options.DatabaseServer != "" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -105,6 +105,26 @@ func TestConfig_ParseDatabaseDSN(t *testing.T) {
|
|||||||
assert.Equal(t, "foo:b@r@tcp(honeypot:1234)/baz?charset=utf8mb4,utf8&parseTime=true", c.DatabaseName())
|
assert.Equal(t, "foo:b@r@tcp(honeypot:1234)/baz?charset=utf8mb4,utf8&parseTime=true", c.DatabaseName())
|
||||||
assert.Equal(t, "", c.DatabaseUser())
|
assert.Equal(t, "", c.DatabaseUser())
|
||||||
assert.Equal(t, "", c.DatabasePassword())
|
assert.Equal(t, "", c.DatabasePassword())
|
||||||
|
|
||||||
|
t.Run("ManualServerConfig", func(t *testing.T) {
|
||||||
|
target := NewConfig(CliTestContext())
|
||||||
|
resetDatabaseOptions(target)
|
||||||
|
|
||||||
|
target.options.DatabaseDriver = MySQL
|
||||||
|
target.options.DatabaseServer = "db.internal:3306"
|
||||||
|
target.options.DatabaseName = "photoprism"
|
||||||
|
target.options.DatabaseUser = "app"
|
||||||
|
target.options.DatabasePassword = "secret"
|
||||||
|
target.options.DatabaseDSN = "foo:b@r@tcp(otherhost:3307)/other?charset=utf8mb4,utf8&parseTime=true"
|
||||||
|
|
||||||
|
target.ParseDatabaseDSN()
|
||||||
|
|
||||||
|
assert.Equal(t, "db.internal:3306", target.options.DatabaseServer)
|
||||||
|
assert.Equal(t, "db.internal", target.DatabaseHost())
|
||||||
|
assert.Equal(t, "photoprism", target.options.DatabaseName)
|
||||||
|
assert.Equal(t, "app", target.options.DatabaseUser)
|
||||||
|
assert.Equal(t, "secret", target.options.DatabasePassword)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestConfig_DatabaseServer(t *testing.T) {
|
func TestConfig_DatabaseServer(t *testing.T) {
|
||||||
@@ -203,6 +223,43 @@ func TestConfig_DatabaseDSN(t *testing.T) {
|
|||||||
assert.Equal(t, "/go/src/github.com/photoprism/photoprism/storage/testdata/index.db?_busy_timeout=5000", c.DatabaseDSN())
|
assert.Equal(t, "/go/src/github.com/photoprism/photoprism/storage/testdata/index.db?_busy_timeout=5000", c.DatabaseDSN())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestConfig_DatabaseDSNFlags(t *testing.T) {
|
||||||
|
t.Run("NoDatabaseDSN", func(t *testing.T) {
|
||||||
|
conf := NewConfig(CliTestContext())
|
||||||
|
resetDatabaseOptions(conf)
|
||||||
|
|
||||||
|
assert.True(t, conf.NoDatabaseDSN())
|
||||||
|
assert.False(t, conf.HasDatabaseDSN())
|
||||||
|
})
|
||||||
|
t.Run("DeprecatedDatabaseDsn", func(t *testing.T) {
|
||||||
|
conf := NewConfig(CliTestContext())
|
||||||
|
resetDatabaseOptions(conf)
|
||||||
|
|
||||||
|
conf.options.DatabaseDriver = MySQL
|
||||||
|
conf.options.Deprecated.DatabaseDsn = "user:pass@tcp(db.internal:3306)/photoprism"
|
||||||
|
|
||||||
|
assert.False(t, conf.NoDatabaseDSN())
|
||||||
|
assert.True(t, conf.HasDatabaseDSN())
|
||||||
|
assert.Equal(t, "user:pass@tcp(db.internal:3306)/photoprism", conf.DatabaseDSN())
|
||||||
|
assert.Empty(t, conf.options.Deprecated.DatabaseDsn)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestConfig_ReportDatabaseDSN(t *testing.T) {
|
||||||
|
conf := NewConfig(CliTestContext())
|
||||||
|
resetDatabaseOptions(conf)
|
||||||
|
|
||||||
|
assert.Equal(t, SQLite3, conf.DatabaseDriver())
|
||||||
|
assert.True(t, conf.ReportDatabaseDSN())
|
||||||
|
|
||||||
|
conf.options.DatabaseDriver = MySQL
|
||||||
|
conf.options.DatabaseDSN = ""
|
||||||
|
assert.False(t, conf.ReportDatabaseDSN())
|
||||||
|
|
||||||
|
conf.options.DatabaseDSN = "user:pass@tcp(db.internal:3306)/photoprism"
|
||||||
|
assert.True(t, conf.ReportDatabaseDSN())
|
||||||
|
}
|
||||||
|
|
||||||
func TestConfig_DatabaseFile(t *testing.T) {
|
func TestConfig_DatabaseFile(t *testing.T) {
|
||||||
c := NewConfig(CliTestContext())
|
c := NewConfig(CliTestContext())
|
||||||
// Ensure SQLite defaults
|
// Ensure SQLite defaults
|
||||||
|
|||||||
@@ -13,13 +13,7 @@ import (
|
|||||||
func (c *Config) Report() (rows [][]string, cols []string) {
|
func (c *Config) Report() (rows [][]string, cols []string) {
|
||||||
cols = []string{"Name", "Value"}
|
cols = []string{"Name", "Value"}
|
||||||
|
|
||||||
var dbKey string
|
reportDatabaseDSN := c.ReportDatabaseDSN()
|
||||||
|
|
||||||
if c.DatabaseDriver() == SQLite3 {
|
|
||||||
dbKey = "database-dsn"
|
|
||||||
} else {
|
|
||||||
dbKey = "database-name"
|
|
||||||
}
|
|
||||||
|
|
||||||
rows = [][]string{
|
rows = [][]string{
|
||||||
// Authentication.
|
// Authentication.
|
||||||
@@ -219,15 +213,27 @@ func (c *Config) Report() (rows [][]string, cols []string) {
|
|||||||
{"http-video-maxage", fmt.Sprintf("%d", c.HttpVideoMaxAge())},
|
{"http-video-maxage", fmt.Sprintf("%d", c.HttpVideoMaxAge())},
|
||||||
{"http-host", c.HttpHost()},
|
{"http-host", c.HttpHost()},
|
||||||
{"http-port", fmt.Sprintf("%d", c.HttpPort())},
|
{"http-port", fmt.Sprintf("%d", c.HttpPort())},
|
||||||
|
}...)
|
||||||
|
|
||||||
// Database.
|
// Database.
|
||||||
{"database-driver", c.DatabaseDriver()},
|
if reportDatabaseDSN {
|
||||||
{dbKey, c.DatabaseName()},
|
rows = append(rows, [][]string{
|
||||||
{"database-server", c.DatabaseServer()},
|
{"database-driver", c.DatabaseDriver()},
|
||||||
{"database-host", c.DatabaseHost()},
|
{"database-dsn", c.DatabaseDSN()},
|
||||||
{"database-port", c.DatabasePortString()},
|
}...)
|
||||||
{"database-user", c.DatabaseUser()},
|
} else {
|
||||||
{"database-password", strings.Repeat("*", utf8.RuneCountInString(c.DatabasePassword()))},
|
rows = append(rows, [][]string{
|
||||||
|
{"database-driver", c.DatabaseDriver()},
|
||||||
|
{"database-name", c.DatabaseName()},
|
||||||
|
{"database-server", c.DatabaseServer()},
|
||||||
|
{"database-host", c.DatabaseHost()},
|
||||||
|
{"database-port", c.DatabasePortString()},
|
||||||
|
{"database-user", c.DatabaseUser()},
|
||||||
|
{"database-password", strings.Repeat("*", utf8.RuneCountInString(c.DatabasePassword()))},
|
||||||
|
}...)
|
||||||
|
}
|
||||||
|
|
||||||
|
rows = append(rows, [][]string{
|
||||||
{"database-timeout", fmt.Sprintf("%d", c.DatabaseTimeout())},
|
{"database-timeout", fmt.Sprintf("%d", c.DatabaseTimeout())},
|
||||||
{"database-conns", fmt.Sprintf("%d", c.DatabaseConns())},
|
{"database-conns", fmt.Sprintf("%d", c.DatabaseConns())},
|
||||||
{"database-conns-idle", fmt.Sprintf("%d", c.DatabaseConnsIdle())},
|
{"database-conns-idle", fmt.Sprintf("%d", c.DatabaseConnsIdle())},
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
@@ -11,3 +12,71 @@ func TestConfig_Report(t *testing.T) {
|
|||||||
r, _ := m.Report()
|
r, _ := m.Report()
|
||||||
assert.GreaterOrEqual(t, len(r), 1)
|
assert.GreaterOrEqual(t, len(r), 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestConfig_ReportDatabaseSection(t *testing.T) {
|
||||||
|
collect := func(rows [][]string) map[string]string {
|
||||||
|
result := make(map[string]string, len(rows))
|
||||||
|
|
||||||
|
for _, row := range rows {
|
||||||
|
if len(row) < 2 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
result[row[0]] = row[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
t.Run("SQLiteReportsDSN", func(t *testing.T) {
|
||||||
|
conf := NewConfig(CliTestContext())
|
||||||
|
resetDatabaseOptions(conf)
|
||||||
|
|
||||||
|
rows, _ := conf.Report()
|
||||||
|
values := collect(rows)
|
||||||
|
|
||||||
|
assert.Equal(t, SQLite3, values["database-driver"])
|
||||||
|
assert.Equal(t, conf.DatabaseDSN(), values["database-dsn"])
|
||||||
|
_, hasName := values["database-name"]
|
||||||
|
assert.False(t, hasName)
|
||||||
|
})
|
||||||
|
t.Run("MariaDBReportsIndividualFields", func(t *testing.T) {
|
||||||
|
conf := NewConfig(CliTestContext())
|
||||||
|
resetDatabaseOptions(conf)
|
||||||
|
|
||||||
|
conf.options.DatabaseDriver = MySQL
|
||||||
|
conf.options.DatabaseServer = "db.internal:3306"
|
||||||
|
conf.options.DatabaseName = "photoprism"
|
||||||
|
conf.options.DatabaseUser = "app"
|
||||||
|
conf.options.DatabasePassword = "secret"
|
||||||
|
|
||||||
|
rows, _ := conf.Report()
|
||||||
|
values := collect(rows)
|
||||||
|
|
||||||
|
assert.Equal(t, MySQL, values["database-driver"])
|
||||||
|
assert.Equal(t, "photoprism", values["database-name"])
|
||||||
|
assert.Equal(t, "db.internal:3306", values["database-server"])
|
||||||
|
assert.Equal(t, "db.internal", values["database-host"])
|
||||||
|
assert.Equal(t, "3306", values["database-port"])
|
||||||
|
assert.Equal(t, "app", values["database-user"])
|
||||||
|
assert.Equal(t, strings.Repeat("*", len("secret")), values["database-password"])
|
||||||
|
_, hasDSN := values["database-dsn"]
|
||||||
|
assert.False(t, hasDSN)
|
||||||
|
})
|
||||||
|
t.Run("MariaDBReportsDSNWhenConfigured", func(t *testing.T) {
|
||||||
|
conf := NewConfig(CliTestContext())
|
||||||
|
resetDatabaseOptions(conf)
|
||||||
|
|
||||||
|
conf.options.DatabaseDriver = MySQL
|
||||||
|
conf.options.DatabaseDSN = "user:pass@tcp(db.internal:3306)/photoprism"
|
||||||
|
|
||||||
|
rows, _ := conf.Report()
|
||||||
|
values := collect(rows)
|
||||||
|
|
||||||
|
assert.Equal(t, MySQL, values["database-driver"])
|
||||||
|
assert.Equal(t, "user:pass@tcp(db.internal:3306)/photoprism", values["database-dsn"])
|
||||||
|
_, hasName := values["database-name"]
|
||||||
|
assert.False(t, hasName)
|
||||||
|
_, hasPassword := values["database-password"]
|
||||||
|
assert.False(t, hasPassword)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user