Skip to content
Open
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
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ lint-config: golangci-lint ## Verify golangci-lint linter configuration
##@ Build

.PHONY: build
build: manifests generate fmt vet ## Build manager binary.
build: manifests generate fmt vet lint ## Build manager binary.
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The golangci-lint was only ran during github e2e tests, and it was frustrating for this to fail remotely. Simple change to check this locally first.

go build -o bin/manager cmd/main.go

.PHONY: run
Expand Down
102 changes: 102 additions & 0 deletions api/v1alpha1/valkeyacls_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*
Copyright 2025 Valkey Contributors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1alpha1

// An UserAclSpec contains user, authorization, and permissions-related configurations
type UserAclSpec struct {

// Username
// +kubebuilder:required:message=A username is required
Name string `json:"name"`

// If the user is enabled or not
// +kubebuilder:default=true
Enabled bool `json:"enabled,omitempty"`

// Reference information to a Secret containing user passwords
// +optional
PasswordSecret PasswordSecretSpec `json:"passwordSecret,omitempty"`

// Do not apply a password to this user
// +kubebuilder:default=false
NoPassword bool `json:"nopass,omitempty"`

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think passwordEnabled or enabledPassword would be good naming here instead of NoPassword. Also i am not sure this is general use case of having nopass attached to user. if they really want to acheieve this they can always use rawacl.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might not be general or recommended, but if Valkey exposes it as an option it might be useful to abstract it away.

https://valkey.io/topics/acl/#configure-acls-with-the-acl-command

This boolean is used in the PR in a few places. If we were to remove NoPassword here, would we change those conditions to be 'nopass' in RawAcl (pseudocode) ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the idea was since the ACL keyword is nopass then this follows-ish 1:1. Since the default is false if not specified, is there a strong reason to remove it? As the code is now, if removed, then passwords are always searched for even in a nopass=true case. The code would then need to check rawAcl for presence of nopass to achieve same logic.

// Valkey command categories, commands, and subcommands restrictions for this user
// +optional
Commands CommandsAclSpec `json:"commands,omitempty"`

// Key restrictions
// +optional
Keys KeysAclSpec `json:"keys,omitempty"`

// Channel restrictions
// +optional
Channels ChannelsAclSpec `json:"channels,omitempty"`

// Raw ACL for (additional) permissions. Appended to anything generated.
// +optional
RawAcl string `json:"permissions,omitempty"`
}

type PasswordSecretSpec struct {

// Name of the referencing Secret; Defaults to clustername-users
// +optional
Name string `json:"name,omitempty"`

// An array of keys inside the referencing Secret to find passwords; defaults to username
// Valkey supports multiple passwords per user for rotation
// +optional
Keys []string `json:"keys,omitempty"`
}

type CommandsAclSpec struct {

// Command categories (@all, @read, @write, @admin, etc.)
// Individual commands (get, set, ping, etc.)
// Subcommands (client|setname, config|get, etc.)

// Allowed commands for this user
// +kubebuilder:validation:Items:Pattern=^[@a-z|]+$}
Allow []string `json:"allow,omitempty"`

// Denied commands for this user
// +kubebuilder:validation:Items:Pattern=^[@a-z|]+$}
Deny []string `json:"deny,omitempty"`
}

type KeysAclSpec struct {

// Keys on which this user can read, and write; maps to Valkey: ~pattern
// +optional
ReadWrite []string `json:"readWrite,omitempty"`

// Keys restricted to read-only; maps to Valkey: %R~pattern
// +optional
ReadOnly []string `json:"readOnly,omitempty"`

// Keys restricted to write-only; maps to Valkey: %W~pattern
// +optional
WriteOnly []string `json:"writeOnly,omitempty"`
}

type ChannelsAclSpec struct {

// Pub/Sub channel patterns - maps to Valkey: &pattern
// +optional
Patterns []string `json:"patterns,omitempty"`
}
6 changes: 6 additions & 0 deletions api/v1alpha1/valkeycluster_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ type ValkeyClusterSpec struct {
// +kubebuilder:default:={enabled:true}
// +optional
Exporter ExporterSpec `json:"exporter,omitempty"`

// Users, and ACL-related configuration; see valkeyacls_types.go
// +listType=map
// +listMapKey=name
Users []UserAclSpec `json:"users,omitempty"`
}

type ExporterSpec struct {
Expand Down Expand Up @@ -154,6 +159,7 @@ const (
ReasonSlotsUnassigned = "SlotsUnassigned"
ReasonPrimaryLost = "PrimaryLost"
ReasonNoSlots = "NoSlotsAvailable"
ReasonUsersAclError = "UsersACLError"
)

// +kubebuilder:object:root=true
Expand Down
121 changes: 121 additions & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

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

91 changes: 91 additions & 0 deletions config/crd/bases/valkey.io_valkeyclusters.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1164,6 +1164,97 @@ spec:
type: string
type: object
type: array
users:
description: Users, and ACL-related configuration; see valkeyacls_types.go
items:
description: An UserAclSpec contains user, authorization, and permissions-related
configurations
properties:
channels:
description: Channel restrictions
properties:
patterns:
description: 'Pub/Sub channel patterns - maps to Valkey:
&pattern'
items:
type: string
type: array
type: object
commands:
description: Valkey command categories, commands, and subcommands
restrictions for this user
properties:
allow:
description: Allowed commands for this user
items:
type: string
type: array
deny:
description: Denied commands for this user
items:
type: string
type: array
type: object
enabled:
default: true
description: If the user is enabled or not
type: boolean
keys:
description: Key restrictions
properties:
readOnly:
description: 'Keys restricted to read-only; maps to Valkey:
%R~pattern'
items:
type: string
type: array
readWrite:
description: 'Keys on which this user can read, and write;
maps to Valkey: ~pattern'
items:
type: string
type: array
writeOnly:
description: 'Keys restricted to write-only; maps to Valkey:
%W~pattern'
items:
type: string
type: array
type: object
name:
description: Username
type: string
nopass:
default: false
description: Do not apply a password to this user
type: boolean
passwordSecret:
description: Reference information to a Secret containing user
passwords
properties:
keys:
description: |-
An array of keys inside the referencing Secret to find passwords; defaults to username
Valkey supports multiple passwords per user for rotation
items:
type: string
type: array
name:
description: Name of the referencing Secret; Defaults to
clustername-users
type: string
type: object
permissions:
description: Raw ACL for (additional) permissions. Appended
to anything generated.
type: string
required:
- name
type: object
type: array
x-kubernetes-list-map-keys:
- name
x-kubernetes-list-type: map
type: object
status:
default:
Expand Down
1 change: 1 addition & 0 deletions config/rbac/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ rules:
- ""
resources:
- configmaps
- secrets
- services
verbs:
- create
Expand Down
Loading