Skip to content
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
10 changes: 9 additions & 1 deletion build/mongot-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
#!/bin/bash

set -o errexit
set -o xtrace

Comment thread
egegunes marked this conversation as resolved.
MONGO_SSL_DIR=${MONGO_SSL_DIR:-/etc/mongodb-ssl}

if [ -f "${MONGO_SSL_DIR}/tls.key" ] && [ -f "${MONGO_SSL_DIR}/tls.crt" ]; then
if [[ -f "${MONGO_SSL_DIR}/tls.key" ]] && [[ -f "${MONGO_SSL_DIR}/tls.crt" ]]; then
cat "${MONGO_SSL_DIR}/tls.key" "${MONGO_SSL_DIR}/tls.crt" >/tmp/tls.pem
fi

# mongot requires passwordFile only be readable by the owner
# but K8s doesn't allow us to set ownership for the mounted secret
if [[ -f /etc/users-secret/MONGODB_SEARCH_PASSWORD ]]; then
cp /etc/users-secret/MONGODB_SEARCH_PASSWORD /tmp/MONGODB_SEARCH_PASSWORD
chmod 400 /tmp/MONGODB_SEARCH_PASSWORD
fi
Comment thread
Copilot marked this conversation as resolved.

exec "$@"
4 changes: 3 additions & 1 deletion deploy/backup/restore.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ spec:
# withUsersAndRoles: true
# namespaces:
# - "db.collection"
# nsFrom: "db1.col1"
# nsTo: "db1.col2"
# replsetRemapping:
# rs0: shard0
# rs1: shard1
Expand Down Expand Up @@ -37,4 +39,4 @@ spec:
# azure:
# credentialsSecret: SECRET-NAME
# prefix: PREFIX-NAME
# container: CONTAINER-NAME
# container: CONTAINER-NAME
2 changes: 1 addition & 1 deletion e2e-tests/functions
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ perconalab/percona-server-mongodb-operator:main-mongod6.0
perconalab/percona-server-mongodb-operator:main-mongod7.0
perconalab/percona-server-mongodb-operator:main-mongod8.0'}
IMAGE_BACKUP=${IMAGE_BACKUP:-"perconalab/percona-server-mongodb-operator:main-backup"}
IMAGE_SEARCH=${IMAGE_SEARCH:-"mongodb/mongodb-community-search:latest"}
IMAGE_SEARCH=${IMAGE_SEARCH:-"perconalab/percona-server-mongodb-operator:main-mongot"}
SKIP_BACKUPS_TO_AWS_GCP_AZURE=${SKIP_BACKUPS_TO_AWS_GCP_AZURE:-1}
PMM_SERVER_VER=${PMM_SERVER_VER:-"9.9.9"}
IMAGE_PMM_CLIENT=${IMAGE_PMM_CLIENT:-"percona/pmm-client:2.44.1-1"}
Expand Down
29 changes: 29 additions & 0 deletions pkg/apis/psmdb/v1/psmdb_defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -698,6 +698,8 @@ func (cr *PerconaServerMongoDB) CheckNSetDefaults(ctx context.Context, platform
return errors.New("MCS is not available on this cluster")
}

cr.setSearchDefaults(platform)

return nil
}

Expand Down Expand Up @@ -1284,3 +1286,30 @@ func (cr *PerconaServerMongoDB) setStorageAutoscalingDefaults() {
spec.GrowthStep = resource.MustParse("2Gi")
}
}

func (cr *PerconaServerMongoDB) setSearchDefaults(platform version.Platform) {
if cr.Spec.Search == nil {
return
}

var userId *int64
if platform == version.PlatformKubernetes {
userId = new(int64(1001))
}

if cr.Spec.Search.ContainerSecurityContext == nil {
cr.Spec.Search.ContainerSecurityContext = &corev1.SecurityContext{
RunAsNonRoot: new(true),
RunAsGroup: userId,
RunAsUser: userId,
}
}
Comment thread
egegunes marked this conversation as resolved.

if cr.Spec.Search.PodSecurityContext == nil {
cr.Spec.Search.PodSecurityContext = &corev1.PodSecurityContext{
RunAsUser: userId,
RunAsGroup: userId,
FSGroup: userId,
}
}
}
4 changes: 4 additions & 0 deletions pkg/controller/perconaservermongodb/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ import (
// search disabled the function deletes any previously created objects
// and returns.
func (r *ReconcilePerconaServerMongoDB) reconcileSearch(ctx context.Context, cr *api.PerconaServerMongoDB, rs *api.ReplsetSpec) error {
if rs.ClusterRole == api.ClusterRoleConfigSvr {
return nil
}
Comment thread
egegunes marked this conversation as resolved.

if !cr.IsSearchEnabled() {
return r.deleteSearch(ctx, cr, rs)
}
Expand Down
10 changes: 10 additions & 0 deletions pkg/controller/perconaservermongodb/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,16 @@ func (r *ReconcilePerconaServerMongoDB) updateStatus(ctx context.Context, cr *ap
if cr.Spec.Sharding.Enabled && cr.Status.Mongos.Status != api.AppStateReady {
state = cr.Status.Mongos.Status
}

if cr.IsSearchEnabled() {
for rs, status := range cr.Status.Search {
if status.Status != api.AppStateReady {
state = status.Status
log.V(1).Info("Mongot is not ready", "replset", rs, "state", state)
break
}
}
}
}

if state != api.AppStateReady {
Expand Down
44 changes: 31 additions & 13 deletions pkg/psmdb/vectorsearch/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,10 @@ func defaultMongotConfig(cr *api.PerconaServerMongoDB, rs *api.ReplsetSpec) mong
cfg := mongot.Config{
SyncSource: mongot.ConfigSyncSource{
ReplicaSet: mongot.ConfigReplicaSet{
Username: string(api.RoleSearch),
PasswordFile: usersSecretMountPath + "/" + api.EnvMongoDBSearchPassword,
ScramAuth: &mongot.ConfigScramAuth{
Username: string(api.RoleSearch),
PasswordFile: "/tmp/" + api.EnvMongoDBSearchPassword,
},
},
},
Logging: mongot.ConfigLogging{
Expand All @@ -111,14 +113,6 @@ func defaultMongotConfig(cr *api.PerconaServerMongoDB, rs *api.ReplsetSpec) mong
},
}

if cr.TLSEnabled() {
cfg.Server.Grpc.TLS = &mongot.ConfigGrpcTLS{
Mode: mongot.ConfigTLSModeMTLS,
CertificateKeyFile: new(mongotTLSCertificatePath),
CertificateAuthorityFile: new(mongotTLSCAPath),
}
}

hosts := make([]string, rs.Size)
for i := range rs.Size {
hosts[i] = mongodHostAndPort(cr, rs, i)
Expand All @@ -127,9 +121,33 @@ func defaultMongotConfig(cr *api.PerconaServerMongoDB, rs *api.ReplsetSpec) mong

if sharding := cr.Spec.Sharding; sharding.Enabled && sharding.Mongos != nil {
cfg.SyncSource.Router = &mongot.ConfigRouter{
HostAndPort: mongosHostAndPort(cr),
Username: string(api.RoleSearch),
PasswordFile: usersSecretMountPath + "/" + api.EnvMongoDBSearchPassword,
HostAndPort: mongosHostAndPort(cr),
ScramAuth: &mongot.ConfigScramAuth{
Username: string(api.RoleSearch),
PasswordFile: "/tmp/" + api.EnvMongoDBSearchPassword,
},
}
}

if cr.TLSEnabled() {
cfg.Server.Grpc.TLS = &mongot.ConfigGrpcTLS{
Mode: mongot.ConfigTLSModeMTLS,
CertificateKeyFile: new(mongotTLSCertificatePath),
CertificateAuthorityFile: new(mongotTLSCAPath),
}

cfg.SyncSource.ReplicaSet.ScramAuth.TLS = &mongot.ScramAuthTLS{
Enabled: true,
TLSCertificateKeyFile: new(mongotTLSCertificatePath),
CertificateAuthorityFile: new(mongotTLSCAPath),
}

if cfg.SyncSource.Router != nil {
cfg.SyncSource.Router.ScramAuth.TLS = &mongot.ScramAuthTLS{
Enabled: true,
TLSCertificateKeyFile: new(mongotTLSCertificatePath),
CertificateAuthorityFile: new(mongotTLSCAPath),
}
}
}

Expand Down
37 changes: 32 additions & 5 deletions pkg/psmdb/vectorsearch/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -348,8 +348,15 @@ func newDefaultExpectedConfig() mongot.Config {
"psmdb-rs0-1.psmdb-rs0.default.svc.cluster.local:27017",
"psmdb-rs0-2.psmdb-rs0.default.svc.cluster.local:27017",
},
Username: "searchCoordinator",
PasswordFile: "/etc/users-secret/MONGODB_SEARCH_PASSWORD",
ScramAuth: &mongot.ConfigScramAuth{
Username: "searchCoordinator",
PasswordFile: "/tmp/MONGODB_SEARCH_PASSWORD",
TLS: &mongot.ScramAuthTLS{
Enabled: true,
TLSCertificateKeyFile: new(mongotTLSCertificatePath),
CertificateAuthorityFile: new(mongotTLSCAPath),
},
},
},
},
Storage: mongot.ConfigStorage{
Expand Down Expand Up @@ -427,10 +434,30 @@ net:
expected: func() mongot.Config {
cfg := newDefaultExpectedConfig()
cfg.SyncSource.Router = &mongot.ConfigRouter{
HostAndPort: []string{"psmdb-mongos.default.svc.cluster.local:27017"},
Username: "searchCoordinator",
PasswordFile: "/etc/users-secret/MONGODB_SEARCH_PASSWORD",
HostAndPort: []string{"psmdb-mongos.default.svc.cluster.local:27017"},
ScramAuth: &mongot.ConfigScramAuth{
Username: "searchCoordinator",
PasswordFile: "/tmp/MONGODB_SEARCH_PASSWORD",
TLS: &mongot.ScramAuthTLS{
Enabled: true,
TLSCertificateKeyFile: new(mongotTLSCertificatePath),
CertificateAuthorityFile: new(mongotTLSCAPath),
},
},
}
return cfg
}(),
},
"cluster TLS disabled leaves scramAuth and grpc TLS off": {
mutateCR: func(cr *api.PerconaServerMongoDB) {
cr.Spec.TLS = &api.TLSSpec{Mode: api.TLSModeDisabled}
},
expected: func() mongot.Config {
cfg := newDefaultExpectedConfig()
cfg.Server.Grpc.TLS = &mongot.ConfigGrpcTLS{
Mode: mongot.ConfigTLSModeDisabled,
}
cfg.SyncSource.ReplicaSet.ScramAuth.TLS = nil
return cfg
}(),
},
Expand Down
54 changes: 36 additions & 18 deletions pkg/psmdb/vectorsearch/mongot/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,35 +18,53 @@ type EmbeddingConfig struct {
}

type ConfigSyncSource struct {
ReplicaSet ConfigReplicaSet `json:"replicaSet" yaml:"replicaSet"`
Router *ConfigRouter `json:"router,omitempty" yaml:"router,omitempty"`
CertificateAuthorityFile *string `json:"caFile,omitempty" yaml:"caFile,omitempty"`
ReplicaSet ConfigReplicaSet `json:"replicaSet" yaml:"replicaSet"`
Router *ConfigRouter `json:"router,omitempty" yaml:"router,omitempty"`
ReplicationReader *ConfigReplicationReader `json:"replicationReader,omitempty" yaml:"replicationReader,omitempty"`
}

type ConfigRouter struct {
HostAndPort []string `json:"hostAndPort" yaml:"hostAndPort"`
Username string `json:"username,omitempty" yaml:"username,omitempty"`
PasswordFile string `json:"passwordFile,omitempty" yaml:"passwordFile,omitempty"`
TLS *bool `json:"tls,omitempty" yaml:"tls,omitempty"`
AuthSource *string `json:"authSource,omitempty" yaml:"authSource,omitempty"`
X509 *ConfigX509 `json:"x509,omitempty" yaml:"x509,omitempty"`
type ConfigReplicationReader struct {
ReadPreference *string `json:"readPreference,omitempty" yaml:"readPreference,omitempty"`
TagSets [][]ConfigTag `json:"tagSets,omitempty" yaml:"tagSets,omitempty"`
}

type ConfigReplicaSet struct {
HostAndPort []string `json:"hostAndPort" yaml:"hostAndPort"`
Username string `json:"username,omitempty" yaml:"username,omitempty"`
PasswordFile string `json:"passwordFile,omitempty" yaml:"passwordFile,omitempty"`
TLS *bool `json:"tls,omitempty" yaml:"tls,omitempty"`
ReadPreference *string `json:"readPreference,omitempty" yaml:"readPreference,omitempty"`
AuthSource *string `json:"authSource,omitempty" yaml:"authSource,omitempty"`
X509 *ConfigX509 `json:"x509,omitempty" yaml:"x509,omitempty"`
type ConfigTag struct {
Name string `json:"name" yaml:"name,omitempty"`
Value string `json:"value" yaml:"value,omitempty"`
}
Comment thread
egegunes marked this conversation as resolved.

type ScramAuthTLS struct {
Enabled bool `json:"enabled" yaml:"enabled,omitempty"`
TLSCertificateKeyFile *string `json:"tlsCertificateKeyFile,omitempty" yaml:"tlsCertificateKeyFile,omitempty"`
TLSCertificateKeyFilePasswordFile *string `json:"tlsCertificateKeyFilePasswordFile,omitempty" yaml:"tlsCertificateKeyFilePasswordFile,omitempty"`
CertificateAuthorityFile *string `json:"caFile,omitempty" yaml:"caFile,omitempty"`
}

type ConfigScramAuth struct {
Username string `json:"username" yaml:"username,omitempty"`
PasswordFile string `json:"passwordFile" yaml:"passwordFile,omitempty"`
TLS *ScramAuthTLS `json:"tls,omitempty" yaml:"tls,omitempty"`
AuthSource *string `json:"authSource,omitempty" yaml:"authSource,omitempty"`
}

type ConfigX509 struct {
CertificateAuthorityFile *string `json:"caFile,omitempty" yaml:"caFile,omitempty"`
TLSCertificateKeyFile *string `json:"tlsCertificateKeyFile,omitempty" yaml:"tlsCertificateKeyFile,omitempty"`
TLSCertificateKeyFilePasswordFile *string `json:"tlsCertificateKeyFilePasswordFile,omitempty" yaml:"tlsCertificateKeyFilePasswordFile,omitempty"`
}

type ConfigRouter struct {
HostAndPort []string `json:"hostAndPort" yaml:"hostAndPort"`
X509 *ConfigX509 `json:"x509,omitempty" yaml:"x509,omitempty"`
ScramAuth *ConfigScramAuth `json:"scramAuth,omitempty" yaml:"scramAuth,omitempty"`
}

type ConfigReplicaSet struct {
HostAndPort []string `json:"hostAndPort" yaml:"hostAndPort"`
X509 *ConfigX509 `json:"x509,omitempty" yaml:"x509,omitempty"`
ScramAuth *ConfigScramAuth `json:"scramAuth,omitempty" yaml:"scramAuth,omitempty"`
}

type ConfigStorage struct {
DataPath string `json:"dataPath" yaml:"dataPath"`
}
Expand Down
20 changes: 1 addition & 19 deletions pkg/psmdb/vectorsearch/statefulset.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,11 +190,6 @@ func mongotContainer(cr *api.PerconaServerMongoDB, search *api.SearchSpec) corev
Name: dataVolumeName,
MountPath: dataMountPath,
},
{
Name: cr.Spec.Secrets.GetInternalKey(cr),
MountPath: config.MongodSecretsDir,
ReadOnly: true,
},
{
Name: configVolumeName,
MountPath: configMountPath,
Expand All @@ -216,8 +211,7 @@ func mongotContainer(cr *api.PerconaServerMongoDB, search *api.SearchSpec) corev
}

mongotCmd := []string{
"mongot-community/mongot",
"--config=" + configMountPath + "/" + configFileName,
"mongot", "--config=" + configMountPath + "/" + configFileName,
}

if flags := jvmFlags(search); len(flags) > 0 {
Expand Down Expand Up @@ -279,25 +273,13 @@ func mongotProbe(override *corev1.Probe) *corev1.Probe {
// it falls back to the inline EmptyDir / HostPath source, matching how
// pkg/psmdb handles mongod's data volume.
func podVolumes(cr *api.PerconaServerMongoDB, rs *api.ReplsetSpec, search *api.SearchSpec) ([]corev1.Volume, []corev1.PersistentVolumeClaim) {
fvar := false

volumes := []corev1.Volume{
{
Name: config.BinVolumeName,
VolumeSource: corev1.VolumeSource{
EmptyDir: &corev1.EmptyDirVolumeSource{},
},
},
{
Name: cr.Spec.Secrets.GetInternalKey(cr),
VolumeSource: corev1.VolumeSource{
Secret: &corev1.SecretVolumeSource{
SecretName: cr.Spec.Secrets.GetInternalKey(cr),
DefaultMode: new(secretFileMode),
Optional: &fvar,
},
},
},
{
Name: configVolumeName,
VolumeSource: corev1.VolumeSource{
Expand Down
2 changes: 1 addition & 1 deletion pkg/psmdb/vectorsearch/statefulset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@ func TestMongotContainer_JVMFlagsArg(t *testing.T) {

wantArgs := append(
[]string{
"mongot-community/mongot",
"mongot",
"--config=" + configMountPath + "/" + configFileName,
},
tt.wantJVMArgs...,
Expand Down
Loading