Skip to content

Commit

Permalink
Merge pull request #679 from samjwillis97/mongo-improvements
Browse files Browse the repository at this point in the history
mongodb: initial user creation
  • Loading branch information
domenkozar authored Mar 22, 2024
2 parents 467e9d9 + c5d03b9 commit bb1164f
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 6 deletions.
61 changes: 61 additions & 0 deletions examples/mongodb/.test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#!/bin/sh
set -x

mongosh --version
mongod --version

# Start service in the background and store the PID
echo "Starting mongo service..."
devenv up&
DEVENV_PID=$!

check_mongo_status() {
echo "Waiting for service to become available..."
MONGO_OUTPUT=$(mongosh --quiet --eval "{ ping: 1 }" 2>&1)
MONGO_EXIT_STATUS=$?
}

check_if_mongo_user_created() {
# This line queries mongo using the shell and trims the output to make sure
# it is either an empty string or the created user document
createdUser=$(echo "use admin\n db.system.users.find({ user: \"mongouser\", db: \"admin\", \"roles.role\": \"root\", \"roles.db\": \"admin\" })" | mongosh --quiet --eval --shell | tail -n +2 | sed 's/^admin> //')

if [ -n "$createdUser" ]; then
MONGO_EXIT_STATUS=0
else
MONGO_EXIT_STATUS=1
fi
}

# Just to allow the service some time to start up
sleep 10

for i in $(seq 1 10); do
check_mongo_status
if [ $MONGO_EXIT_STATUS -eq 0 ]; then
echo "Service is up..."
break
else
sleep 1
fi
done

echo "Startup complete..."
echo "Checking for initial user creation..."
for i in $(seq 1 10); do
check_if_mongo_user_created
if [ $MONGO_EXIT_STATUS -eq 0 ]; then
echo "Initial user created..."
break
else
sleep 1
fi
done

echo 'Killing service...'
pkill -P $DEVENV_PID
wait $DEVENV_PID 2>&1 >/dev/null

# Exit the script
exit $MONGO_EXIT_STATUS

9 changes: 9 additions & 0 deletions examples/mongodb/devenv.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{ pkgs, config, ... }:

{
services.mongodb = {
enable = true;
initDatabaseUsername = "mongouser";
initDatabasePassword = "secret";
};
}
4 changes: 4 additions & 0 deletions examples/mongodb/devenv.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
allowUnfree: true
inputs:
nixpkgs:
url: github:NixOS/nixpkgs/nixpkgs-unstable
73 changes: 67 additions & 6 deletions src/modules/services/mongodb.nix
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,56 @@ let
startScript = pkgs.writeShellScriptBin "start-mongodb" ''
set -euo pipefail
${setupScript}/bin/setup-mongodb
exec ${cfg.package}/bin/mongod ${lib.concatStringsSep " " cfg.additionalArgs} -dbpath "$MONGODBDATA"
exec ${cfg.package}/bin/mongod ${
lib.concatStringsSep " " cfg.additionalArgs
} -dbpath "$MONGODBDATA"
'';

configureScript = pkgs.writeShellScriptBin "configure-mongodb" ''
set -euo pipefail
mongodArgs=(${lib.concatStringsSep " " cfg.additionalArgs})
mongoShellArgs=""
# Loop over the arguments, check if it contains --port
# If it does grab the port which must be the following arg
# wanted to keep the additionalArgs to not break any existing
# configs using it.
for i in "''${!mongodArgs[@]}"; do
if [[ "''${mongodArgs[$i]}" = "--port" ]]; then
mongoShellArgs="--port ''${mongodArgs[i + 1]}"
break
fi
done
while ! ${pkgs.mongosh}/bin/mongosh --quiet --eval "{ ping: 1 }" ''${mongoShellArgs} 2>&1 >/dev/null ; do
sleep 1
done
if [ "${cfg.initDatabaseUsername}" ] && [ "${cfg.initDatabasePassword}" ]; then
echo "Creating initial user"
rootAuthDatabase="admin"
${pkgs.mongosh}/bin/mongosh ''${mongoShellArgs} "$rootAuthDatabase" >/dev/null <<-EOJS
db.createUser({
user: "${cfg.initDatabaseUsername}",
pwd: "${cfg.initDatabasePassword}",``
roles: [ { role: 'root', db: "$rootAuthDatabase" } ]
})
EOJS
fi
# We need to keep this process running otherwise all processes stop
tail -f /dev/null
'';

in
{
imports = [
(lib.mkRenamedOptionModule [ "mongodb" "enable" ] [ "services" "mongodb" "enable" ])
(lib.mkRenamedOptionModule [ "mongodb" "enable" ] [
"services"
"mongodb"
"enable"
])
];

options.services.mongodb = {
Expand All @@ -41,16 +85,33 @@ in
Additional arguments passed to `mongod`.
'';
};

initDatabaseUsername = lib.mkOption {
type = types.str;
default = "";
example = "mongoadmin";
description = ''
This used in conjunction with initDatabasePassword, create a new user and set that user's password. This user is created in the admin authentication database and given the role of root, which is a "superuser" role.
'';
};

initDatabasePassword = lib.mkOption {
type = types.str;
default = "";
example = "secret";
description = ''
This used in conjunction with initDatabaseUsername, create a new user and set that user's password. This user is created in the admin authentication database and given the role of root, which is a "superuser" role.
'';
};
};

config = lib.mkIf cfg.enable {
packages = [
cfg.package
pkgs.mongodb-tools
];
packages = [ cfg.package pkgs.mongodb-tools pkgs.mongosh ];

env.MONGODBDATA = config.env.DEVENV_STATE + "/mongodb";

processes.mongodb.exec = "${startScript}/bin/start-mongodb";
processes.mongodb-configure.exec =
"${configureScript}/bin/configure-mongodb";
};
}

0 comments on commit bb1164f

Please sign in to comment.