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

Go to beta for SOGo #2

Merged
merged 49 commits into from
Dec 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
4e0ff80
Update build-images.sh script to include SOGo
stephdl Nov 27, 2023
e1c1cc7
Add discover-ldap script for LDAP service
stephdl Nov 27, 2023
6e2f84f
Add discover-service script for finding mail
stephdl Nov 27, 2023
bfab8e1
Add SOGo configuration file
stephdl Nov 27, 2023
fd6d2f5
Add systemd unit for sogo, mariadb-app, sogo-app
stephdl Nov 27, 2023
07bc2d8
Update build-images.sh script
stephdl Dec 13, 2023
a357aa6
Update sogo configuration with new parameters
stephdl Dec 13, 2023
fb84e28
Add hostname validation and configure SOGo environment variables
stephdl Dec 13, 2023
fb95bac
Add default environment variables for module creation
stephdl Dec 13, 2023
39015da
Refactor get-configuration script to read environment variables and u…
stephdl Dec 13, 2023
1e31acc
Update LDAP domain environment variable and rename discovery.env to d…
stephdl Dec 13, 2023
378305f
Update environment variable names in discover-service script
stephdl Dec 13, 2023
ab7ee50
Add expand-configuration script for generating SOGo configuration files
stephdl Dec 13, 2023
bf2295b
Add script to reveal master secret for mail module
stephdl Dec 13, 2023
380502c
Add SOGo configuration for database and authentication
stephdl Dec 13, 2023
36b40e3
Add SOGo apache configuration template file
stephdl Dec 13, 2023
992ede0
Add cron jobs for Sogod by template file
stephdl Dec 13, 2023
970a418
Update sogo-app.service with new environment files and volume mounts
stephdl Dec 13, 2023
4b9a784
Add network and host configurations to sogo.service
stephdl Dec 13, 2023
5e9b875
Remove static SOGo configuration file
stephdl Dec 13, 2023
82faa72
VueJs web settings page
stephdl Dec 13, 2023
f0f7516
Update metadata.json with new categories and author information
stephdl Dec 13, 2023
8319e68
Update @nethserver/ns8-ui-lib version to 0.1.27
stephdl Dec 13, 2023
71e6b74
Update configuration settings and remove http_to_https toggle
stephdl Dec 13, 2023
21dfef8
Add skeleton loading for module configuration form
stephdl Dec 13, 2023
caf789c
Update translation and settings for SOGo integration
stephdl Dec 13, 2023
e9c9df5
Update configure-module input schema
stephdl Dec 14, 2023
29fca94
Add examples and properties to validate-output.json
stephdl Dec 14, 2023
f78a488
Add translations and options for administrators, DAV, ActiveSync, wor…
stephdl Dec 14, 2023
762e6bb
Add activesync and dav configuration options
stephdl Dec 14, 2023
19ac656
Add advanced options in Settings page
stephdl Dec 14, 2023
df1bf0c
Update README.md with SOGo module description and installation instru…
stephdl Dec 14, 2023
b308f2a
Remove unused script smarthost-discovery and update service configur…
stephdl Dec 14, 2023
3fb8741
Add get-configuration command to README.md
stephdl Dec 14, 2023
31bdee7
Add symlink for configure-module/20configure
stephdl Dec 14, 2023
13dfb1f
Add restore-module scripts
stephdl Dec 14, 2023
aa8c930
Add module cleanup and dump state scripts
stephdl Dec 14, 2023
24675d9
Remove unused environment variables in sogo-app.service
stephdl Dec 14, 2023
07af8be
Add restart script for SOGo service
stephdl Dec 14, 2023
16d4887
Update default values in configuration file
stephdl Dec 14, 2023
a9ebe42
Update exit code in restoreDB script
stephdl Dec 14, 2023
2cedb2d
Update SOGo image reference
stephdl Dec 18, 2023
c136570
Update SOGo image variable in sogo-app.service
stephdl Dec 18, 2023
7f62707
Update sogo-server image version to 5.9.0
stephdl Dec 18, 2023
e5497ca
Update LDAP hostname in sogo.conf
stephdl Dec 18, 2023
c97bee0
Add fine tuning instructions for SOGo
stephdl Dec 19, 2023
b04a21c
Update SOGo installation guide with backup and restore instructions
stephdl Dec 19, 2023
a7c2c68
Update description in metadata.json
stephdl Dec 19, 2023
954a54c
Update documentation URL in metadata.json
stephdl Dec 19, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
127 changes: 77 additions & 50 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,32 +1,6 @@
# ns8-sogo

This is a template module for [NethServer 8](https://github.com/NethServer/ns8-core).
To start a new module from it:

1. Click on [Use this template](https://github.com/NethServer/ns8-sogo/generate).
Name your repo with `ns8-` prefix (e.g. `ns8-mymodule`).
Do not end your module name with a number, like ~~`ns8-baaad2`~~!

1. Clone the repository, enter the cloned directory and
[configure your GIT identity](https://git-scm.com/book/en/v2/Getting-Started-First-Time-Git-Setup#_your_identity)

1. Rename some references inside the repo:
```
modulename=$(basename $(pwd) | sed 's/^ns8-//')
git mv imageroot/systemd/user/sogo.service imageroot/systemd/user/${modulename}.service
git mv tests/sogo.robot tests/${modulename}.robot
sed -i "s/sogo/${modulename}/g" $(find .github/ * -type f)
git commit -a -m "Repository initialization"
```

1. Edit this `README.md` file, by replacing this section with your module
description

1. Adjust `.github/workflows` to your needs. `clean-registry.yml` might
need the proper list of image names to work correctly. Unused workflows
can be disabled from the GitHub Actions interface.

1. Commit and push your local changes
This module intends to istall the SOGo groupware : https://www.sogo.nu/

## Install

Expand All @@ -39,46 +13,99 @@ Output example:

{"module_id": "sogo1", "image_name": "sogo", "image_url": "ghcr.io/nethserver/sogo:latest"}

## Get the configuration
You can retrieve the configuration with

api-cli run get-configuration --agent module/sogo1

## Configure

Let's assume that the sogo instance is named `sogo1`.


Launch `configure-module`, by setting the following parameters:
- `<MODULE_PARAM1_NAME>`: <MODULE_PARAM1_DESCRIPTION>
- `<MODULE_PARAM2_NAME>`: <MODULE_PARAM2_DESCRIPTION>
- ...
- `host`: a fully qualified domain name for the application
- `lets_encrypt`: enable or disable Let's Encrypt certificate (true/false)
- `mail_server`: the module UUID of the the mail server (only on NS8), for example `24c52316-5af5-4b4d-8b0f-734f9ee9c1d9`
- `mail_domain`: the mail domain used for user IMAP login and SOGo user identifier. It must correspond to a valid mail domain handled by `mail_server` where user names are valid mail addresses too
- `ldap_domain`: a Ldap domain where to authenticate the users, it could be different than hostname. The ldap_domain is used to find an existing LDAP through LDAP proxy
- `admin_users`: the administrator of SOGo, a comma separated list (user1,user2)
- `workers_count`: The number of workers for SOGo; you need to adapt it to the numbers of users
- `auxiliary_account`: Allow users to set other email accounts inside the SOGo webmail (boolean)
- `activesync`: Enable the activesync protocom (boolean)
- `dav`: Enable the DAV protocol (caldav,cardav) (boolean)

Example:

api-cli run module/sogo1/configure-module --data '{}'
api-cli run configure-module --agent module/sogo1 --data - <<EOF
{
"mail_server": "f38f9911-8341-452e-8941-d889385a59a8",
"ldap_domain": "ad.rocky9-pve4.org",
"admin_users" : "Administrator",
"mail_domain": "rocky9-pve4.org",
"lets_encrypt": false,
"host": "sogo3.rocky9-pve4.org",
"workers_count": "3",
"auxiliary_account": true,
"activesync": true,
"dav": true
}
EOF

The above command will:
- start and configure the sogo instance
- (describe configuration process)
- ...
- start and configure the SOGo instance
- configure a virtual host for trafik to access the instance

## Manual configuration

Some settings are not available in the UI, you need to change them manually, refer to documentation : https://www.sogo.nu/files/docs/SOGoInstallationGuide.html

```
ssh sogo1@::1
vim .config/state/environment
```
modify the settings, then restart sogo : `systemctl restart --user sogo`

```
BACKUPTIME=#30 0
DRAFTSFOLDER=Drafts
SENTFOLDER=Sent
SESSIONDURATION=1440
SOGOACLSSENDEMAILNOTIFICATIONS=NO
SOGOAPPOINTMENTSENDEMAILNOTIFICATIONS=YES
SOGOENABLEEMAILALARMS=YES
SOGOFOLDERSSENDEMAILNOTIFICATIONS=NO
SOGOINTERNALSYNCINTERVAL=30
SOGOMAXIMUMPINGINTERVAL=3540
SOGOMAXIMUMSYNCINTERVAL=3540
SOGOMAXIMUMSYNCRESPONSESIZE=2048
SOGOMAXIMUMSYNCWINDOWSIZE=100
SXVMEMLIMIT=512
WOWATCHDOGREQUESTTIMEOUT=60
```

## Fine tuning

SOGo must be tuned https://sogo.nu/files/docs/SOGoInstallationGuide.html#_microsoft_enterprise_activesync_tuning following the number of users, some settings can be tested.

Keep in mind to set one worker per active user for the activesync connection. The SXVMEMLIMIT https://sogo.nu/files/docs/SOGoInstallationGuide.html#_general_preferences could be be adjusted also, between 25MB to 45 MB per active user with the activesync service.

Send a test HTTP request to the sogo backend service:
## Backup database

curl http://127.0.0.1/sogo/
You can enable a databse backup for each users of their addressbooks and their calendars, older entries more than 31 days are removed. The syntax is cron based, in the example it will be triggered each day at 00h30. the backup is disabled by default

## Smarthost setting discovery
```
- BACKUPTIME=#30 0
+ BACKUPTIME=30 0
```

Some configuration settings, like the smarthost setup, are not part of the
`configure-module` action input: they are discovered by looking at some
Redis keys. To ensure the module is always up-to-date with the
centralized [smarthost
setup](https://nethserver.github.io/ns8-core/core/smarthost/) every time
sogo starts, the command `bin/discover-smarthost` runs and refreshes
the `state/smarthost.env` file with fresh values from Redis.
you can restore the data with a tool ``sogo-restore-user``, for example:

Furthermore if smarthost setup is changed when sogo is already
running, the event handler `events/smarthost-changed/10reload_services`
restarts the main module service.
`sogo-restore-user /var/lib/sogo/backups/sogo-2017-12-10_0030/ stephane`

See also the `systemd/user/sogo.service` file.
or for all users:

This setting discovery is just an example to understand how the module is
expected to work: it can be rewritten or discarded completely.
`sogo-restore-user /var/lib/sogo/backups/sogo-2017-12-10_0030/ -A`

## Uninstall

Expand Down
6 changes: 4 additions & 2 deletions build-images.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ set -e

# Prepare variables for later use
images=()

# The image will be pushed to GitHub container registry
repobase="${REPOBASE:-ghcr.io/nethserver}"
# Configure the image name
reponame="sogo"
sogo_version="5.9.0"

# Create a new empty container image
container=$(buildah from scratch)
Expand All @@ -36,10 +38,10 @@ buildah add "${container}" imageroot /imageroot
buildah add "${container}" ui/dist /ui
# Setup the entrypoint, ask to reserve one TCP port with the label and set a rootless container
buildah config --entrypoint=/ \
--label="org.nethserver.authorizations=traefik@node:routeadm" \
--label="org.nethserver.authorizations=traefik@node:routeadm mail@any:mailadm" \
--label="org.nethserver.tcp-ports-demand=1" \
--label="org.nethserver.rootfull=0" \
--label="org.nethserver.images=docker.io/jmalloc/echo-server:latest" \
--label="org.nethserver.images=docker.io/mariadb:10.11.6 ghcr.io/nethserver/sogo-server:${sogo_version}" \
"${container}"
# Commit the image
buildah commit "${container}" "${repobase}/${reponame}"
Expand Down
1 change: 1 addition & 0 deletions imageroot/actions/clone-module/20configure
29 changes: 29 additions & 0 deletions imageroot/actions/configure-module/01hostname-validation
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/usr/bin/env python3

#
# Copyright (C) 2023 Nethesis S.r.l.
# SPDX-License-Identifier: GPL-3.0-or-later
#

import os
import sys
import json
import agent
import urllib.request
import urllib.error
import ssl

agent.set_weight(os.path.basename(__file__), 0) # Validation step, no task progress at all

# retrieve json data
data = json.load(sys.stdin)

# Setup default values
hostname = data.get("host")
# do not test if it is the same host
oldHost = os.environ.get('TRAEFIK_HOST','')

if hostname != oldHost and agent.http_route_in_use(domain=hostname):
agent.set_status('validation-failed')
json.dump([{'field':'hostname','parameter':'hostname','value':hostname,'error':'domain_already_used_in_traefik'}],fp=sys.stdout)
sys.exit(2)
24 changes: 24 additions & 0 deletions imageroot/actions/configure-module/10EnvSOGo
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/usr/bin/env python3

#
# Copyright (C) 2023 Nethesis S.r.l.
# SPDX-License-Identifier: GPL-3.0-or-later
#

import json
import sys
import agent

# Try to parse the stdin as JSON.
# If parsing fails, output everything to stderr
data = json.load(sys.stdin)

# Setup configuration from user input.
agent.set_env("MAIL_SERVER", data["mail_server"])
agent.set_env("ADMIN_USERS", data.get("admin_users","Administrator"))
agent.set_env("LDAP_DOMAIN", data["ldap_domain"])
agent.set_env("MAIL_DOMAIN",data.get("mail_domain",""))
agent.set_env("WOWORKERSCOUNT",data.get("workers_count","3"))
agent.set_env("AUXILIARYACCOUNT",data.get("auxiliary_account",True))
agent.set_env("ACTIVESYNC",data.get("activesync",True))
agent.set_env("DAV",data.get("dav",True))
31 changes: 23 additions & 8 deletions imageroot/actions/configure-module/20configure
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,37 @@ import agent
import agent.tasks
import os

request = json.load(sys.stdin)
# Try to parse the stdin as JSON.
# If parsing fails, output everything to stderr
data = json.load(sys.stdin)

# TODO: do something with the request payload. For example configure a
# custom route in our web router. Here the path is hardcoded as
# 'sogo'.
# Setup default values
host = data.get("host")
le = data.get("lets_encrypt", False)

# Talk with agent using file descriptor.
# Setup configuration from user input.
agent.set_env("TRAEFIK_HOST", host)
agent.set_env("TRAEFIK_LETS_ENCRYPT", le)

# Make sure everything is saved inside the environment file
# just before starting systemd unit
agent.dump_env()

# Find default traefik instance for current node
default_traefik_id = agent.resolve_agent_id('traefik@node')
if default_traefik_id is None:
sys.exit(2)

# Configure Traefik to route "/sogo" path requests to the sogo service
response = agent.tasks.run(
agent_id=agent.resolve_agent_id('traefik@node'),
action='set-route',
data={
'instance': os.environ['MODULE_ID'],
'url': 'http://127.0.0.1:' + os.environ["TCP_PORT"],
'http2https': False,
'lets_encrypt': False,
'path': '/sogo',
'host': host,
'http2https': True,
'lets_encrypt': le
},
)

Expand Down
5 changes: 2 additions & 3 deletions imageroot/actions/configure-module/80start_services
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,5 @@

# If the control reaches this step, the service can be enabled and started

touch smarthost.env

systemctl --user enable --now sogo.service
systemctl --user enable sogo.service
systemctl --user restart sogo.service
61 changes: 59 additions & 2 deletions imageroot/actions/configure-module/validate-input.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,63 @@
"title": "configure-module input",
"$id": "http://schema.nethserver.org/sogo/configure-module-input.json",
"description": "Configure sogo",
"examples": [],
"type": "object"
"examples": [
{
"mail_server": "f38f9911-8341-452e-8941-d889385a59a8",
"ldap_domain": "ad.domain.org",
"admin_users": "Administrator,user1",
"mail_domain": "domain.org",
"lets_encrypt": false,
"host": "sogo.domain.org",
"workers_count": "3",
"auxiliary_account": true,
"activesync": true,
"dav": true
}
],
"type": "object",
"properties": {
"mail_server": {
"type": "string"
},
"ldap_domain": {
"type": "string"
},
"admin_users": {
"type": "string"
},
"mail_domain": {
"type": "string"
},
"lets_encrypt": {
"type": "boolean"
},
"host": {
"type": "string"
},
"workers_count": {
"type": "string"
},
"auxiliary_account": {
"type": "boolean"
},
"activesync": {
"type": "boolean"
},
"dav": {
"type": "boolean"
}
},
"required": [
"mail_server",
"ldap_domain",
"admin_users",
"mail_domain",
"lets_encrypt",
"host",
"workers_count",
"auxiliary_account",
"activesync",
"dav"
]
}