feat: added support for redis username configuration
Redis introduced an Access Control List (ACL) mechanism since version 6.0. This commit implements the necessary changes to support configuring the username for Redis. Users can now define a specific username to authenticate with Redis and enhance security through the ACL feature. Signed-off-by: chlins <chenyuzh@vmware.com>
This commit is contained in:
parent
807a836852
commit
32a476b840
3 changed files with 94 additions and 1 deletions
|
@ -174,6 +174,9 @@ type Configuration struct {
|
||||||
// Addr specifies the the redis instance available to the application.
|
// Addr specifies the the redis instance available to the application.
|
||||||
Addr string `yaml:"addr,omitempty"`
|
Addr string `yaml:"addr,omitempty"`
|
||||||
|
|
||||||
|
// Usernames can be used as a finer-grained permission control since the introduction of the redis 6.0.
|
||||||
|
Username string `yaml:"username,omitempty"`
|
||||||
|
|
||||||
// Password string to use when making a connection.
|
// Password string to use when making a connection.
|
||||||
Password string `yaml:"password,omitempty"`
|
Password string `yaml:"password,omitempty"`
|
||||||
|
|
||||||
|
|
|
@ -131,6 +131,40 @@ var configStruct = Configuration{
|
||||||
Disabled: false,
|
Disabled: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Redis: struct {
|
||||||
|
Addr string `yaml:"addr,omitempty"`
|
||||||
|
Username string `yaml:"username,omitempty"`
|
||||||
|
Password string `yaml:"password,omitempty"`
|
||||||
|
DB int `yaml:"db,omitempty"`
|
||||||
|
TLS struct {
|
||||||
|
Enabled bool `yaml:"enabled,omitempty"`
|
||||||
|
} `yaml:"tls,omitempty"`
|
||||||
|
DialTimeout time.Duration `yaml:"dialtimeout,omitempty"`
|
||||||
|
ReadTimeout time.Duration `yaml:"readtimeout,omitempty"`
|
||||||
|
WriteTimeout time.Duration `yaml:"writetimeout,omitempty"`
|
||||||
|
Pool struct {
|
||||||
|
MaxIdle int `yaml:"maxidle,omitempty"`
|
||||||
|
MaxActive int `yaml:"maxactive,omitempty"`
|
||||||
|
IdleTimeout time.Duration `yaml:"idletimeout,omitempty"`
|
||||||
|
} `yaml:"pool,omitempty"`
|
||||||
|
}{
|
||||||
|
Addr: "localhost:6379",
|
||||||
|
Username: "alice",
|
||||||
|
Password: "123456",
|
||||||
|
DB: 1,
|
||||||
|
Pool: struct {
|
||||||
|
MaxIdle int `yaml:"maxidle,omitempty"`
|
||||||
|
MaxActive int `yaml:"maxactive,omitempty"`
|
||||||
|
IdleTimeout time.Duration `yaml:"idletimeout,omitempty"`
|
||||||
|
}{
|
||||||
|
MaxIdle: 16,
|
||||||
|
MaxActive: 64,
|
||||||
|
IdleTimeout: time.Second * 300,
|
||||||
|
},
|
||||||
|
DialTimeout: time.Millisecond * 10,
|
||||||
|
ReadTimeout: time.Millisecond * 10,
|
||||||
|
WriteTimeout: time.Millisecond * 10,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// configYamlV0_1 is a Version 0.1 yaml document representing configStruct
|
// configYamlV0_1 is a Version 0.1 yaml document representing configStruct
|
||||||
|
@ -175,6 +209,18 @@ http:
|
||||||
- /path/to/ca.pem
|
- /path/to/ca.pem
|
||||||
headers:
|
headers:
|
||||||
X-Content-Type-Options: [nosniff]
|
X-Content-Type-Options: [nosniff]
|
||||||
|
redis:
|
||||||
|
addr: localhost:6379
|
||||||
|
username: alice
|
||||||
|
password: 123456
|
||||||
|
db: 1
|
||||||
|
pool:
|
||||||
|
maxidle: 16
|
||||||
|
maxactive: 64
|
||||||
|
idletimeout: 300s
|
||||||
|
dialtimeout: 10ms
|
||||||
|
readtimeout: 10ms
|
||||||
|
writetimeout: 10ms
|
||||||
`
|
`
|
||||||
|
|
||||||
// inmemoryConfigYamlV0_1 is a Version 0.1 yaml document specifying an inmemory
|
// inmemoryConfigYamlV0_1 is a Version 0.1 yaml document specifying an inmemory
|
||||||
|
@ -242,6 +288,23 @@ func (suite *ConfigSuite) TestParseInmemory(c *check.C) {
|
||||||
suite.expectedConfig.Storage = Storage{"inmemory": Parameters{}}
|
suite.expectedConfig.Storage = Storage{"inmemory": Parameters{}}
|
||||||
suite.expectedConfig.Reporting = Reporting{}
|
suite.expectedConfig.Reporting = Reporting{}
|
||||||
suite.expectedConfig.Log.Fields = nil
|
suite.expectedConfig.Log.Fields = nil
|
||||||
|
suite.expectedConfig.Redis = struct {
|
||||||
|
Addr string `yaml:"addr,omitempty"`
|
||||||
|
Username string `yaml:"username,omitempty"`
|
||||||
|
Password string `yaml:"password,omitempty"`
|
||||||
|
DB int `yaml:"db,omitempty"`
|
||||||
|
TLS struct {
|
||||||
|
Enabled bool `yaml:"enabled,omitempty"`
|
||||||
|
} `yaml:"tls,omitempty"`
|
||||||
|
DialTimeout time.Duration `yaml:"dialtimeout,omitempty"`
|
||||||
|
ReadTimeout time.Duration `yaml:"readtimeout,omitempty"`
|
||||||
|
WriteTimeout time.Duration `yaml:"writetimeout,omitempty"`
|
||||||
|
Pool struct {
|
||||||
|
MaxIdle int `yaml:"maxidle,omitempty"`
|
||||||
|
MaxActive int `yaml:"maxactive,omitempty"`
|
||||||
|
IdleTimeout time.Duration `yaml:"idletimeout,omitempty"`
|
||||||
|
} `yaml:"pool,omitempty"`
|
||||||
|
}{}
|
||||||
|
|
||||||
config, err := Parse(bytes.NewReader([]byte(inmemoryConfigYamlV0_1)))
|
config, err := Parse(bytes.NewReader([]byte(inmemoryConfigYamlV0_1)))
|
||||||
c.Assert(err, check.IsNil)
|
c.Assert(err, check.IsNil)
|
||||||
|
@ -262,6 +325,23 @@ func (suite *ConfigSuite) TestParseIncomplete(c *check.C) {
|
||||||
suite.expectedConfig.Reporting = Reporting{}
|
suite.expectedConfig.Reporting = Reporting{}
|
||||||
suite.expectedConfig.Notifications = Notifications{}
|
suite.expectedConfig.Notifications = Notifications{}
|
||||||
suite.expectedConfig.HTTP.Headers = nil
|
suite.expectedConfig.HTTP.Headers = nil
|
||||||
|
suite.expectedConfig.Redis = struct {
|
||||||
|
Addr string `yaml:"addr,omitempty"`
|
||||||
|
Username string `yaml:"username,omitempty"`
|
||||||
|
Password string `yaml:"password,omitempty"`
|
||||||
|
DB int `yaml:"db,omitempty"`
|
||||||
|
TLS struct {
|
||||||
|
Enabled bool `yaml:"enabled,omitempty"`
|
||||||
|
} `yaml:"tls,omitempty"`
|
||||||
|
DialTimeout time.Duration `yaml:"dialtimeout,omitempty"`
|
||||||
|
ReadTimeout time.Duration `yaml:"readtimeout,omitempty"`
|
||||||
|
WriteTimeout time.Duration `yaml:"writetimeout,omitempty"`
|
||||||
|
Pool struct {
|
||||||
|
MaxIdle int `yaml:"maxidle,omitempty"`
|
||||||
|
MaxActive int `yaml:"maxactive,omitempty"`
|
||||||
|
IdleTimeout time.Duration `yaml:"idletimeout,omitempty"`
|
||||||
|
} `yaml:"pool,omitempty"`
|
||||||
|
}{}
|
||||||
|
|
||||||
// Note: this also tests that REGISTRY_STORAGE and
|
// Note: this also tests that REGISTRY_STORAGE and
|
||||||
// REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY can be used together
|
// REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY can be used together
|
||||||
|
@ -555,5 +635,7 @@ func copyConfig(config Configuration) *Configuration {
|
||||||
configCopy.HTTP.Headers[k] = v
|
configCopy.HTTP.Headers[k] = v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
configCopy.Redis = config.Redis
|
||||||
|
|
||||||
return configCopy
|
return configCopy
|
||||||
}
|
}
|
||||||
|
|
|
@ -546,8 +546,16 @@ func (app *App) configureRedis(configuration *configuration.Configuration) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// authorize the connection
|
// authorize the connection
|
||||||
|
authArgs := make([]interface{}, 0, 2)
|
||||||
|
if configuration.Redis.Username != "" {
|
||||||
|
authArgs = append(authArgs, configuration.Redis.Username)
|
||||||
|
}
|
||||||
if configuration.Redis.Password != "" {
|
if configuration.Redis.Password != "" {
|
||||||
if _, err = conn.Do("AUTH", configuration.Redis.Password); err != nil {
|
authArgs = append(authArgs, configuration.Redis.Password)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(authArgs) > 0 {
|
||||||
|
if _, err = conn.Do("AUTH", authArgs...); err != nil {
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
done(err)
|
done(err)
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
Loading…
Reference in a new issue