diff --git a/nextcloud-aci/README.md b/nextcloud-aci/README.md index 246330c..fe697af 100644 --- a/nextcloud-aci/README.md +++ b/nextcloud-aci/README.md @@ -41,7 +41,7 @@ Unfortunately, this approach doesn't work well for two reasons: a technical issue, and a pricing issue. ### The Technical Issue with This Approach -ended up not working because of limitations in both +This approach ended up not working because of limitations in both Azure Files and Nextcloud. Nextcloud requires `config.php` to be owned by the same user account as the web server is running under (i.e. `www-data`) and to have permissions of `0770`. Meanwhile, Azure Files uses SMB which does not @@ -99,3 +99,6 @@ provides more robust control over volumes at a much more affordable price. F2s v2 instances can be used as Kubernetes nodes. This has the added benefit that multiple applications can be run on the same VMs in addition to Nextcloud, further increasing the cost effectiveness of your installation. + +**See the [nextcloud-aks](https://github.com/GuyPaddock/inveniem-nextcloud-azure/tree/master/nextcloud-aks) +folder for an approach that works by using AKS.** diff --git a/nextcloud-aks/helm-ingress/.gitignore b/nextcloud-aks/addons/helm-ingress/.gitignore similarity index 100% rename from nextcloud-aks/helm-ingress/.gitignore rename to nextcloud-aks/addons/helm-ingress/.gitignore diff --git a/nextcloud-aks/addons/helm-ingress/README.md b/nextcloud-aks/addons/helm-ingress/README.md new file mode 100644 index 0000000..b4893f3 --- /dev/null +++ b/nextcloud-aks/addons/helm-ingress/README.md @@ -0,0 +1,58 @@ +# Helm Ingress Add-on for Nextcloud Running on AKS +This folder contains configurations and scripts to assist in setting up an +ingress controller on AKS, running over HTTPS with certificates automatically +issued and renewed by Let's Encrypt. + +This approach is based primarily on +[Microsoft's Official Documentation](https://docs.microsoft.com/en-us/azure/aks/ingress-tls). + +## Using this Kit +### Providing Settings to the Scripts +All of the settings needed by scripts need to be provided in `config.env`. +Copy `config.example.env` to `config.env` and then customize it for your needs. + +Some settings are pulled-in from the top-level `nextcloud-aks` `config.env` file +as well; make sure both have been configured. See top-level README.md for details. + +### Prerequisite: Setting Up Helm and Tiller +Before Helm can be used to install components on the cluster, the cluster needs +to be configured with a Tiller server, and provided with TLS certificates to +secure the connection between the server and Helm clients. + +After providing settings in both `config.env` files (the one in the current +directory and the one in the top-level folder), run scripts in the following +order to perform this setup: +1. `./generate_ca_cert.sh` (do NOT run this a second time or you will lose CA certs). +2. `./generate_helm_client_cert.sh` +3. `./generate_tiller_server_cert.sh` +4. `./setup_helm.sh` + +## Prerequisite: Installing an Ingress Controller and Certificate Issuer +Before ingress can be deployed for Nextcloud, the cluster needs an ingress +_controller_ and a certificate issuer that can use Let's Encrypt to generate +SSL certificates. + +After setting-up Helm and Tiller, run scripts in the following order to +deploy an nginx-based ingress controller and certificate issuer: + +1. `./setup_cert_manager.sh` +2. `./deploy_certmanager_issuer.sh` +3. `./setup_ingress_controller.sh` + +### Deploying the Certificate Manager and Nextcloud Ingress +You can now deploy an ingress route for Nextcloud in the current Kubernetes +namespace by running the following command: + +``` +./deploy_nextcloud_ingress.sh +``` + +This command is idempotent; you can tweak your deployment and run it again to +make changes to the ingress configuration. + +This configuration automatically routes to the Nextcloud service that is +deployed and made available by the top-level `nextcloud-aks` kit. You only need +to deploy the ingress route once; you don't need to be re-deploy it if/when +you re-deploy Nextcloud or make changes to your Nextcloud deployment (e.g. +adding or removing replicas, updating images, etc). If there are no Nextcloud +instances available for the ingress to route to, you will get a 503 error. diff --git a/nextcloud-aks/helm-ingress/config.example.env b/nextcloud-aks/addons/helm-ingress/config.example.env similarity index 96% rename from nextcloud-aks/helm-ingress/config.example.env rename to nextcloud-aks/addons/helm-ingress/config.example.env index 6ff333c..9354d24 100644 --- a/nextcloud-aks/helm-ingress/config.example.env +++ b/nextcloud-aks/addons/helm-ingress/config.example.env @@ -11,6 +11,8 @@ # @license GNU AGPL version 3 or any later version # +source "../../config.env" + ################################################################################ # Certificate Settings ################################################################################ @@ -91,5 +93,4 @@ CERTMANAGER_NAMESPACE="kube-system" # # The default is to source from the trusted domain list in the top-level config. # -TRUSTED_DOMAIN_LIST=( ${NEXTCLOUD_TRUSTED_DOMAINS} ) -NEXTCLOUD_INGRESS_HOSTNAME="${TRUSTED_DOMAIN_LIST[0]}" +NEXTCLOUD_INGRESS_HOSTNAME="${NEXTCLOUD_PRIMARY_HOSTNAME}" diff --git a/nextcloud-aks/helm-ingress/configs/certmanager-issuer.template.yaml b/nextcloud-aks/addons/helm-ingress/configs/certmanager-issuer.template.yaml similarity index 100% rename from nextcloud-aks/helm-ingress/configs/certmanager-issuer.template.yaml rename to nextcloud-aks/addons/helm-ingress/configs/certmanager-issuer.template.yaml diff --git a/nextcloud-aks/helm-ingress/configs/helm-rbac.yaml b/nextcloud-aks/addons/helm-ingress/configs/helm-rbac.yaml similarity index 100% rename from nextcloud-aks/helm-ingress/configs/helm-rbac.yaml rename to nextcloud-aks/addons/helm-ingress/configs/helm-rbac.yaml diff --git a/nextcloud-aks/helm-ingress/configs/ingress-nextcloud.template.yaml b/nextcloud-aks/addons/helm-ingress/configs/ingress-nextcloud.template.yaml similarity index 100% rename from nextcloud-aks/helm-ingress/configs/ingress-nextcloud.template.yaml rename to nextcloud-aks/addons/helm-ingress/configs/ingress-nextcloud.template.yaml diff --git a/nextcloud-aks/helm-ingress/constants.env b/nextcloud-aks/addons/helm-ingress/constants.env similarity index 100% rename from nextcloud-aks/helm-ingress/constants.env rename to nextcloud-aks/addons/helm-ingress/constants.env diff --git a/nextcloud-aks/helm-ingress/deploy_certmanager_issuer.sh b/nextcloud-aks/addons/helm-ingress/deploy_certmanager_issuer.sh similarity index 93% rename from nextcloud-aks/helm-ingress/deploy_certmanager_issuer.sh rename to nextcloud-aks/addons/helm-ingress/deploy_certmanager_issuer.sh index b4a03e9..4d194e1 100755 --- a/nextcloud-aks/helm-ingress/deploy_certmanager_issuer.sh +++ b/nextcloud-aks/addons/helm-ingress/deploy_certmanager_issuer.sh @@ -21,8 +21,8 @@ set -e set -u -source "./constants.env" -source "./config.env" +source "constants.env" +source "config.env" ../preprocess_config.sh "${KUBE_CONFIG_PATH}/certmanager-issuer.template.yaml" | \ kubectl apply -f - diff --git a/nextcloud-aks/helm-ingress/deploy_nextcloud_ingress.sh b/nextcloud-aks/addons/helm-ingress/deploy_nextcloud_ingress.sh similarity index 93% rename from nextcloud-aks/helm-ingress/deploy_nextcloud_ingress.sh rename to nextcloud-aks/addons/helm-ingress/deploy_nextcloud_ingress.sh index b3678bc..10e0cf4 100755 --- a/nextcloud-aks/helm-ingress/deploy_nextcloud_ingress.sh +++ b/nextcloud-aks/addons/helm-ingress/deploy_nextcloud_ingress.sh @@ -23,8 +23,8 @@ set -e set -u -source "./constants.env" -source "./config.env" +source "constants.env" +source "config.env" ../preprocess_config.sh "${KUBE_CONFIG_PATH}/ingress-nextcloud.template.yaml" | kubectl apply -f - diff --git a/nextcloud-aks/helm-ingress/functions.sh b/nextcloud-aks/addons/helm-ingress/functions.sh old mode 100644 new mode 100755 similarity index 100% rename from nextcloud-aks/helm-ingress/functions.sh rename to nextcloud-aks/addons/helm-ingress/functions.sh diff --git a/nextcloud-aks/helm-ingress/generate_ca_cert.sh b/nextcloud-aks/addons/helm-ingress/generate_ca_cert.sh similarity index 95% rename from nextcloud-aks/helm-ingress/generate_ca_cert.sh rename to nextcloud-aks/addons/helm-ingress/generate_ca_cert.sh index fdc7297..0d76153 100755 --- a/nextcloud-aks/helm-ingress/generate_ca_cert.sh +++ b/nextcloud-aks/addons/helm-ingress/generate_ca_cert.sh @@ -21,9 +21,9 @@ set -e set -u -source "./constants.env" -source "./config.env" -source "./functions.sh" +source "constants.env" +source "config.env" +source "functions.sh" mkdir -p "${OUTPUT_PATH}" diff --git a/nextcloud-aks/helm-ingress/generate_helm_client_cert.sh b/nextcloud-aks/addons/helm-ingress/generate_helm_client_cert.sh similarity index 95% rename from nextcloud-aks/helm-ingress/generate_helm_client_cert.sh rename to nextcloud-aks/addons/helm-ingress/generate_helm_client_cert.sh index 1a56301..0b715da 100755 --- a/nextcloud-aks/helm-ingress/generate_helm_client_cert.sh +++ b/nextcloud-aks/addons/helm-ingress/generate_helm_client_cert.sh @@ -20,9 +20,9 @@ set -e set -u -source "./constants.env" -source "./config.env" -source "./functions.sh" +source "constants.env" +source "config.env" +source "functions.sh" mkdir -p "${OUTPUT_PATH}" diff --git a/nextcloud-aks/helm-ingress/generate_tiller_server_cert.sh b/nextcloud-aks/addons/helm-ingress/generate_tiller_server_cert.sh similarity index 95% rename from nextcloud-aks/helm-ingress/generate_tiller_server_cert.sh rename to nextcloud-aks/addons/helm-ingress/generate_tiller_server_cert.sh index 2596c42..27fe231 100755 --- a/nextcloud-aks/helm-ingress/generate_tiller_server_cert.sh +++ b/nextcloud-aks/addons/helm-ingress/generate_tiller_server_cert.sh @@ -20,9 +20,9 @@ set -e set -u -source "./constants.env" -source "./config.env" -source "./functions.sh" +source "constants.env" +source "config.env" +source "functions.sh" mkdir -p "${OUTPUT_PATH}" diff --git a/nextcloud-aks/helm-ingress/setup_cert_manager.sh b/nextcloud-aks/addons/helm-ingress/setup_cert_manager.sh similarity index 95% rename from nextcloud-aks/helm-ingress/setup_cert_manager.sh rename to nextcloud-aks/addons/helm-ingress/setup_cert_manager.sh index eb1e057..593ae20 100755 --- a/nextcloud-aks/helm-ingress/setup_cert_manager.sh +++ b/nextcloud-aks/addons/helm-ingress/setup_cert_manager.sh @@ -21,8 +21,8 @@ set -e set -u -source "./constants.env" -source "./config.env" +source "constants.env" +source "config.env" kubectl label namespace \ "${CERTMANAGER_NAMESPACE}" \ diff --git a/nextcloud-aks/helm-ingress/setup_helm.sh b/nextcloud-aks/addons/helm-ingress/setup_helm.sh similarity index 97% rename from nextcloud-aks/helm-ingress/setup_helm.sh rename to nextcloud-aks/addons/helm-ingress/setup_helm.sh index 0aa62e8..4a89813 100755 --- a/nextcloud-aks/helm-ingress/setup_helm.sh +++ b/nextcloud-aks/addons/helm-ingress/setup_helm.sh @@ -30,8 +30,8 @@ set -e set -u -source "./constants.env" -source "./config.env" +source "constants.env" +source "config.env" if [[ ! -f "${CA_CERT_PATH}" ]]; then echo "CA certificate is missing: ${CA_CERT_PATH}" >&2 diff --git a/nextcloud-aks/helm-ingress/setup_ingress_controller.sh b/nextcloud-aks/addons/helm-ingress/setup_ingress_controller.sh similarity index 96% rename from nextcloud-aks/helm-ingress/setup_ingress_controller.sh rename to nextcloud-aks/addons/helm-ingress/setup_ingress_controller.sh index b51a2ff..90027db 100755 --- a/nextcloud-aks/helm-ingress/setup_ingress_controller.sh +++ b/nextcloud-aks/addons/helm-ingress/setup_ingress_controller.sh @@ -26,14 +26,14 @@ set -e set -u source "constants.env" -source "./config.env" +source "config.env" helm install --tls \ stable/nginx-ingress \ --namespace "${INGRESS_NAMESPACE}" \ --set 'controller.replicaCount=2' \ --set 'controller.service.externalTrafficPolicy=Local' \ - --set-string controller.config.proxy-body-size="512M" + --set-string controller.config.proxy-body-size="2G" # Public IP address of your ingress controller for attempt in {1..20}; do diff --git a/nextcloud-aks/addons/sftp/.gitignore b/nextcloud-aks/addons/sftp/.gitignore new file mode 100644 index 0000000..b386605 --- /dev/null +++ b/nextcloud-aks/addons/sftp/.gitignore @@ -0,0 +1 @@ +host_keys/ diff --git a/nextcloud-aks/addons/sftp/README.md b/nextcloud-aks/addons/sftp/README.md new file mode 100644 index 0000000..0cee261 --- /dev/null +++ b/nextcloud-aks/addons/sftp/README.md @@ -0,0 +1,75 @@ +# SFTP Server Add-on for Nextcloud Running on AKS +This folder contains configurations and scripts to assist in setting up an +SFTP server that can grant one or more users direct access to the Azure Files +volumes that underlie a Nextcloud AKS deployment. + +## Using this Kit +### Providing Settings to the Scripts +All of the settings needed by scripts need to be provided in `config.env`. +Copy `config.example.env` to `config.env` and then customize it for your needs. + +Some settings are pulled-in from the top-level `nextcloud-aks` `config.env` file +as well; make sure both have been configured. See top-level README.md for +details. + +### Specifying User Names and Passwords +This is controlled by the `SFTP_USER_ARRAY` array in `config.env`. + +See +[`config.example.env`](https://github.com/GuyPaddock/inveniem-nextcloud-azure/blob/master/nextcloud-aks/addons/sftp/config.example.env) +for an example of how to add users and passwords. In the example file, +the following users are allowed to log-in to the system: +- `larry` with a password of `larry-password` (password was encrypted). +- `moe` with a password of `moe-password` (password was encrypted). +- `curly` with a password of `curly-password` (password was encrypted). + +**NOTE:** All users _must_ have a user ID of `33` to maintain compatibility +with the way that the Azure Files volumes are mounted in the Nextcloud +containers. + +Long story short, Azure Files does not implement an ACL or POSIX ownership +controls, but Nextcloud requires specific permissions to function. To +accommodate this, the top-level `nextcloud-aks` kit uses options exposed by the +Azure Files driver (`mountOptions`) to set the user ID and permissions of each +volume at the _Persistent Volume_ level. In the Nextcloud containers, user ID +`33` is `www-data`. To avoid having to duplicate each persistent volumes just to +support SFTP, we are therefore forced to re-use the same user ID in the SFTP +container to ensure each user has access to files on those same persistent +volumes. + +### Specifying which Volumes Users Have Access To +This is controlled by the `PATH_USERS` associative array in `config.env`. + +See +[`config.example.env`](https://github.com/GuyPaddock/inveniem-nextcloud-azure/blob/master/nextcloud-aks/addons/sftp/config.example.env) +for an example of how to grant users access to file shares. In the example file, +the following users have access to the file shares specified: +- Larry and Moe both have access to the `client1` volume/share. It will appear + as `/client1` in SFTP when they log-in to their chroot-ed environment. +- Only Moe has access to the `client2` volume/share. It will appear as + `/client2` in SFTP when he logs-in to his chroot-ed environment. +- Curly and Moe both have access to the `client3` volume/share. It will appear + as `/client3` in SFTP when they log-in to their chroot-ed environment. + +### Prerequisite: Generating and Deploying Host Keys +To ensure that users don't get security errors when reconnecting to the cluster +after an SFTP pod has been cycled, this resource kit requires that SSH server +keys are pre-generated and deployed as a secret in the cluster. + +After providing settings in both `config.env` files (the one in the current +directory and the one in the top-level folder), run the following script +to perform this setup: +``` +./setup_host_keys.sh +``` + +### Deploying the SFTP Server +You can now deploy the SFTP server to the cluster in the current Kubernetes +namespace by running the following command: + +``` +./deploy_sftp_app.sh +``` + +This command is idempotent; you can tweak your deployment and run it again to +make changes to the SFTP pod configuration. diff --git a/nextcloud-aks/addons/sftp/config.example.env b/nextcloud-aks/addons/sftp/config.example.env new file mode 100644 index 0000000..8693d57 --- /dev/null +++ b/nextcloud-aks/addons/sftp/config.example.env @@ -0,0 +1,71 @@ +## +# Configuration Constants for the SFTP add-on application. +# +# This is an example configuration file for the scripts in this folder. You must +# tailor it to meet your needs, or you will end up with a less-than-ideal setup. +# +# @author Guy Elsmore-Paddock (guy@inveniem.com) +# @copyright Copyright (c) 2019, Inveniem +# @license GNU AGPL version 3 or any later version +# + +source '../../config.env' + +################################################################################ +# User Accounts and User Access +################################################################################ + +## +# An array of all the users who should be granted access to the system, along +# with their encrypted passwords and user IDs. +# +# NOTE: User ID MUST be 33 in order to match the Azure Files mount options that +# are in place for compatibility with Nextcloud's volume mounts. This +# means that all users log-in as the same user ID but with different login +# names. +# +# This is safe because: +# - Azure Files does not provide any ACL/permission enforcement anyway. +# - All users are chroot-ed by login name, so they can't see each other's +# files anyway. +# - SSH access is disabled, so they can't see who else is logged-in. +# +# See documentation here for the format: +# https://hub.docker.com/r/atmoz/sftp#encrypted-password +# +# Per documentation above, passwords can be generated like this: +# ``` +# echo -n "your-password" | \ +# docker run -i --rm atmoz/makepasswd --crypt-md5 --clearfrom=- +# ``` +# +SFTP_USER_ARRAY=( + 'larry:$1$36ZEFQn6$bDdiGy8EFUzaCtO.07xPO1:e:33' + 'curly:$1$KIB014xD$EOpbnqVSBjPUrJkn2L/Kk1:e:33' + 'moe:$1$e103gR21$M5JK/a8e2tOIDk.cH9S/5/:e:33' +) +SFTP_USER_STRING="${SFTP_USER_ARRAY[@]}" + +## +# An associative array from Nextcloud volume mounts to a space-separated list +# of users who should have access to that volume mount. +# +# Each key defined here must match a value that was defined in the +# STORAGE_FILE_SHARES value of the top-level config.env file in order for it +# to be effective. +# +declare -A PATH_USERS +PATH_USERS['client1']='larry moe' +PATH_USERS['client2']='moe' +PATH_USERS['client3']='curly moe' + +################################################################################ +# Secret Names +################################################################################ +# The names of ALL secrets must be unique, and must not overlap with any secrets +# from any other application running on the Kubernetes cluster. + +## +# The name of the secret within Kubernetes that will store the SFTP host keys. +# +KUBE_SFTP_CREDS_SECRET="sftp-host-keys" diff --git a/nextcloud-aks/addons/sftp/configs/app-sftp.template.yaml b/nextcloud-aks/addons/sftp/configs/app-sftp.template.yaml new file mode 100644 index 0000000..c5d57a6 --- /dev/null +++ b/nextcloud-aks/addons/sftp/configs/app-sftp.template.yaml @@ -0,0 +1,82 @@ +## +# Kubernetes deployment configuration for running SFTP alongside Nextcloud for +# one or more shares. +# +# @author Guy Elsmore-Paddock (guy@inveniem.com) +# @copyright Copyright (c) 2019, Inveniem +# @license GNU AGPL version 3 or any later version +# +apiVersion: apps/v1 +kind: Deployment +metadata: + name: sftp +spec: + replicas: 1 + revisionHistoryLimit: 2 + selector: + matchLabels: + app: frontend-sftp + template: + metadata: + labels: + app: frontend-sftp + role: frontend + spec: + containers: + # Container: The SFTP server. + - name: frontend-sftp + image: "atmoz/sftp:alpine" + ports: + - containerPort: 22 + resources: + requests: + cpu: 100m + memory: 64Mi + limits: + cpu: 500m + memory: 128Mi + volumeMounts: + - name: volume-secret-ssh-host-keys + mountPath: /etc/ssh/ssh_host_ed25519_key + subPath: ssh_host_ed25519_key + readOnly: true + - name: volume-secret-ssh-host-keys + mountPath: /etc/ssh/ssh_host_rsa_key + subPath: ssh_host_rsa_key + readOnly: true + # HACK: Until AKS supports pod presets, we have to kludge the dynamic + # mounts in via a variable expansion. Do not modify the last line of + # this comment; it gets expanded and replaced automatically when this + # file is pre-processed. Remove this entire comment when switching over + # to using pod presets. + # + # ${FILE_SHARE_VOLUME_MOUNT_LINES} + env: + - name: SFTP_USERS + value: "${SFTP_USER_STRING}" + volumes: + - name: volume-secret-ssh-host-keys + secret: + secretName: "${KUBE_SFTP_CREDS_SECRET}" + defaultMode: 0400 + # HACK: Until AKS supports pod presets, we have to kludge the dynamic + # mounts in via a variable expansion. Do not modify the last line of + # this comment; it gets expanded and replaced automatically when this + # file is pre-processed. Remove this entire comment when switching over + # to using pod presets. + # + # ${FILE_SHARE_VOLUME_LINES} +--- +apiVersion: v1 +kind: Service +metadata: + name: external-sftp + labels: + role: external-service +spec: + type: LoadBalancer + ports: + - port: 22889 + targetPort: 22 + selector: + app: frontend-sftp diff --git a/nextcloud-aks/addons/sftp/delete_sftp_app.sh b/nextcloud-aks/addons/sftp/delete_sftp_app.sh new file mode 100755 index 0000000..0975475 --- /dev/null +++ b/nextcloud-aks/addons/sftp/delete_sftp_app.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash + +## +# This script removes the SFTP application and its load balancer from +# Kubernetes. +# +# @author Guy Elsmore-Paddock (guy@inveniem.com) +# @copyright Copyright (c) 2019, Inveniem +# @license GNU AGPL version 3 or any later version +# + +set -e +set -u + +source './config.env' + +FILES+=( + 'app-sftp.template.yaml' +) + +# HACK: Until AKS supports pod presets, we have to kludge the dynamic mounts in +# via a variable expansions. +source ./generate_share_mount_lines.sh + +echo "Un-deploying SFTP application..." +for file in "${FILES[@]}"; do + ../../preprocess_config.sh "configs/${file}" | kubectl delete -f - +done +echo "Done." +echo "" diff --git a/nextcloud-aks/addons/sftp/deploy_sftp_app.sh b/nextcloud-aks/addons/sftp/deploy_sftp_app.sh new file mode 100755 index 0000000..b3ea69e --- /dev/null +++ b/nextcloud-aks/addons/sftp/deploy_sftp_app.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash + +## +# This script deploys the SFTP application and its load balancer to Kubernetes. +# +# NOTE: You MUST run `./setup_host_keys.sh` BEFORE running this script. +# +# @author Guy Elsmore-Paddock (guy@inveniem.com) +# @copyright Copyright (c) 2019, Inveniem +# @license GNU AGPL version 3 or any later version +# + +set -e +set -u + +source './config.env' + +FILES+=( + 'app-sftp.template.yaml' +) + +# HACK: Until AKS supports pod presets, we have to kludge the dynamic mounts in +# via a variable expansions instead. +source ./generate_share_mount_lines.sh + +echo "Deploying SFTP application..." +for file in "${FILES[@]}"; do + ../../preprocess_config.sh "configs/${file}" | kubectl apply -f - +done +echo "Done." +echo "" diff --git a/nextcloud-aks/addons/sftp/generate_host_keys.sh b/nextcloud-aks/addons/sftp/generate_host_keys.sh new file mode 100755 index 0000000..0c2fb4a --- /dev/null +++ b/nextcloud-aks/addons/sftp/generate_host_keys.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +## +# This script generates SSH host keys for the SFTP container. +# +# This ensures users do not get a security error upon connecting over SFTP after +# containers have cycled. +# +# @author Guy Elsmore-Paddock (guy@inveniem.com) +# @copyright Copyright (c) 2019, Inveniem +# @license GNU AGPL version 3 or any later version +# + +set -e +set -u + +mkdir -p ./host_keys/ +ssh-keygen -t ed25519 -f ./host_keys/ssh_host_ed25519_key -N '' +ssh-keygen -t rsa -b 4096 -f ./host_keys/ssh_host_rsa_key -N '' diff --git a/nextcloud-aks/addons/sftp/generate_share_mount_lines.sh b/nextcloud-aks/addons/sftp/generate_share_mount_lines.sh new file mode 100755 index 0000000..5674274 --- /dev/null +++ b/nextcloud-aks/addons/sftp/generate_share_mount_lines.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash + +## +# This script dynamically generates the portions of a Kubernetes container +# configuration that specify mounts for every file share defined in the +# configuration. +# +# - The `volumeMount` lines are exported in `FILE_SHARE_VOLUME_MOUNT_LINES`. +# - The `volume` lines are exported in `FILE_SHARE_VOLUME_LINES`. +# +# This frees users from having to edit shares directly in +# `app-sftp.template.yaml`. +# +# NOTE: This is a hack until AKS supports pod presets, which provide a much +# more elegant approach to this problem. Vote for the feature here: +# https://feedback.azure.com/forums/914020-azure-kubernetes-service-aks/suggestions/35054089-support-podpreset-alpha-feature +# +# ALSO NOTE: This is similar to, but distinct from, +# `generate_backend_share_mount_lines.sh` in the parent folder. This script has +# been tailored to match the needs of the SFTP application. +# +# @author Guy Elsmore-Paddock (guy@inveniem.com) +# @copyright Copyright (c) 2019, Inveniem +# @license GNU AGPL version 3 or any later version +# + +set -e +set -u + +source './config.env' + +generate_volume_mount_lines() { + # Ensure we end the comment on the prior line of the YAML file. + echo "" + + for file_share_name in "${STORAGE_FILE_SHARES[@]}"; do + if [[ ! ${PATH_USERS["${file_share_name}"]+_} ]]; then + continue + fi + + for user in ${PATH_USERS["${file_share_name}"]}; do + mount_path="/home/${user}/${file_share_name}" + + cat < '/var/log/nextcloud.log', + 'loglevel' => 1, ); diff --git a/nextcloud-aks/docker/nextcloud-common/config/readonly.config.php b/nextcloud-aks/docker/nextcloud-common/config/readonly.config.php new file mode 100644 index 0000000..a5a954b --- /dev/null +++ b/nextcloud-aks/docker/nextcloud-common/config/readonly.config.php @@ -0,0 +1,11 @@ + $read_only_bool, + ); diff --git a/nextcloud-aks/docker/nextcloud-common/entrypoint.sh b/nextcloud-aks/docker/nextcloud-common/entrypoint.sh index ad51825..f5ac603 100755 --- a/nextcloud-aks/docker/nextcloud-common/entrypoint.sh +++ b/nextcloud-aks/docker/nextcloud-common/entrypoint.sh @@ -96,6 +96,17 @@ deploy_nextcloud_release() { # Explicitly sync 'custom_apps' in this Docker image rsync $rsync_options --delete /usr/src/nextcloud/custom_apps/ /var/www/html/custom_apps/ + if [ -w "/var/www/html/config" ]; then + echo "'config' directory is writable." + echo "Sync-ing configuration snippets:" + cp -v /usr/src/nextcloud/config/*.config.php /var/www/html/config/ + echo "" + else + echo "'config' directory is not writable." + echo "Configuration snippets will not be synced." + echo "" + fi + echo "Deployment finished." echo "" } diff --git a/nextcloud-aks/docker/publish_all.sh b/nextcloud-aks/docker/publish_all.sh index 47b7937..4fafdcc 100755 --- a/nextcloud-aks/docker/publish_all.sh +++ b/nextcloud-aks/docker/publish_all.sh @@ -12,14 +12,10 @@ set -e set -u -DIRS=( - 'backend-nextcloud-apache' - 'backend-nextcloud-fpm' - 'middle-nextcloud-nginx' -) +DIRS=$(find . -mindepth 1 -maxdepth 1 -type d -not -name '*common') ./nextcloud-common/download_apps.sh -for dir in "${DIRS[@]}"; do - "${dir}/publish.sh" +echo "${DIRS[@]}" | while read -r dir; do + "${dir}/publish.sh" done diff --git a/nextcloud-aks/generate_azure_file_volume_configs.sh b/nextcloud-aks/generate_azure_file_volume_configs.sh index 1d9c218..a32e0e1 100755 --- a/nextcloud-aks/generate_azure_file_volume_configs.sh +++ b/nextcloud-aks/generate_azure_file_volume_configs.sh @@ -21,6 +21,6 @@ for file_share_name in "${STORAGE_FILE_SHARES[@]}"; do export file_share_name # We use `grep -o` to skip Bash comment lines - ./preprocess_config.sh './configs/file-share.template.yaml' | \ + ./preprocess_config.sh './configs/vol-file-share.template.yaml' | \ grep -o '^[^#]*' done diff --git a/nextcloud-aks/generate_backend_share_mount_lines.sh b/nextcloud-aks/generate_backend_share_mount_lines.sh index 0e99c40..811ef0b 100755 --- a/nextcloud-aks/generate_backend_share_mount_lines.sh +++ b/nextcloud-aks/generate_backend_share_mount_lines.sh @@ -9,7 +9,7 @@ # - The `volume` lines are exported in `FILE_SHARE_VOLUME_LINES`. # # This frees users from having to edit shares directly in -# `nextcloud-apache.template.yaml` or `nextcloud-fpm-nginx.template.yaml`. +# `app-nextcloud-apache.template.yaml` or `app-nextcloud-fpm-nginx.template.yaml`. # # NOTE: This is a hack until AKS supports pod presets, which provide a much # more elegant approach to this problem. Vote for the feature here: diff --git a/nextcloud-aks/generate_share_mount_pod_preset.sh b/nextcloud-aks/generate_share_mount_pod_preset.sh index 837291c..01b4ea5 100755 --- a/nextcloud-aks/generate_share_mount_pod_preset.sh +++ b/nextcloud-aks/generate_share_mount_pod_preset.sh @@ -6,7 +6,7 @@ # configuration. # # This frees users from having to edit shares directly in -# `nextcloud-apache.template.yaml` or `nextcloud-fpm-nginx.template.yaml`. +# `app-nextcloud-apache.template.yaml` or `app-nextcloud-fpm-nginx.template.yaml`. # # @author Guy Elsmore-Paddock (guy@inveniem.com) # @copyright Copyright (c) 2019, Inveniem diff --git a/nextcloud-aks/launch_aks_dashboard.sh b/nextcloud-aks/launch_aks_dashboard.sh index 3dd2668..015d79f 100755 --- a/nextcloud-aks/launch_aks_dashboard.sh +++ b/nextcloud-aks/launch_aks_dashboard.sh @@ -16,10 +16,16 @@ source './config.env' # Loop to restore tunnel if it dies due to inactivity while true; do + PREVIOUS_CONTEXT=$(kubectl config current-context) + + # NOTE: This changes to the "default" Kube context az aks get-credentials \ --resource-group "${KUBE_RESOURCE_GROUP}" \ --name "${KUBE_NAME}" \ + # Restore context + kubectl config use-context "${PREVIOUS_CONTEXT}" + echo "Open http://localhost:8090 in your browser to connect to the Kubernetes dashboard." az aks browse \ --resource-group "${KUBE_RESOURCE_GROUP}" \ @@ -27,6 +33,9 @@ while true; do --listen-port=8090 \ --disable-browser + # Restore context + kubectl config use-context "${PREVIOUS_CONTEXT}" + echo "Relaunching tunnel in 2 seconds (CTRL+C to cancel)..." sleep 2 done diff --git a/nextcloud-aks/setup_aks_acr_service_principal.sh b/nextcloud-aks/setup_aks_acr_service_principal.sh index b0c84a8..ea7f6f0 100755 --- a/nextcloud-aks/setup_aks_acr_service_principal.sh +++ b/nextcloud-aks/setup_aks_acr_service_principal.sh @@ -4,7 +4,7 @@ # This script is used to setup AKS with credentials to an Azure AD service # principal that has access to the ACR repo where images are stored. # -# This script only needs to be run once per AKS instance. The name of each +# This script only needs to be run once per AKS context. The name of each # ACR service principal must be unique within an AD tenant. # # This script is based on: