Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add phpredis sentinel auth support #727

Merged
merged 4 commits into from
Sep 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 11 additions & 6 deletions .github/workflows/continuous-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
include:
- dependency-versions: "lowest"
php-version: "7.4"
php-extensions: "redis-5.3.0"
php-extensions: "redis-5.3.2"
- symfony-require: "5.4.*"
php-version: "8.2"
php-extensions: "redis"
Expand All @@ -31,13 +31,18 @@ jobs:

steps:
- name: "Checkout"
uses: "actions/checkout@v3"
uses: "actions/checkout@v4"
with:
fetch-depth: 2
- name: "Install requirements"
run: sudo apt-get update && sudo apt-get install --no-install-recommends redis-server ruby-foreman
- name: "Install redis server"
uses: shogo82148/actions-setup-redis@v1
with:
redis-version: "7.x"
auto-start: 'false'
- name: "Install cli for Procfile"
run: sudo apt-get update && sudo apt-get install --no-install-recommends ruby-foreman
- name: "Start background services"
run: sudo systemctl stop redis-server && foreman start &
run: foreman start &
- name: "Install PHP"
uses: "shivammathur/setup-php@v2"
with:
Expand All @@ -47,7 +52,7 @@ jobs:
tools: "flex"

- name: "Install dependencies with Composer"
uses: "ramsey/composer-install@v2"
uses: "ramsey/composer-install@v3"
with:
dependency-versions: "${{ matrix.dependency-versions }}"

Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/redis-configs/redis-sentinel.conf
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
sentinel monitor mymaster 127.0.0.1 6379 2
user default on +@all ~* >sentinelauthdefaultpw
user sentinelauth on +@all ~* >sentinelauthpw
appendonly no
18 changes: 9 additions & 9 deletions Procfile
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
redis: redis-server .github/workflows/redis-configs/redis.conf --port 6379
redis-acl: redis-server .github/workflows/redis-configs/redis-acl.conf --port 7099
redis-sentinel: redis-server .github/workflows/redis-configs/redis-sentinel.conf --sentinel
redis-node1: sh -c 'cd .github/workflows/redis-configs/redis-node1 && redis-server redis.conf --port 7079'
redis-node2: sh -c 'cd .github/workflows/redis-configs/redis-node2 && redis-server redis.conf --port 7080'
redis-node3: sh -c 'cd .github/workflows/redis-configs/redis-node3 && redis-server redis.conf --port 7081'
redis-node4: sh -c 'cd .github/workflows/redis-configs/redis-node4 && redis-server redis.conf --port 7082'
redis-node5: sh -c 'cd .github/workflows/redis-configs/redis-node5 && redis-server redis.conf --port 7083'
redis-node6: sh -c 'cd .github/workflows/redis-configs/redis-node6 && redis-server redis.conf --port 7084'
redis: sh -c 'cp .github/workflows/redis-configs/redis.conf /tmp/ && redis-server /tmp/redis.conf --port 6379'
redis-acl: sh -c 'cp .github/workflows/redis-configs/redis-acl.conf /tmp/ && redis-server /tmp/redis-acl.conf --port 7099'
redis-sentinel: sh -c 'cp .github/workflows/redis-configs/redis-sentinel.conf /tmp/ && redis-server /tmp/redis-sentinel.conf --sentinel'
redis-node1: sh -c 'cp -R .github/workflows/redis-configs/redis-node1 /tmp/ && cd /tmp/redis-node1 && redis-server redis.conf --port 7079'
redis-node2: sh -c 'cp -R .github/workflows/redis-configs/redis-node2 /tmp/ && cd /tmp/redis-node2 && redis-server redis.conf --port 7080'
redis-node3: sh -c 'cp -R .github/workflows/redis-configs/redis-node3 /tmp/ && cd /tmp/redis-node3 && redis-server redis.conf --port 7081'
redis-node4: sh -c 'cp -R .github/workflows/redis-configs/redis-node4 /tmp/ && cd /tmp/redis-node4 && redis-server redis.conf --port 7082'
redis-node5: sh -c 'cp -R .github/workflows/redis-configs/redis-node5 /tmp/ && cd /tmp/redis-node5 && redis-server redis.conf --port 7083'
redis-node6: sh -c 'cp -R .github/workflows/redis-configs/redis-node6 /tmp/ && cd /tmp/redis-node6 && redis-server redis.conf --port 7084'
5 changes: 3 additions & 2 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ A setup using `predis`, `phpredis` or `relay` sentinel replication could look li
snc_redis:
clients:
default:
type: "predis" # or "phpredis", or "relay"
type: "phpredis" # or "predis", or "relay"
alias: default
dsn:
- redis://localhost:26379
Expand All @@ -121,6 +121,8 @@ snc_redis:
parameters:
database: 1
password: pass
sentinel_username: myuser # default to null
sentinel_password: mypass # default to null
```

The `service` is the name of the set of Redis instances.
Expand All @@ -131,7 +133,6 @@ If you use a password, it must be in the password parameter and must
be omitted from the DSNs. Also make sure to use the sentinel port number
(26379 by default) in the DSNs, and not the default Redis port.
You can find more information about this on [Configuring Sentinel](https://redis.io/topics/sentinel#configuring-sentinel).

A setup using `RedisCluster` from `phpredis` could look like this:

``` yaml
Expand Down
12 changes: 6 additions & 6 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
config.allowUnfree = true;
config.allowInsecurePredicate = pkg: pkgs.lib.getName pkg == "openssl";
};
php = pkgs.php82.buildEnv {
php = pkgs.php83.buildEnv {
extensions = (
{
all,
Expand Down
2 changes: 2 additions & 0 deletions src/DependencyInjection/Configuration/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@ private function addClientsSection(ArrayNodeDefinition $rootNode): void
->scalarNode('database')->defaultNull()->end()
->scalarNode('username')->defaultNull()->end()
->scalarNode('password')->defaultNull()->end()
->scalarNode('sentinel_username')->defaultNull()->end()
->scalarNode('sentinel_password')->defaultNull()->end()
->booleanNode('logging')->defaultValue($this->debug)->end()
->variableNode('ssl_context')->defaultNull()->end()
->end()
Expand Down
8 changes: 5 additions & 3 deletions src/Factory/PhpredisClientFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,9 @@ public function create(string $class, array $dsns, array $options, string $alias
}

/**
* @param class-string $class
* @param list<RedisDsn> $dsns
* @param array{service: ?string, connection_persistent: ?bool, connection_timeout: ?string, read_write_timeout: ?string} $options
* @param class-string $class
* @param list<RedisDsn> $dsns
* @param array{service: ?string, connection_persistent: ?bool, connection_timeout: ?string, read_write_timeout: ?string, parameters: array{sentinel_username: string, sentinel_password: string}} $options
*
* @return Redis|Relay
*/
Expand All @@ -125,6 +125,7 @@ private function createClientFromSentinel(string $class, array $dsns, string $al
$connectionTimeout = $options['connection_timeout'] ?? 0;
$connectionPersistent = $options['connection_persistent'] ? $masterName : null;
$readTimeout = $options['read_write_timeout'] ?? 0;
$parameters = $options['parameters'];

foreach ($dsns as $dsn) {
$args = [
Expand All @@ -134,6 +135,7 @@ private function createClientFromSentinel(string $class, array $dsns, string $al
'persistent' => $connectionPersistent,
'retryInterval' => 5,
'readTimeout' => $readTimeout,
'auth' => [$parameters['sentinel_username'], $parameters['sentinel_password']],
];
try {
if ($isRelay || version_compare(phpversion('redis'), '6.0', '<')) {
Expand Down
6 changes: 6 additions & 0 deletions tests/DependencyInjection/SncRedisExtensionEnvTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ public function testPredisDefaultParameterConfig(): void
'database' => null,
'username' => null,
'password' => null,
'sentinel_username' => null,
'sentinel_password' => null,
'logging' => false,
],
'commands' => ['foo' => 'Foo\Bar\Baz'],
Expand Down Expand Up @@ -132,6 +134,8 @@ public function testPhpredisFullConfig(): void
'database' => null,
'username' => null,
'password' => null,
'sentinel_username' => null,
'sentinel_password' => null,
'logging' => false,
],
'connection_async' => false,
Expand Down Expand Up @@ -170,6 +174,8 @@ public function testPhpredisWithAclConfig(): void
'database' => null,
'logging' => false,
'ssl_context' => null,
'sentinel_username' => null,
'sentinel_password' => null,
],
'prefix' => null,
'read_write_timeout' => null,
Expand Down
18 changes: 14 additions & 4 deletions tests/Factory/PhpredisClientFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,17 @@ public function testCreateMinimalClusterConfig(): void

/**
* @requires extension relay
* @testWith ["RedisSentinel", "Redis"]
* ["Relay\\Sentinel", "Relay\\Relay"]
* @testWith ["RedisSentinel", "Redis", null, "sentinelauthdefaultpw"]
* ["RedisSentinel", "Redis", "sentinelauth", "sentinelauthpw"]
* ["Relay\\Sentinel", "Relay\\Relay", null, "sentinelauthdefaultpw"]
* ["Relay\\Sentinel", "Relay\\Relay", "sentinelauth", "sentinelauthpw"]
*/
public function testCreateSentinelConfig(string $sentinelClass, string $outputClass): void
{
public function testCreateSentinelConfig(
string $sentinelClass,
string $outputClass,
?string $sentinelUser,
?string $sentinelPassword
): void {
$this->logger->method('debug')->with(...$this->withConsecutive(
[$this->stringContains('Executing command "CONNECT 127.0.0.1 6379 5 <null>')],
['Executing command "AUTH sncredis"'],
Expand All @@ -130,6 +136,10 @@ public function testCreateSentinelConfig(string $sentinelClass, string $outputCl
'connection_timeout' => 5,
'connection_persistent' => false,
'service' => 'mymaster',
'parameters' => [
'sentinel_username' => $sentinelUser,
'sentinel_password' => $sentinelPassword,
],
],
'phpredissentinel',
true,
Expand Down
3 changes: 3 additions & 0 deletions tests/Functional/App/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ snc_redis:
options:
replication: true
service: mymaster
parameters:
sentinel_username: sentinelauth
sentinel_password: sentinelauthpw
with_acl:
type: predis
alias: with_acl
Expand Down
Loading