Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F117751758
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
21 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/kolabctl b/kolabctl
index 9f2d15c..4932905 100755
--- a/kolabctl
+++ b/kolabctl
@@ -1,673 +1,674 @@
#!/bin/bash
# shellcheck disable=SC2068
# shellcheck disable=SC2086
HOST=${HOST:-kolab.local}
NAMESPACE=${NAMESPACE:-kolab}
CHART_VERSION=${CHART_VERSION:-"0.1.0"}
CHART_URL=${CHART_URL:-"oci://quay.io/apheleiait/kolab/kolab"}
USERNAME=${USERNAME:-"apheleiait+kolab"}
PASSWORD=${PASSWORD:-"Z8Q8KT04M4ADF7D18PDINUG4V3ZO6GYP4JPPAUGPANO4KWGYS93LR7QQ5DGLFRQP"}
export KUBECONFIG=${KUBECONFIG:-"$HOME/.kube/config"}
### ========== Implementation Details ============
#Ensure we are connected to the correct cluster (localhost only for now)
__ensure_server() {
- if ! grep server: ~/.kube/config | grep 127.0.0.1; then
- echo "Connected to the wrong server!"
+ if ! kubectl cluster-info | grep 127.0.0.1; then
+ echo "Connected to the wrong server! Only localhost is supported for now."
+ kubectl cluster-info
exit
fi
}
__helm_upgrade() {
if [[ -f values.yaml ]]; then
ARGS="-f values.yaml"
fi
time helm upgrade -i kolab --create-namespace $ARGS $@ --namespace "$NAMESPACE" "$CHART_URL" --version "$CHART_VERSION"
command kubectl -n $NAMESPACE rollout status deployment
command helm status kolab -n $NAMESPACE
}
__helm_template() {
if [[ -f values.yaml ]]; then
ARGS="-f values.yaml"
fi
command helm template kolab --namespace "$NAMESPACE" "$CHART_URL" $ARGS $@ --version "$CHART_VERSION"
}
__k3s_login() {
# Copy k3s config
mkdir -p "$HOME/.kube"
sudo cp /etc/rancher/k3s/k3s.yaml "$HOME/.kube/config"
sudo chown $(id -u):$(id -g) "$HOME/.kube/config"
chmod 600 "$HOME/.kube/config"
echo "Export this: export KUBECONFIG=$HOME/.kube/config"
}
# Pull images as defined in helm chart.
# Pass in username and password for registry
# This currently only pulls the kolab images (for the rest we'd have to figure out where to pull from)
__k3s_pull() {
# Figure out which images to pull
images=$(__helm_template | grep "image: " | grep -v "#" | grep -oP "(?<=image: ).*" | sed 's/\"//g' | uniq )
for image in $images; do
echo "Pulling $image"
# For the quay.io/apheleiait images we need to pass in the credentials
if [[ $image == *"quay.io/apheleiait"* ]]; then
if [[ -z $1 || -z $2 ]]; then
echo "You need to specify the quay.io/apheleiait username and password"
exit 1
fi
sudo k3s ctr images pull --user "$1:$2" "$image"
else
#TODO Support non apheleiait images?
sudo k3s ctr images pull "$image"
fi
done
}
__k3s_install() {
# TURN OFF firewalld if you're seeing any networking issues.
# Install K3S
sudo mkdir -p /etc/rancher/k3s/
curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="server" sh -s - --disable traefik,servicelb
sudo chmod 644 /etc/rancher/k3s/k3s.yaml
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
__k3s_login
# Check K3S
kubectl get pods -n kube-system
# Install certmanager
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.3/cert-manager.crds.yaml
helm repo add jetstack https://charts.jetstack.io
helm repo add haproxytech https://haproxytech.github.io/helm-charts
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo add metallb https://metallb.github.io/metallb
helm repo update
helm install cert-manager jetstack/cert-manager \
--wait \
--namespace cert-manager \
--create-namespace \
--version v1.13.3
helm install haproxy-ingress haproxytech/kubernetes-ingress \
--wait \
--namespace haproxy-controller \
--create-namespace \
--set controller.config.ssl-certificate=kolab/kolab-cert \
--set controller.kind=DaemonSet \
--set controller.daemonset.useHostPort=true \
--version 1.38.5
helm install kube-state-metrics prometheus-community/kube-state-metrics \
--wait \
--namespace default \
--version 3.0.0
helm install metallb metallb/metallb --create-namespace \
--namespace metallb-system --wait
}
__sum_memory_requests() {
res=$(kubectl get pods -o=jsonpath='{.items[*]..resources.requests.memory}' -n "$NAMESPACE")
let tot=0
for i in $res; do
if [[ $i =~ "Mi" ]]; then
i=$(echo $i | sed 's/[^0-9]*//g')
tot=$(( tot + i ))
elif [[ $i =~ "Gi" ]]; then
i=$(echo $i | sed 's/[^0-9]*//g')
tot=$(( tot + i * 1000 ))
fi
done
echo $tot
}
__sum_cpu_requests() {
res=$(kubectl get pods -o=jsonpath='{.items[*]..resources.requests.cpu}' -n "$NAMESPACE")
let tot=0
for i in $res; do
if [[ $i =~ "m" ]]; then
i=$(echo $i | sed 's/[^0-9]*//g')
tot=$(( tot + i ))
else
tot=$(( tot + i*1000 ))
fi
done
echo $tot
}
__replace_multiline() {
# Echo content, indent by the passed in spaces, insert before matching line
echo -n "$2" | sed -e "s/^/$4/" | sed -i "/$1/e cat /dev/stdin;echo" $3
# delete the matching line
sed -i "/$1/d" $3
}
### ========== End of Implementation ============
#
### ========== Commands ============
# Cluster admin commands
kolab__deploy() {
if [[ ! -f values.yaml ]]; then
echo "Missing a values.yaml file, run configure first."
exit 1
fi
if [[ "$1" == "--k3s" ]]; then
shift
__k3s_install
__k3s_pull $USERNAME $PASSWORD
helm registry login quay.io/apheleiait -u "$USERNAME" -p "$PASSWORD"
fi
__ensure_server
echo "This is going to take a while (timeout after 30 minutes)"
__helm_upgrade
}
kolab__uninstall() {
command helm uninstall kolab --wait --timeout 10m0s --debug $ARGS $@ --namespace "$NAMESPACE"
}
kolab__update() {
__helm_upgrade $@
}
kolab__template() {
__helm_template $@
}
kolab__pull() {
__k3s_pull $@
}
# Update the kolabctl script from the latest tarball
kolab__selfupdate() {
wget https://mirror.apheleia-it.ch/pub/kolab-kubernetes-latest.tar.gz -O /tmp/kolab-kubernetes-latest.tar.gz
tar -zxvf /tmp/kolab-kubernetes-latest.tar.gz kolabctl
}
# kolab__backup() {
# command bin/backup.sh
# }
# kolab__restore() {
# command bin/restore.sh
# }
# Render a values.yaml file from a template in docs
kolab__configure() {
if [[ "$1" == "--openshift" ]]; then
TEMPLATE="docs/openshift.values.yaml"
else
TEMPLATE="docs/k3s.values.yaml"
fi
if [[ -f values.yaml ]]; then
echo "values.yaml already exists";
exit 1
fi
if [[ -z $DOMAIN ]]; then
echo "Please enter your domain:"
read -r DOMAIN
fi
if [[ -z $ADMIN_PASSWORD ]]; then
echo "Please enter your new admin password for the admin@$DOMAIN user:"
read -r ADMIN_PASSWORD
fi
if [[ "$1" == "--openshift" ]]; then
if [[ -z $POSTFIX_LOADBALANCER_IP ]]; then
echo "Please enter your postfix loadbalancer ip:"
read -r POSTFIX_LOADBALANCER_IP
fi
if [[ -z $PROXY_LOADBALANCER_IP ]]; then
echo "Please enter your proxy loadbalancer ip:"
read -r PROXY_LOADBALANCER_IP
fi
if [[ -z $MEET_LOADBALANCER_IP ]]; then
echo "Please enter your meet loadbalancer ip:"
read -r MEET_LOADBALANCER_IP
fi
if [[ -z $METALLB_ADDRESS_POOL ]]; then
echo "Please enter your metallb address pool:"
read -r METALLB_ADDRESS_POOL
fi
if [[ -z $STORAGE_CLASS ]]; then
echo "Please enter your storage class:"
read -r STORAGE_CLASS
fi
else
# Assamble the docker secret, which will be our pull secret
PULL_SECRET=$(
cat <<EOF | base64 -w0
{
"auths": {
"quay.io": {
"auth": "$(echo -n "$USERNAME:$PASSWORD" | base64 -w0)",
"email": ""
}
}
}
EOF
)
fi
if [[ -z $PUBLIC_IP ]]; then
echo "Please enter your public ip:"
read -r PUBLIC_IP
fi
TEST_PASSWORD=$(openssl rand -base64 24)
APP_KEY=$(openssl rand -base64 32);
APP_KEY="base64:${APP_KEY}"
COTURN_STATIC_SECRET=$(openssl rand -hex 32);
PASSPORT_PROXY_OAUTH_CLIENT_ID=$(uuidgen);
PASSPORT_PROXY_OAUTH_CLIENT_SECRET=$(openssl rand -base64 32)
PASSPORT_PRIVATE_KEY=$(openssl genrsa 4096);
PASSPORT_PUBLIC_KEY=$(echo "$PASSPORT_PRIVATE_KEY" | openssl rsa -pubout 2>/dev/null)
MEET_WEBHOOK_TOKEN=$(openssl rand -hex 32)
MEET_SERVER_TOKEN=$(openssl rand -hex 32)
MEET_PUBLIC_IP="$PUBLIC_IP"
DB_ROOT_PASSWORD=$(openssl rand -hex 16)
DB_KOLAB_PASSWORD=$(openssl rand -hex 16)
DB_LEGACY_PASSWORD=$(openssl rand -hex 16)
DB_ROUNDCUBE_PASSWORD=$(openssl rand -hex 16)
REDIS_PASSWORD=$(openssl rand -hex 16)
MAIL_NOREPLY_PASSWORD=$(openssl rand -hex 16)
MINIO_ROOT_PASSWORD=$(openssl rand -hex 16)
IMAP_ADMIN_PASSWORD=$(openssl rand -hex 16)
ROUNDCUBE_DES_KEY=$(openssl rand -base64 24);
DKIM_IDENTIFIER="dkim20240318"
DKIM_KEY=$(openssl genrsa 2048);
cp "$TEMPLATE" values.yaml
# / can appear in base64, but | not
sed -i \
-e "s|DOMAIN|${DOMAIN}|g" \
-e "s|TEST_PASSWORD|${TEST_PASSWORD}|g" \
-e "s|IMAP_ADMIN_PASSWORD|${IMAP_ADMIN_PASSWORD}|g" \
-e "s|APP_KEY|${APP_KEY}|g" \
-e "s|PULL_SECRET|${PULL_SECRET}|g" \
-e "s|PASSPORT_PROXY_OAUTH_CLIENT_ID|${PASSPORT_PROXY_OAUTH_CLIENT_ID}|g" \
-e "s|PASSPORT_PROXY_OAUTH_CLIENT_SECRET|${PASSPORT_PROXY_OAUTH_CLIENT_SECRET}|g" \
-e "s|PASSPORT_PROXY_OAUTH_CLIENT_SECRET|${PASSPORT_PROXY_OAUTH_CLIENT_SECRET}|g" \
-e "s|ROUNDCUBE_DES_KEY|${ROUNDCUBE_DES_KEY}|g" \
-e "s|MEET_WEBHOOK_TOKEN|${MEET_WEBHOOK_TOKEN}|g" \
-e "s|MEET_SERVER_TOKEN|${MEET_SERVER_TOKEN}|g" \
-e "s|MEET_PUBLIC_IP|${MEET_PUBLIC_IP}|g" \
-e "s|COTURN_STATIC_SECRET|${COTURN_STATIC_SECRET}|g" \
-e "s|DB_ROOT_PASSWORD|${DB_ROOT_PASSWORD}|g" \
-e "s|DB_KOLAB_PASSWORD|${DB_KOLAB_PASSWORD}|g" \
-e "s|DB_LEGACY_PASSWORD|${DB_LEGACY_PASSWORD}|g" \
-e "s|DB_ROUNDCUBE_PASSWORD|${DB_ROUNDCUBE_PASSWORD}|g" \
-e "s|REDIS_PASSWORD|${REDIS_PASSWORD}|g" \
-e "s|MAIL_NOREPLY_PASSWORD|${MAIL_NOREPLY_PASSWORD}|g" \
-e "s|MINIO_ROOT_PASSWORD|${MINIO_ROOT_PASSWORD}|g" \
-e "s|DKIM_IDENTIFIER|${DKIM_IDENTIFIER}|g" \
-e "s|ADMIN_PASSWORD|${ADMIN_PASSWORD}|g" \
-e "s|PUBLIC_IP|${PUBLIC_IP}|g" \
-e "s|STORAGE_CLASS|${STORAGE_CLASS}|g" \
-e "s|MEET_LOADBALANCER_IP|${MEET_LOADBALANCER_IP}|g" \
-e "s|PROXY_LOADBALANCER_IP|${PROXY_LOADBALANCER_IP}|g" \
-e "s|POSTFIX_LOADBALANCER_IP|${POSTFIX_LOADBALANCER_IP}|g" \
-e "s|METALLB_ADDRESS_POOL|${METALLB_ADDRESS_POOL}|g" \
values.yaml
__replace_multiline PASSPORT_PRIVATE_KEY "$PASSPORT_PRIVATE_KEY" values.yaml " "
__replace_multiline PASSPORT_PUBLIC_KEY "$PASSPORT_PUBLIC_KEY" values.yaml " "
__replace_multiline DKIM_KEY "$DKIM_KEY" values.yaml " "
}
kolab__registry_login() {
helm registry login quay.io/apheleiait -u "$1" -p "$2"
}
__wait_for_service() {
echo "Waiting for service/$1"
# Wait for the ingress section with the assigned ip to appear
command timeout 10s bash -c "until kubectl -n kolab get service/$1 --output=jsonpath='{.status.loadBalancer}' | grep 'ingress'; do : ; done" || :
if command kubectl -n kolab get service/external-proxy --output=jsonpath='{.status.loadBalancer}' | grep "ingress"; then
echo "Service $1 is bound";
else
echo "Service $1 does not have an external ip";
exit 1;
fi
}
kolab__selfcheck() {
set -e
if command kubectl -n $NAMESPACE describe secret/kolab-cert-static --request-timeout "5s" &> /dev/null; then
echo "Found static tls secret"
elif command kubectl -n $NAMESPACE describe secret/kolab-cert-letsencrypt --request-timeout "5s" &> /dev/null; then
echo "Found letsencrypt secret"
else
echo "TLS secret not found"
exit 1
fi
# Wait for all rollouts to complete
command kubectl -n $NAMESPACE rollout status deployment
__wait_for_service "external-proxy"
__wait_for_service "external-smtp"
# Check that all pvcs are available
for pvc in $(kubectl -n kolab get --no-headers=true pvc -o name); do
command kubectl -n kolab wait --for=jsonpath='{.status.phase}'=Bound $pvc
done
command helm status kolab -n $NAMESPACE | grep "STATUS: deployed"
command kubectl exec --stdin --tty -n "$NAMESPACE" deployment/imap -- bash -c "testsaslauthd -u \$IMAP_ADMIN_LOGIN -p \$IMAP_ADMIN_PASSWORD"
command kubectl exec --stdin --tty -n "$NAMESPACE" deployment/horizon -- ./artisan status:health --check=Redis --check=IMAP
command kubectl exec --stdin --tty -n "$NAMESPACE" deployment/roundcube -- ./checkconnections.sh
echo "All tests passed"
}
kolab__stop() {
command /usr/local/bin/k3s-killall.sh
}
kolab__start() {
command systemctl start k3s
}
kolab__status() {
echo "# Cluster info"
command kubectl cluster-info
echo "# Helm deployments"
command helm list -A
echo "# Helm status"
command helm status kolab -n "$NAMESPACE" --show-resources
echo "# Events"
command kubectl get events --sort-by=.metadata.creationTimestamp
}
kolab__shell() {
if [[ $1 == "" ]]; then
# command kubectl run kolab -ti --rm -n "$NAMESPACE" --image localhost:5000/webapp:latest -- /bin/bash
command kubectl run utils -ti --rm -n "$NAMESPACE" --image quay.io/apheleiait/kolab/utils:latest -- /bin/bash
else
deployment=$1
shift
command kubectl exec --stdin --tty -n "$NAMESPACE" "deployment/$deployment" $@ -- /bin/bash
fi
}
kolab__logs() {
deployment="$1"
shift
command kubectl -n "$NAMESPACE" logs "deployment/$deployment" $@
}
# Tail the logs via logcli
# --pod=: wildcard match on the pod_name label
# --search=: Run a fulltext query match on the record
# -f: Stream the log
# --full: Full output including the entire record
kolab__tail() {
if [[ "$*" =~ "--pod" ]]; then
ARGUMENT=$(echo "$*" | grep -o -e "--pod=.*" | cut -d ' ' -f 1)
POD_NAME=$(echo "$ARGUMENT" | cut -d '=' -f 2)
POD_FILTER=",pod_name=~\"$POD_NAME.*\""
set -- "$(echo "$*" | sed "s|$ARGUMENT *||")"
fi
if [[ "$*" =~ "--search" ]]; then
ARGUMENT=$(echo "$*" | grep -o -e "--search=.*" | cut -d ' ' -f 1)
SEARCH_STRING=$(echo "$ARGUMENT" | cut -d '=' -f 2)
FULLTEXT_FILTER=" |~ \"$SEARCH_STRING\""
set -- "$(echo "$*" | sed "s|$ARGUMENT *||")"
fi
if [[ "$*" =~ "--full" ]]; then
set -- "$(echo "$*" | sed "s|--full *||")"
else
OUTPUT="--output=raw"
fi
echo "$*"
if [[ "$*" =~ "-f" ]]; then
FOLLOW="--follow"
fi
# The format is --from=2024-02-22T08:30:24Z --to=2024-02-23T12:30:24Z
if [[ "$*" =~ "--from" ]]; then
# Can't have --from without --to
FROM=$(echo "$*" | grep -o -e "--from=.*" | cut -d ' ' -f 1)
TO=$(echo "$*" | grep -o -e "--to=.*" | cut -d ' ' -f 1)
#beware of --limit (it will continue to apply, so you may get partial results)
# Can't follow with a time range
FOLLOW=""
fi
QUERY="{namespace_name=\"$NAMESPACE\"$POD_FILTER} $FULLTEXT_FILTER | json log | line_format \"{{ __timestamp__ }} \t {{.pod_name | trunc 10}} \t{{.log}}\""
echo "Running query: $QUERY"
env LOKI_ADDR="http://$HOST/" logcli query "$QUERY" $OUTPUT $FOLLOW $FROM $TO
}
kolab__describe() {
if [[ $1 == *"pod"* ]]; then
command kubectl -n "$NAMESPACE" describe $@
else
deployment="$1"
shift
command kubectl -n "$NAMESPACE" describe "deployment/$deployment" $@
fi
}
kolab__restart() {
command kubectl -n "$NAMESPACE" rollout restart deployment
}
kolab__ps() {
command kubectl -n "$NAMESPACE" get pods
}
kolab__get() {
command kubectl -n "$NAMESPACE" get $@
}
kolab__volumes() {
command kubectl -n "$NAMESPACE" get persistentvolumeclaims $@
}
kolab__build() {
command env REGISTRY="localhost:5000" build/build.sh --nochecks
}
kolab__top() {
command kubectl top pods -n "$NAMESPACE" --sum=true
command kubectl get pods -n "$NAMESPACE" -o=jsonpath='{range .items[*]}{"\n"}{.metadata.name}{":\t\t"}{..resources.requests.memory}{end}'
echo
echo
echo "Total memory requests: $(__sum_memory_requests) Mi"
echo "Total cpu requests: $(__sum_cpu_requests) m"
}
kolab__metrics() {
command kubectl get --raw /apis/metrics.k8s.io/v1beta1/pods | jq
command kubectl get --raw /apis/metrics.k8s.io/v1beta1/nodes | jq
# # Get the metrics for node <node_name>
# kubectl get --raw /apis/metrics.k8s.io/v1beta1/<node_name> | jq '.'
# # Get the metrics for pode <pod_name>
# kubectl get --raw /apis/metrics.k8s.io/v1beta1/<pod_name> | jq '.'
}
kolab__reset() {
if [[ "$1" == "--force" ]]; then
REPLY="y"
else
read -p "Are you sure? This will delete the k3s cluster including all data" -n 1 -r
echo
fi
if [[ "$REPLY" =~ ^[Yy]$ ]];
then
/usr/local/bin/k3s-uninstall.sh
fi
}
kolab__login() {
if [[ "$1" == "--k3s" ]]; then
__k3s_login
else
echo "Configure kubectl manually, login is not implemented"
fi
command kubectl cluster-info
}
kolab__exec() {
container=$1
shift
command kubectl exec --stdin --tty -n "$NAMESPACE" "deployment/$container" -- $@
}
# Administration commands
kolab__cyradm() {
# FIXME grep credentials from files
command kubectl exec --stdin --tty -n "$NAMESPACE" deployment/imap -- cyradm --auth PLAIN -u admin@kolab.local -w simple123 --port 11143 localhost
}
kolab__reseed() {
read -p "Are you sure? This will delete all data" -n 1 -r
echo
if [[ "$REPLY" =~ ^[Yy]$ ]];
then
kolab__exec horizon ./artisan migrate:fresh --seed
fi
}
kolab__users() {
kolab__exec horizon ./artisan users --attr=email
}
kolab__password() {
kolab__exec horizon ./artisan user:password $@
}
kolab__db() {
kolab__exec mariadb mysql -p
}
kolab__cleanup() {
kubectl -n $NAMESPACE delete pod --field-selector=status.phase==Succeeded
kubectl -n $NAMESPACE delete pod --field-selector=status.phase==Failed
}
# Show dns configuration based on values.yaml values
kolab__dns() {
PUBLIC_IP=$(cat values.yaml | yq '.meet.publicIp')
DOMAIN=$(cat values.yaml | yq '.domainName')
EMAILDOMAIN=$DOMAIN
DKIM_PRIVATE_KEY=$(cat values.yaml | yq '.amavis.dkim.key')
DKIM_IDENTIFIER=$(cat values.yaml | yq '.amavis.dkim.identifier')
# Extract public key from private key, remove delimiters and add quotation marks on each line. Finally indent result
DKIM_PUBLIC_KEY=$(cat values.yaml | yq '.amavis.dkim.key' | openssl pkey -pubout | grep --invert-match "\----" | sed -e 's/^\|$/"/g' | sed 's/^/ /';)
echo
echo "DNS Configuration:"
echo
cat <<EOF
$DOMAIN A $PUBLIC_IP
$EMAILDOMAIN MX 10 $DOMAIN.
$EMAILDOMAIN TXT "v=spf1 mx a:$DOMAIN mx:$DOMAIN -all"
autodiscover.$EMAILDOMAIN CNAME $DOMAIN.
_autodiscover._tcp.$DOMAIN SRV 0 0 443 $DOMAIN.
_caldav._tcp.$DOMAIN SRV 0 0 80 $DOMAIN.
_caldavs._tcp.$DOMAIN SRV 0 1 443 $DOMAIN.
_carddav._tcp.$DOMAIN SRV 0 0 80 $DOMAIN.
_carddavs._tcp.$DOMAIN SRV 0 1 443 $DOMAIN.
_imap._tcp.$DOMAIN SRV 0 0 143 $DOMAIN.
_imaps._tcp.$DOMAIN SRV 0 1 993 $DOMAIN.
_pop3._tcp.$DOMAIN SRV 10 0 110 $DOMAIN.
_pop3s._tcp.$DOMAIN SRV 10 1 995 $DOMAIN.
_sieve._tcp.$DOMAIN SRV 0 0 4190 $DOMAIN.
_smtp._tcp.$DOMAIN TXT "v=TLSRPTv1; rua=mailto:admin@$DOMAIN"
_submission._tcp.$DOMAIN SRV 0 1 587 $DOMAIN.
_webdav._tcp.$DOMAIN SRV 0 0 80 $DOMAIN.
_webdavs._tcp.$DOMAIN SRV 0 1 443 $DOMAIN.
_dmarc.$DOMAIN TXT "v=DMARC1; p=quarantine; adkim=s; aspf=s; rua=mailto:admin@$DOMAIN; ruf=mailto:admin@$DOMAIN"
_mta-sts.$DOMAIN TXT "v=STSv1; id=2024031901;"
$DKIM_IDENTIFIER._domainkey.$DOMAIN TXT (
"v=DKIM1; p="
$DKIM_PUBLIC_KEY
)
EOF
}
kolab__help() {
cat <<EOF
This is the kolab commandline utility.
The following commands are available:
deploy: Deploy kolab
start: Start all containers
stop: Stop all containers
update: This will update all containers.
backup: Create a backup in backup/
restore: Restore a backup from backup/
selfcheck: Run a selfcheck to ensure kolab is functional
EOF
}
cmdname=$1
shift
if [[ "${cmdname}" != "deploy" && "${cmdname}" != "configure" ]]; then
__ensure_server
fi
# make sure we actually *did* get passed a valid function name
if declare -f "kolab__$cmdname" >/dev/null 2>&1; then
"kolab__$cmdname" "${@:1}"
else
echo "Function $cmdname not recognized" >&2
kolab__help
exit 1
fi
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Apr 4, 3:25 AM (1 d, 2 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18822404
Default Alt Text
(21 KB)
Attached To
Mode
R114 kolab-infrastructure
Attached
Detach File
Event Timeline