diff --git a/.env b/.env new file mode 100644 index 000000000..7d096db7b --- /dev/null +++ b/.env @@ -0,0 +1,14 @@ +# tileserver +TILE_SPRITES_URL=https://raw.githubusercontent.com/maputnik/osm-liberty/gh-pages/sprites + +# database +POSTGRES_PASSWORD=CHANGE_ME +POSTGRES_USER=navigatum +POSTGRES_DB=navigatum + +# feedback +GITHUB_TOKEN=CHANGE_ME +JWT_KEY=CHANGE_ME + +# main api +MEILI_MASTER_KEY=CHANGE_ME diff --git a/.github/workflows/webclient-cicd.yml b/.github/workflows/webclient-cicd.yml index 1e4d7cc3d..6403f382e 100644 --- a/.github/workflows/webclient-cicd.yml +++ b/.github/workflows/webclient-cicd.yml @@ -30,7 +30,7 @@ jobs: uses: cypress-io/github-action@v5 with: start: npm run dev - wait-on: "http://localhost:8000" + wait-on: "http://localhost:3000" browser: ${{ matrix.browser }} working-directory: webclient webclient-linting: diff --git a/README.md b/README.md index 2b9d74070..326841f9f 100644 --- a/README.md +++ b/README.md @@ -41,8 +41,6 @@ Note: The API is still under development, and we are open to Issues, Feature Req NavigaTUM consists of three main parts + deployment resources. Depending on what you want to work on, you **do not need to set up all of them**. -For an overview of how the components work, have a look at the -[deployment documentation](deployment/README.md). - `data/` contains the code to obtain and process the data - `server/` contains the APIs written in Rust @@ -50,7 +48,18 @@ For an overview of how the components work, have a look at the - `deployment/` contains deployment related configuration - `map/` contains information about our own map, how to style it and how to run it -The following steps assume you have just cloned the repository and are in the root directory of it. +Let's go through them one by one, but first, you need to clone the repository: + +```bash +git clone https://github.com/TUM-Dev/Navigatum.git +cd Navigatum +``` + +> [!NOTE] +> You can skip all the parts if you run `docker compose up --build` in the root of the repository +> and then open [http://localhost:3000](http://localhost:3000) in your browser. +> This will run the server, the data processing and the webclient in docker containers. +> Initial setup will take a while, as it needs to download maps data for the entire planet (~90GB). ### Data Processing @@ -69,14 +78,7 @@ Else you can follow the steps in the [data documentation](data/README.md). If you want to work on the webclient only (and not server or data), you don't need to set up the server. You can instead either use the public API (see the [webclient documentation](webclient/README.md#Testing)) or use our ready-made docker images to run the server locally: ```bash -docker network create navigatum-net -sudo rm -fr /tmp/navigatum/ && mkdir -p /tmp/navigatum/ && mkdir -p /tmp/navigatum/meili/ && mkdir -p /tmp/navigatum/server/ - -docker run -it --rm -v /tmp/navigatum/meili:/meili_data ghcr.io/tum-dev/navigatum-mieli-search-init:main -docker run -it --rm -p 7700:7700 --name search -v /tmp/navigatum/meili:/meili_data --network navigatum-net getmeili/meilisearch:latest - -docker run -it --rm -v /tmp:/navigatum/server/ ghcr.io/tum-dev/navigatum-building-db-init:main -docker run -it --rm -p 8080:8080 --network navigatum-net -e API_SVC_SERVICE_HOST=search ghcr.io/tum-dev/navigatum-server:main /bin/navigatum-main-api +docker compose up --build ``` Else you can follow the steps in the [server documentation](server/README.md). diff --git a/data/Dockerfile b/data/Dockerfile index b19107a95..253dcc4ec 100644 --- a/data/Dockerfile +++ b/data/Dockerfile @@ -32,6 +32,6 @@ RUN mkdir /cdn COPY --from=build-stage /app/output /cdn COPY nginx.conf /etc/nginx/nginx.conf -EXPOSE 8000 -HEALTHCHECK CMD curl --fail localhost:8000/cdn/health || exit 1 +EXPOSE 3002 +HEALTHCHECK CMD curl --fail http://localhost:3002/cdn/health || exit 1 CMD ["nginx", "-g", "daemon off;"] diff --git a/data/nginx.conf b/data/nginx.conf index a00d2fb98..ec633bc34 100644 --- a/data/nginx.conf +++ b/data/nginx.conf @@ -21,7 +21,7 @@ http { server { # default_server makes nginx not care about HOST, we hande this upstream by Traefik - listen 8000 default_server; + listen 3002 default_server; root /; # compression configuration diff --git a/deployment/ansible/.gitignore b/deployment/ansible/.gitignore deleted file mode 100644 index 454b6550e..000000000 --- a/deployment/ansible/.gitignore +++ /dev/null @@ -1 +0,0 @@ -credentials diff --git a/deployment/ansible/group_vars/all.yml b/deployment/ansible/group_vars/all.yml deleted file mode 100644 index 25eedbe27..000000000 --- a/deployment/ansible/group_vars/all.yml +++ /dev/null @@ -1,43 +0,0 @@ -vpn_ips: - - 10.152.126.0/24 - - 10.152.127.0/24 - - 10.152.42.0/24 - - 10.152.43.0/24 - - 10.157.36.0/22 - - 10.157.40.0/22 - - 10.157.44.0/22 - - 10.157.48.0/22 - - 10.157.52.0/22 - - 129.187.100.0/24 - - 129.187.16.0/24 - - 129.187.17.0/24 - - 129.187.173.0/24 - - 129.187.178.0/24 - - 129.187.205.0/24 - - 129.187.207.0/24 - - 129.187.209.0/24 - - 129.187.210.0/24 - - 129.187.211.0/24 - - 129.187.212.0/24 - - 129.187.41.0/24 - - 129.187.47.0/24 - - 129.187.51.0/24 - - 129.187.98.0/24 - - "2001:4ca0:2fff::/48" -leaders_ipv6s: - - "2001:4ca0:800::8af6:e1ac" - - "2001:4ca0:800::8af6:e1ad" - - "2001:4ca0:800::8af6:e1ae" -leaders_ipv4s: - - 138.246.225.172 - - 138.246.225.173 - - 138.246.225.174 - -leader_ips: "{{ leaders_ipv6s + leaders_ipv4s }}" -# k8s -etcd_leader_ip: "{{ leaders_ipv6s[0] }}" -# nessesary or ipv6 dual-stack cluster -cluster_cidr: "10.42.0.0/16,2001:cafe:42:0::/56" -service_cidr: "10.43.0.0/16,2001:cafe:42:1::/112" -loadbalancer_ipv4: "129.187.254.65" -loadbalancer_ipv6: "2001:4ca0:0:103::81bb:fe41" diff --git a/deployment/ansible/hosts.ini b/deployment/ansible/hosts.ini deleted file mode 100644 index 34796d33c..000000000 --- a/deployment/ansible/hosts.ini +++ /dev/null @@ -1,10 +0,0 @@ -tuzeitm-navigatum-1 ansible_host=2001:4ca0:800::8af6:e1ac ansible_host_v4=138.246.225.172 ansible_port=37670 ansible_user=root -tuzeitm-navigatum-2 ansible_host=2001:4ca0:800::8af6:e1ad ansible_host_v4=138.246.225.173 ansible_port=37670 ansible_user=root -tuzeitm-navigatum-3 ansible_host=2001:4ca0:800::8af6:e1ae ansible_host_v4=138.246.225.174 ansible_port=37670 ansible_user=root - -[leader] -tuzeitm-navigatum-1 - -[followers] -tuzeitm-navigatum-2 -tuzeitm-navigatum-3 diff --git a/deployment/ansible/roles/common/handlers/main.yml b/deployment/ansible/roles/common/handlers/main.yml deleted file mode 100644 index 7fe20daa1..000000000 --- a/deployment/ansible/roles/common/handlers/main.yml +++ /dev/null @@ -1,4 +0,0 @@ -- name: restart_fail2ban - service: - name: fail2ban - state: restarted diff --git a/deployment/ansible/roles/common/tasks/_unatended_upgrades.yml b/deployment/ansible/roles/common/tasks/_unatended_upgrades.yml deleted file mode 100644 index 7b6e7510d..000000000 --- a/deployment/ansible/roles/common/tasks/_unatended_upgrades.yml +++ /dev/null @@ -1,18 +0,0 @@ -# This part is done by the LRZ, whcich is the hoster of the server -# If we were to migrate to another hoster, this would be needed -- name: Install unattended upgrades - apt: - name: "{{ item }}" - state: present - with_items: - - unattended-upgrades - - apt-listchanges -- name: Configure unattended upgrades - template: - src: 50unattended-upgrades.j2 - dest: /etc/apt/apt.conf.d/50unattended-upgrades - owner: root - group: root - mode: 0644 - notify: - - restart unattended upgrades diff --git a/deployment/ansible/roles/common/tasks/fail2ban.yml b/deployment/ansible/roles/common/tasks/fail2ban.yml deleted file mode 100644 index 301eba3a8..000000000 --- a/deployment/ansible/roles/common/tasks/fail2ban.yml +++ /dev/null @@ -1,13 +0,0 @@ -- name: Install fail2ban - apt: - name: fail2ban - state: present -- name: Configure fail2ban - template: - src: jail.local.j2 - dest: /etc/fail2ban/jail.local - owner: root - group: root - mode: 0644 - notify: - - restart_fail2ban diff --git a/deployment/ansible/roles/common/tasks/main.yml b/deployment/ansible/roles/common/tasks/main.yml deleted file mode 100644 index f1e3648ad..000000000 --- a/deployment/ansible/roles/common/tasks/main.yml +++ /dev/null @@ -1,46 +0,0 @@ ---- -# -# Tasks to be applied to all servers -# - -- name: Check connectivity - ping: - data: alive - tags: check -- name: Update apt cache - apt: - update_cache: yes - upgrade: safe - tags: check - -- name: Install packages - apt: - name: "{{ item }}" - state: present - with_items: - - htop - - tldr - - python3 - - python3-pip - tags: install - -- name: Run settings.yml - include_tasks: settings.yml - tags: settings - -- name: Run ssh.yml - include_tasks: ssh.yml - tags: ssh - -- name: Run ufw.yml - include_tasks: ufw.yml - tags: ufw - -- name: Run fail2ban.yml - include_tasks: fail2ban.yml - tags: fail2ban -# This part is done by the LRZ, whcich is the hoster of the server -# If we were to migrate to another hoster, this would be needed -#- name: Run unatended_upgrades.yml -# include_tasks: unatended_upgrades.yml -# tags: unatended_upgrades diff --git a/deployment/ansible/roles/common/tasks/settings.yml b/deployment/ansible/roles/common/tasks/settings.yml deleted file mode 100644 index 203a61498..000000000 --- a/deployment/ansible/roles/common/tasks/settings.yml +++ /dev/null @@ -1,42 +0,0 @@ -- name: set timezone - timezone: - name: Europe/Berlin -- name: set locale - locale_gen: - name: en_US.UTF-8 - state: present -- name: set text editor - alternatives: - name: editor - path: /bin/nano -- name: Set the hostname - hostname: - name: "{{ inventory_hostname }}" - -# by default this is configured to get our nodes down at 7 on specific dates, this configures the nodes not to fail all at the same time -- name: Configure lrz-base-automatic-reboot - template: - src: lrz-base-automatic-reboot.j2 - dest: /etc/cron.d/lrz-base-automatic-reboot - owner: root - group: root - mode: 0644 - -- name: Create an user, which can login via SSH to edit a file using rsync, but nothing more - ansible.builtin.user: - name: "rbg-rsync" - create_home: true - generate_ssh_key: true - ssh_key_type: ed25519 - ssh_key_file: ".ssh/id_{{ inventory_hostname }}" - ssh_key_comment: "frank@elsinga.de" - state: present - shell: /bin/bash -- name: make shure, that the user can login via SSH - ansible.builtin.copy: - remote_src: true - src: /home/rbg-rsync/.ssh/id_{{ inventory_hostname }}.pub - dest: /home/rbg-rsync/.ssh/authorized_keys - owner: rbg-rsync - group: rbg-rsync - mode: 0600 diff --git a/deployment/ansible/roles/common/tasks/ssh.yml b/deployment/ansible/roles/common/tasks/ssh.yml deleted file mode 100644 index 2ebdb0908..000000000 --- a/deployment/ansible/roles/common/tasks/ssh.yml +++ /dev/null @@ -1,34 +0,0 @@ -- name: Add ssh ports to UFW - ufw: - direction: in - rule: allow - port: "37670" - from_ip: "{{ item }}" - proto: tcp - comment: SSH from VPN - loop: "{{ vpn_ips }}" - -- name: Enshure, that authorized_keys file has the correct content - template: - src: authorized_keys.j2 - dest: /root/.ssh/authorized_keys - owner: root - group: root - mode: 0600 - -- name: Enshure sshd is configured correctly - template: - src: sshd_config.j2 - dest: /etc/ssh/sshd_config - owner: root - group: root - mode: 0644 - -- name: Remove default ssh port from UFW - ufw: - rule: allow - port: "22" - proto: tcp - delete: yes - from_ip: "{{ item }}" - loop: "{{ vpn_ips }}" diff --git a/deployment/ansible/roles/common/tasks/ufw.yml b/deployment/ansible/roles/common/tasks/ufw.yml deleted file mode 100644 index 43593a1bb..000000000 --- a/deployment/ansible/roles/common/tasks/ufw.yml +++ /dev/null @@ -1,16 +0,0 @@ -- name: Install ufw - apt: - name: ufw - state: present - -- name: Configure UFW's default outgoing policy - ufw: - default: allow - direction: outgoing -- name: Configure UFW default incoming policy - ufw: - default: deny - direction: incoming -- name: Enable UFW - ufw: - state: disabled # TODO further debug this and activate once fixed diff --git a/deployment/ansible/roles/common/templates/50unattended-upgrades.j2 b/deployment/ansible/roles/common/templates/50unattended-upgrades.j2 deleted file mode 100644 index 466bf417b..000000000 --- a/deployment/ansible/roles/common/templates/50unattended-upgrades.j2 +++ /dev/null @@ -1,143 +0,0 @@ -// Automatically upgrade packages from these (origin:archive) pairs -// -// Note that in Ubuntu security updates may pull in new dependencies -// from non-security sources (e.g. chromium). By allowing the release -// pocket these get automatically pulled in. -Unattended-Upgrade::Allowed-Origins { - "${distro_id}:${distro_codename}"; - "${distro_id}:${distro_codename}-security"; - // Extended Security Maintenance; doesn't necessarily exist for - // every release and this system may not have it installed, but if - // available, the policy for updates is such that unattended-upgrades - // should also install from here by default. - "${distro_id}ESMApps:${distro_codename}-apps-security"; - "${distro_id}ESM:${distro_codename}-infra-security"; - "${distro_id}:${distro_codename}-updates"; -// "${distro_id}:${distro_codename}-proposed"; -// "${distro_id}:${distro_codename}-backports"; -}; - -// Python regular expressions, matching packages to exclude from upgrading -Unattended-Upgrade::Package-Blacklist { - // The following matches all packages starting with linux- -// "linux-"; - - // Use $ to explicitely define the end of a package name. Without - // the $, "libc6" would match all of them. -// "libc6$"; -// "libc6-dev$"; -// "libc6-i686$"; - - // Special characters need escaping -// "libstdc\+\+6$"; - - // The following matches packages like xen-system-amd64, xen-utils-4.1, - // xenstore-utils and libxenstore3.0 -// "(lib)?xen(store)?"; - - // For more information about Python regular expressions, see - // https://docs.python.org/3/howto/regex.html -}; - -// This option controls whether the development release of Ubuntu will be -// upgraded automatically. Valid values are "true", "false", and "auto". -Unattended-Upgrade::DevRelease "auto"; - -// This option allows you to control if on a unclean dpkg exit -// unattended-upgrades will automatically run -// dpkg --force-confold --configure -a -// The default is true, to ensure updates keep getting installed -Unattended-Upgrade::AutoFixInterruptedDpkg "true"; - -// Split the upgrade into the smallest possible chunks so that -// they can be interrupted with SIGTERM. This makes the upgrade -// a bit slower but it has the benefit that shutdown while a upgrade -// is running is possible (with a small delay) -Unattended-Upgrade::MinimalSteps "true"; - -// Install all updates when the machine is shutting down -// instead of doing it in the background while the machine is running. -// This will (obviously) make shutdown slower. -// Unattended-upgrades increases logind's InhibitDelayMaxSec to 30s. -// This allows more time for unattended-upgrades to shut down gracefully -// or even install a few packages in InstallOnShutdown mode, but is still a -// big step back from the 30 minutes allowed for InstallOnShutdown previously. -// Users enabling InstallOnShutdown mode are advised to increase -// InhibitDelayMaxSec even further, possibly to 30 minutes. -//Unattended-Upgrade::InstallOnShutdown "false"; - -// Send email to this address for problems or packages upgrades -// If empty or unset then no email is sent, make sure that you -// have a working mail setup on your system. A package that provides -// 'mailx' must be installed. E.g. "user@example.com" -//Unattended-Upgrade::Mail ""; - -// Set this value to one of: -// "always", "only-on-error" or "on-change" -// If this is not set, then any legacy MailOnlyOnError (boolean) value -// is used to chose between "only-on-error" and "on-change" -//Unattended-Upgrade::MailReport "on-change"; - -// Remove unused automatically installed kernel-related packages -// (kernel images, kernel headers and kernel version locked tools). -Unattended-Upgrade::Remove-Unused-Kernel-Packages "true"; - -// Do automatic removal of newly unused dependencies after the upgrade -Unattended-Upgrade::Remove-New-Unused-Dependencies "true"; - -// Do automatic removal of unused packages after the upgrade -// (equivalent to apt-get autoremove) -//Unattended-Upgrade::Remove-Unused-Dependencies "false"; - -// Automatically reboot *WITHOUT CONFIRMATION* if -// the file /var/run/reboot-required is found after the upgrade -Unattended-Upgrade::Automatic-Reboot "true"; - -// Automatically reboot even if there are users currently logged in -// when Unattended-Upgrade::Automatic-Reboot is set to true -//Unattended-Upgrade::Automatic-Reboot-WithUsers "true"; - -// If automatic reboot is enabled and needed, reboot at the specific -// time instead of immediately -// Default: "now" -Unattended-Upgrade::Automatic-Reboot-Time "05:00"; - -// Use apt bandwidth limit feature, this example limits the download -// speed to 70kb/sec -//Acquire::http::Dl-Limit "70"; - -// Enable logging to syslog. Default is False -// Unattended-Upgrade::SyslogEnable "false"; - -// Specify syslog facility. Default is daemon -// Unattended-Upgrade::SyslogFacility "daemon"; - -// Download and install upgrades only on AC power -// (i.e. skip or gracefully stop updates on battery) -// Unattended-Upgrade::OnlyOnACPower "true"; - -// Download and install upgrades only on non-metered connection -// (i.e. skip or gracefully stop updates on a metered connection) -// Unattended-Upgrade::Skip-Updates-On-Metered-Connections "true"; - -// Verbose logging -// Unattended-Upgrade::Verbose "false"; - -// Print debugging information both in unattended-upgrades and -// in unattended-upgrade-shutdown -// Unattended-Upgrade::Debug "false"; - -// Allow package downgrade if Pin-Priority exceeds 1000 -// Unattended-Upgrade::Allow-downgrade "false"; - -// When APT fails to mark a package to be upgraded or installed try adjusting -// candidates of related packages to help APT's resolver in finding a solution -// where the package can be upgraded or installed. -// This is a workaround until APT's resolver is fixed to always find a -// solution if it exists. (See Debian bug #711128.) -// The fallback is enabled by default, except on Debian's sid release because -// uninstallable packages are frequent there. -// Disabling the fallback speeds up unattended-upgrades when there are -// uninstallable packages at the expense of rarely keeping back packages which -// could be upgraded or installed. -// Unattended-Upgrade::Allow-APT-Mark-Fallback "true"; diff --git a/deployment/ansible/roles/common/templates/authorized_keys.j2 b/deployment/ansible/roles/common/templates/authorized_keys.j2 deleted file mode 100644 index 536215863..000000000 --- a/deployment/ansible/roles/common/templates/authorized_keys.j2 +++ /dev/null @@ -1 +0,0 @@ -ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPh5bjQWc8X1/nhsp5KSFD6VehaRK5qidPxL5JgLOBoX frank@elsinga.com diff --git a/deployment/ansible/roles/common/templates/lrz-base-automatic-reboot.j2 b/deployment/ansible/roles/common/templates/lrz-base-automatic-reboot.j2 deleted file mode 100644 index 64822ca9b..000000000 --- a/deployment/ansible/roles/common/templates/lrz-base-automatic-reboot.j2 +++ /dev/null @@ -1,11 +0,0 @@ -SHELL=/bin/sh -PATH=/usr/sbin:/usr/bin:/sbin:/bin -MAILTO=nomailpls@example.com - -{% with node_id=inventory_hostname | replace('tuzeitm-navigatum-', '') | int %} -{% set reboot_time=node_id + 3%} -# Reboot automatically on working days between {{reboot_time}}:00 and {{reboot_time}}:30 when -# a kernel update has been installed, but not booted into yet - -0 {{reboot_time }} * * Mon-Fri root test -x /usr/sbin/lrz-automatic-reboot && /usr/sbin/lrz-automatic-reboot -D 1800 -{% endwith %} diff --git a/deployment/ansible/roles/common/templates/sshd_config.j2 b/deployment/ansible/roles/common/templates/sshd_config.j2 deleted file mode 100644 index 50312465d..000000000 --- a/deployment/ansible/roles/common/templates/sshd_config.j2 +++ /dev/null @@ -1,122 +0,0 @@ -# This is the sshd server system-wide configuration file. See -# sshd_config(5) for more information. - -# This sshd was compiled with PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games - -# The strategy used for options in the default sshd_config shipped with -# OpenSSH is to specify options with their default value where -# possible, but leave them commented. Uncommented options override the -# default value. - -Include /etc/ssh/sshd_config.d/*.conf - -Port 37670 -AddressFamily inet6 -#ListenAddress 0.0.0.0 -#ListenAddress :: - -#HostKey /etc/ssh/ssh_host_rsa_key -#HostKey /etc/ssh/ssh_host_ecdsa_key -#HostKey /etc/ssh/ssh_host_ed25519_key - -# Ciphers and keying -#RekeyLimit default none - -# Logging -#SyslogFacility AUTH -#LogLevel INFO - -# Authentication: - -#LoginGraceTime 2m -PermitRootLogin yes -#StrictModes yes -#MaxAuthTries 6 -#MaxSessions 10 - -PubkeyAuthentication yes - -# Expect .ssh/authorized_keys2 to be disregarded by default in future. -#AuthorizedKeysFile .ssh/authorized_keys .ssh/authorized_keys2 - -#AuthorizedPrincipalsFile none - -#AuthorizedKeysCommand none -#AuthorizedKeysCommandUser nobody - -# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts -#HostbasedAuthentication no -# Change to yes if you don't trust ~/.ssh/known_hosts for -# HostbasedAuthentication -#IgnoreUserKnownHosts no -# Don't read the user's ~/.rhosts and ~/.shosts files -#IgnoreRhosts yes - -# To disable tunneled clear text passwords, change to no here! -PasswordAuthentication no -#PermitEmptyPasswords no - -# Change to yes to enable challenge-response passwords (beware issues with -# some PAM modules and threads) -#KbdInteractiveAuthentication no - -# Kerberos options -#KerberosAuthentication no -#KerberosOrLocalPasswd yes -#KerberosTicketCleanup yes -#KerberosGetAFSToken no - -# GSSAPI options -#GSSAPIAuthentication no -#GSSAPICleanupCredentials yes -#GSSAPIStrictAcceptorCheck yes -#GSSAPIKeyExchange no - - -# Set this to 'yes' to enable PAM authentication, account processing, -# and session processing. If this is enabled, PAM authentication will -# be allowed through the KbdInteractiveAuthentication and -# PasswordAuthentication. Depending on your PAM configuration, -# PAM authentication via KbdInteractiveAuthentication may bypass -# the setting of "PermitRootLogin without-password". -# If you just want the PAM account and session checks to run without -# PAM authentication, then enable this but set PasswordAuthentication -# and KbdInteractiveAuthentication to 'no'. -# UsePAM yes - -#AllowAgentForwarding yes -#AllowTcpForwarding yes -#GatewayPorts no -X11Forwarding yes -#X11DisplayOffset 10 -#X11UseLocalhost yes -#PermitTTY yes -PrintMotd no -#PrintLastLog yes -#TCPKeepAlive yes -#PermitUserEnvironment no -#Compression delayed -#ClientAliveInterval 0 -#ClientAliveCountMax 3 -#UseDNS no -#PidFile /run/sshd.pid -#MaxStartups 10:30:100 -#PermitTunnel no -#ChrootDirectory none -#VersionAddendum none - -# no default banner path -#Banner none - -# Allow client to pass locale environment variables -AcceptEnv LANG LC_* - -# override default of no subsystems -Subsystem sftp /usr/lib/openssh/sftp-server - -# Example of overriding settings on a per-user basis -#Match User anoncvs -# X11Forwarding no -# AllowTcpForwarding no -# PermitTTY no -# ForceCommand cvs server diff --git a/deployment/ansible/roles/k8s-components/tasks/cert-manager.yml b/deployment/ansible/roles/k8s-components/tasks/cert-manager.yml deleted file mode 100644 index 19da820ab..000000000 --- a/deployment/ansible/roles/k8s-components/tasks/cert-manager.yml +++ /dev/null @@ -1,83 +0,0 @@ ---- -- name: Add jetstack chart repo - kubernetes.core.helm_repository: - name: jetstack - repo_url: "https://charts.jetstack.io" - -- name: Install cert-manager - kubernetes.core.helm: - atomic: true - wait: true - update_repo_cache: yes - release_state: present - chart_ref: jetstack/cert-manager - chart_version: v1.10.0 - name: cert-manager - namespace: cert-manager - create_namespace: yes - values: - installCRDs: true - ingressShim: - defaultIssuerName: letsencrypt-production - defaultIssuerKind: ClusterIssuer - -- name: add letsencrypt-staging ClusterIssuer - kubernetes.core.k8s: - state: present - namespace: default - definition: - apiVersion: cert-manager.io/v1 - kind: ClusterIssuer - metadata: - name: letsencrypt-staging - spec: - acme: - server: https://acme-staging-v02.api.letsencrypt.org/directory - email: navigatum@tum.de - privateKeySecretRef: - name: letsencrypt-account-key-staging - solvers: - - http01: - ingress: - class: traefik - -- name: add letsencrypt-production ClusterIssuer - kubernetes.core.k8s: - state: present - namespace: default - definition: - apiVersion: cert-manager.io/v1 - kind: ClusterIssuer - metadata: - name: letsencrypt-production - spec: - acme: - server: https://acme-v02.api.letsencrypt.org/directory - email: navigatum@tum.de - privateKeySecretRef: - name: letsencrypt-account-key-production - solvers: - - http01: - ingress: - class: traefik - - dns01: - cnameStrategy: Follow - cloudflare: - email: kb@exgen.io - apiTokenSecretRef: - name: tum-sexy-cf-api-token - key: api-key - ingress: - class: traefik - -- name: add selfsigned ClusterIssuer - kubernetes.core.k8s: - state: present - namespace: default - definition: - apiVersion: cert-manager.io/v1 - kind: ClusterIssuer - metadata: - name: selfsigned - spec: - selfSigned: {} diff --git a/deployment/ansible/roles/k8s-components/tasks/components/argocd.yml b/deployment/ansible/roles/k8s-components/tasks/components/argocd.yml deleted file mode 100644 index d55ada4c7..000000000 --- a/deployment/ansible/roles/k8s-components/tasks/components/argocd.yml +++ /dev/null @@ -1,174 +0,0 @@ ---- -- name: Add argo chart repo - kubernetes.core.helm_repository: - name: argo - repo_url: "https://argoproj.github.io/argo-helm" -- name: Install argo-cd - kubernetes.core.helm: - atomic: false - wait: false - update_repo_cache: yes - release_state: present - chart_version: 5.36.11 - chart_ref: argo/argo-cd - name: argo-cd - namespace: argocd - create_namespace: yes - values: - configs: - params: - server.insecure: true - rbac: - policy.csv: | - p, role:image-updater, applications, get, */*, allow - p, role:image-updater, applications, action/apps/Deployment/restart, */*, allow - g, github, role:image-updater - - g, TUM-Dev:Ops, role:admin - policy.default: "role: admin" - cm: - statusbadge.enabled: true - url: https://argocd.nav.tum.sexy - accounts.github: apiKey # we want to be able to restart Deployments automatically - # make shure that we can only log in with github - admin.enabled: false - dex.config: | - connectors: - - type: github - id: github - name: GitHub - config: - clientID: $dex.github.clientID - clientSecret: $dex.github.clientSecret - orgs: - - name: TUM-Dev - teams: - - Ops - notifications: - argocdUrl: https://argocd.nav.tum.sexy - redis-ha: - enabled: true - controller: - replicas: 1 - server: - replicas: 2 - repoServer: - replicas: 2 - applicationSet: - replicaCount: 2 -- name: add an cert for argo - kubernetes.core.k8s: - state: present - namespace: argocd - definition: - apiVersion: cert-manager.io/v1 - kind: Certificate - metadata: - name: argocd.nav.tum.sexy - spec: - commonName: argocd.nav.tum.sexy - dnsNames: - - argocd.nav.tum.sexy - secretName: argocd.nav.tum.sexy - issuerRef: - name: letsencrypt-production - kind: ClusterIssuer - -- name: add an secret for argo - kubernetes.core.k8s: - state: present - namespace: argocd - definition: - apiVersion: v1 - kind: Secret - metadata: - name: argocd-secret - namespace: argocd - labels: - app.kubernetes.io/name: argocd-secret - app.kubernetes.io/part-of: argocd - type: Opaque - data: - dex.github.clientSecret: "{{ lookup('ansible.builtin.password', 'credentials/argocd/github_clientSecret') | b64encode }}" - dex.github.clientID: "{{ lookup('ansible.builtin.password', 'credentials/argocd/github_clientID') | b64encode }}" -- name: add an ingress for argo - kubernetes.core.k8s: - state: present - namespace: argocd - definition: - apiVersion: traefik.containo.us/v1alpha1 - kind: IngressRoute - metadata: - name: argocd-server - spec: - entryPoints: - - websecure - routes: - - kind: Rule - match: Host(`argocd.nav.tum.sexy`) - priority: 10 - services: - - name: argo-cd-argocd-server - port: 80 - - kind: Rule - match: Host(`argocd.nav.tum.sexy`) && Headers(`Content-Type`, `application/grpc`) - priority: 11 - services: - - name: argo-cd-argocd-server - port: 80 - scheme: h2c - tls: - secretName: argocd.nav.tum.sexy -- name: add web ingress - kubernetes.core.k8s: - state: present - namespace: argocd - definition: - apiVersion: traefik.containo.us/v1alpha1 - kind: IngressRoute - metadata: - name: argocd-server-http - spec: - entryPoints: - - web - routes: - - kind: Rule - match: Host(`argocd.nav.tum.sexy`) - services: - - name: noop@internal - kind: TraefikService - middlewares: - - name: https -- name: add http middleware - kubernetes.core.k8s: - state: present - namespace: argocd - definition: - apiVersion: traefik.containo.us/v1alpha1 - kind: Middleware - metadata: - name: https - spec: - redirectScheme: - scheme: https - permanent: true -# The following is a patch to the local-path storage class to allow Immediate binding -# Since StorageClass is a immutable resource, this has to be manually added -#- name: Add the local storage class to allow Immediate binding -# kubernetes.core.k8s: -# state: present -# namespace: kube-system -# definition: -# apiVersion: storage.k8s.io/v1 -# kind: StorageClass -# metadata: -# name: local -# annotations: -# storageclass.kubernetes.io/is-default-class: "false" -# selfLink: /apis/storage.k8s.io/v1/storageclasses/local -# allowedTopologies: [] -# mountOptions: [] -# parameters: {} -# provisioner: rancher.io/local-path -# reclaimPolicy: Delete -# volumeBindingMode: Immediate diff --git a/deployment/ansible/roles/k8s-components/tasks/components/traefik-dashboard.yml b/deployment/ansible/roles/k8s-components/tasks/components/traefik-dashboard.yml deleted file mode 100644 index 15e8913c4..000000000 --- a/deployment/ansible/roles/k8s-components/tasks/components/traefik-dashboard.yml +++ /dev/null @@ -1,94 +0,0 @@ ---- -- name: add a login middleware - kubernetes.core.k8s: - state: present - namespace: kube-system - definition: - apiVersion: traefik.containo.us/v1alpha1 - kind: Middleware - metadata: - name: traefik-auth - spec: - basicAuth: - secret: traefik-login -- name: add a certificate for traefiks dashboard - kubernetes.core.k8s: - state: present - namespace: kube-system - definition: - apiVersion: cert-manager.io/v1 - kind: Certificate - metadata: - name: traefik.nav.tum.sexy - spec: - commonName: traefik.nav.tum.sexy - dnsNames: - - traefik.nav.tum.sexy - secretName: traefik.nav.tum.sexy - issuerRef: - name: letsencrypt-production - kind: ClusterIssuer -- name: add a redirect-to-dashboard middleware - kubernetes.core.k8s: - state: present - namespace: kube-system - definition: - apiVersion: traefik.containo.us/v1alpha1 - kind: Middleware - metadata: - name: redirect-to-dashboard - spec: - redirectRegex: - regex: ^https?://traefik.nav.tum.sexy/(.*) - replacement: https://traefik.nav.tum.sexy/dashboard/ -- name: add an ingress for traefiks dashboard (1/2) - kubernetes.core.k8s: - state: present - namespace: kube-system - definition: - apiVersion: traefik.containo.us/v1alpha1 - kind: IngressRoute - metadata: - name: traefik-dashboard - spec: - entryPoints: - - web - routes: - - match: Host(`traefik.nav.tum.sexy`) - kind: Rule - services: - - name: noop@internal - kind: TraefikService - middlewares: - - name: redirect-to-dashboard -- name: add an ingress for traefiks dashboard (2/2) - kubernetes.core.k8s: - state: present - namespace: kube-system - definition: - apiVersion: traefik.containo.us/v1alpha1 - kind: IngressRoute - metadata: - name: traefik-dashboard-http - spec: - entryPoints: - - websecure - routes: - - match: Host(`traefik.nav.tum.sexy`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`)) - kind: Rule - priority: 10 - services: - - name: api@internal - kind: TraefikService - middlewares: - - name: traefik-auth - - match: Host(`traefik.nav.tum.sexy`) - kind: Rule - priority: 9 - services: - - name: noop@internal - kind: TraefikService - middlewares: - - name: redirect-to-dashboard - tls: - secretName: traefik.nav.tum.sexy diff --git a/deployment/ansible/roles/k8s-components/tasks/components/wiki.yml b/deployment/ansible/roles/k8s-components/tasks/components/wiki.yml deleted file mode 100644 index 1c7fedd5d..000000000 --- a/deployment/ansible/roles/k8s-components/tasks/components/wiki.yml +++ /dev/null @@ -1,91 +0,0 @@ ---- -- name: Add requarks chart repo - kubernetes.core.helm_repository: - name: requarks - repo_url: "https://charts.js.wiki" -- name: Install wikijs - kubernetes.core.helm: - atomic: false - wait: false - update_repo_cache: yes - release_state: present - chart_version: 2.2.0 - chart_ref: requarks/wiki - name: wiki - namespace: wiki - create_namespace: yes - values: - ingress: - enabled: false - -- name: add an cert for wikijs - kubernetes.core.k8s: - state: present - namespace: wiki - definition: - apiVersion: cert-manager.io/v1 - kind: Certificate - metadata: - name: wiki.nav.tum.sexy - spec: - commonName: wiki.nav.tum.sexy - dnsNames: - - wiki.nav.tum.sexy - secretName: wiki.nav.tum.sexy - issuerRef: - name: letsencrypt-production - kind: ClusterIssuer - -- name: add an ingress for wikijs - kubernetes.core.k8s: - state: present - namespace: wiki - definition: - apiVersion: traefik.containo.us/v1alpha1 - kind: IngressRoute - metadata: - name: wiki - spec: - entryPoints: - - websecure - routes: - - kind: Rule - match: Host(`wiki.nav.tum.sexy`) - services: - - name: wiki - port: 80 - tls: - secretName: wiki.nav.tum.sexy -- name: add web ingress - kubernetes.core.k8s: - state: present - namespace: wiki - definition: - apiVersion: traefik.containo.us/v1alpha1 - kind: IngressRoute - metadata: - name: wiki-http - spec: - entryPoints: - - web - routes: - - kind: Rule - match: Host(`wiki.nav.tum.sexy`) - services: - - name: noop@internal - kind: TraefikService - middlewares: - - name: https -- name: add http middleware - kubernetes.core.k8s: - state: present - namespace: wiki - definition: - apiVersion: traefik.containo.us/v1alpha1 - kind: Middleware - metadata: - name: https - spec: - redirectScheme: - scheme: https - permanent: true diff --git a/deployment/ansible/roles/k8s-components/tasks/longhorn.yml b/deployment/ansible/roles/k8s-components/tasks/longhorn.yml deleted file mode 100644 index b9f54a9d3..000000000 --- a/deployment/ansible/roles/k8s-components/tasks/longhorn.yml +++ /dev/null @@ -1,17 +0,0 @@ ---- -- name: Add longhorn chart repo - kubernetes.core.helm_repository: - name: longhorn - repo_url: "https://charts.longhorn.io" - -- name: Install longhorn - kubernetes.core.helm: - atomic: true - wait: true - update_repo_cache: yes - release_state: present - chart_ref: longhorn/longhorn - chart_version: 1.4.1 - name: longhorn - namespace: longhorn-system - create_namespace: yes diff --git a/deployment/ansible/roles/k8s-components/tasks/main.yml b/deployment/ansible/roles/k8s-components/tasks/main.yml deleted file mode 100644 index e2ebab403..000000000 --- a/deployment/ansible/roles/k8s-components/tasks/main.yml +++ /dev/null @@ -1,28 +0,0 @@ ---- -# -# Tasks to be applied to the cluster, but not nessesarily to the master -# -- name: Install the python kubernetes package (needed for ansible to controll kubernetes) - pip: - name: kubernetes - state: present - -- name: Setup cert-manager - include_tasks: cert-manager.yml - -- name: Setup longhorn - include_tasks: longhorn.yml - -- name: Setup the various monitoring compontentes (no order) - include_tasks: "{{ comp }}" - loop_control: - loop_var: comp - with_fileglob: - - monitoring/*.yml - -- name: Setup the various k3s compontentes (no order) - include_tasks: "{{ comp }}" - loop_control: - loop_var: comp - with_fileglob: - - components/*.yml diff --git a/deployment/ansible/roles/k8s-components/tasks/monitoring/fairlight.yml b/deployment/ansible/roles/k8s-components/tasks/monitoring/fairlight.yml deleted file mode 100644 index 8c96cd9be..000000000 --- a/deployment/ansible/roles/k8s-components/tasks/monitoring/fairlight.yml +++ /dev/null @@ -1,54 +0,0 @@ ---- -- name: Add fairwinds-stable chart repo - kubernetes.core.helm_repository: - name: fairwinds-stable - repo_url: "https://charts.fairwinds.com/stable" - -- name: Install insights-agent - kubernetes.core.helm: - atomic: true - wait: false - update_repo_cache: yes - release_state: present - chart_version: 2.20.* - chart_ref: fairwinds-stable/insights-agent - name: insights-agent - namespace: insights-agent - create_namespace: yes - values: - insights: - organization: "tumzitm" - cluster: "tumzitm" - base64token: "cWJmMlFKdmdBVmdtTTFndzBlYllHcEdUTmR3SEo2Y1Vya0s1My1HNHBtRThZcHUxZ1FRcDY3RG5XR2pJRHI5Sg==" - secret: - create: true - nova: - enabled: true - opa: - enabled: true - pluto: - enabled: true - polaris: # non debuggable failiour - enabled: false - kube-bench: - enabled: false - mode: daemonset - trivy: - enabled: true - maxConcurrentScans: 2 - maxScansPerRun: 50 - goldilocks: - enabled: true - dashboard: - enabled: true - workloads: # non debuggable failiour - enabled: false - kube-hunter: - enabled: true - rbac-reporter: # non debuggable failiour - enabled: false - prometheus-metrics: - enabled: true - address: http://prometheus-operated.monitoring.svc.cluster.local:9090 # TODO: change once grafana cloud is ready - admission: - enabled: true diff --git a/deployment/ansible/roles/k8s-components/tasks/monitoring/pushgateway.yml b/deployment/ansible/roles/k8s-components/tasks/monitoring/pushgateway.yml deleted file mode 100644 index 17c81392a..000000000 --- a/deployment/ansible/roles/k8s-components/tasks/monitoring/pushgateway.yml +++ /dev/null @@ -1,31 +0,0 @@ ---- -- name: Add prometheus-community chart repo - kubernetes.core.helm_repository: - name: prometheus-community - repo_url: https://prometheus-community.github.io/helm-charts - -- name: Install prometheus-pushgateway - kubernetes.core.helm: - atomic: true - wait: false - update_repo_cache: yes - release_state: present - chart_version: 2.1.6 - chart_ref: prometheus-community/prometheus-pushgateway - name: prometheus-pushgateway - namespace: monitoring - create_namespace: yes - values: - resources: - limits: - cpu: 200m - memory: 50Mi - requests: - cpu: 100m - memory: 30Mi - serviceMonitor: - enabled: true - persistentVolume: - enabled: true - size: 2Gi - storageClass: "longhorn" diff --git a/deployment/ansible/roles/k8s/tasks/install/helm.yml b/deployment/ansible/roles/k8s/tasks/install/helm.yml deleted file mode 100644 index e01734804..000000000 --- a/deployment/ansible/roles/k8s/tasks/install/helm.yml +++ /dev/null @@ -1,15 +0,0 @@ ---- -- name: Install helm - shell: curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash -- name: Dump kubectl's kubeconfig to .kube/config (otherwise helm wont know where to connect) - shell: - cmd: "kubectl config view --raw >~/.kube/config && chmod 600 ~/.kube/config" - creates: ~/.kube/config -- name: make shure that the helm diff plugin is instaled - kubernetes.core.helm_plugin: - plugin_path: https://github.com/databus23/helm-diff - state: present -- name: make shure that the helm diff plugin is up to date - kubernetes.core.helm_plugin: - plugin_name: diff - state: latest diff --git a/deployment/ansible/roles/k8s/tasks/install/k3s.yml b/deployment/ansible/roles/k8s/tasks/install/k3s.yml deleted file mode 100644 index 37167da38..000000000 --- a/deployment/ansible/roles/k8s/tasks/install/k3s.yml +++ /dev/null @@ -1,81 +0,0 @@ ---- -- name: make shure /etc/rancher/k3s/config.yaml includes all the limits we want - template: - src: config.yaml.j2 - dest: /etc/rancher/k3s/config.yaml - owner: root - group: root - mode: 0644 - -- name: Install k3s - shell: > - curl -sfL https://get.k3s.io | sh -s - - --cluster-init - --tls-san {{ loadbalancer_ipv4 }} - --tls-san {{ loadbalancer_ipv6 }} - --tls-san controlplane.nav.tum.sexy - --node-ip {{ ansible_host_v4 }} - --node-external-ip {{ ansible_host_v4 }} - environment: - K3S_TOKEN: "{{ lookup('ansible.builtin.password', 'credentials/k3s_token length=1024') }}" - K3S_NODE_NAME: "eliza-{{ 2 + inventory_hostname | replace('tuzeitm-navigatum-', '') | int }}" - # ipv6 dual stack - K3S_CLUSTER_CIDR: "{{ cluster_cidr }}" - K3S_SERVICE_CIDR: "{{ service_cidr }}" - when: inventory_hostname == 'tuzeitm-navigatum-1' - -- name: Wait for the k3s service to be running - wait_for: - port: 6443 - state: started - timeout: 300 - delay: 5 - when: inventory_hostname == 'tuzeitm-navigatum-1' - -- name: Install k3s - shell: > - curl -sfL https://get.k3s.io | sh -s - - --server https://[{{ etcd_leader_ip }}]:6443 - --tls-san {{ loadbalancer_ipv4 }} - --tls-san {{ loadbalancer_ipv6 }} - --tls-san controlplane.nav.tum.sexy - --node-ip {{ ansible_host_v4 }} - --node-external-ip {{ ansible_host_v4 }} - environment: - K3S_TOKEN: "{{ lookup('ansible.builtin.password', 'credentials/k3s_token length=1024') }}" - K3S_NODE_NAME: "eliza-{{ 2 + inventory_hostname | replace('tuzeitm-navigatum-', '') | int }}" - # ipv6 dual stack - K3S_CLUSTER_CIDR: "{{ cluster_cidr }}" - K3S_SERVICE_CIDR: "{{ service_cidr }}" - when: inventory_hostname == 'tuzeitm-navigatum-2' -- name: Wait for the k3s service to be running - wait_for: - port: 6443 - state: started - timeout: 300 - delay: 5 - when: inventory_hostname == 'tuzeitm-navigatum-2' - -- name: Install k3s - shell: > - curl -sfL https://get.k3s.io | sh -s - - --server https://[{{ etcd_leader_ip }}]:6443 - --tls-san {{ loadbalancer_ipv4 }} - --tls-san {{ loadbalancer_ipv6 }} - --tls-san controlplane.nav.tum.sexy - --node-ip {{ ansible_host_v4 }} - --node-external-ip {{ ansible_host_v4 }} - environment: - K3S_TOKEN: "{{ lookup('ansible.builtin.password', 'credentials/k3s_token length=1024') }}" - K3S_NODE_NAME: "eliza-{{ 2 + inventory_hostname | replace('tuzeitm-navigatum-', '') | int }}" - # ipv6 dual stack - K3S_CLUSTER_CIDR: "{{ cluster_cidr }}" - K3S_SERVICE_CIDR: "{{ service_cidr }}" - when: inventory_hostname == 'tuzeitm-navigatum-3' -- name: Wait for the k3s service to be running - wait_for: - port: 6443 - state: started - timeout: 300 - delay: 5 - when: inventory_hostname == 'tuzeitm-navigatum-3' diff --git a/deployment/ansible/roles/k8s/tasks/install/longhorn-requirements.yml b/deployment/ansible/roles/k8s/tasks/install/longhorn-requirements.yml deleted file mode 100644 index d6d999fb5..000000000 --- a/deployment/ansible/roles/k8s/tasks/install/longhorn-requirements.yml +++ /dev/null @@ -1,15 +0,0 @@ ---- -- name: Install longhorn requirements - apt: - name: "{{ item }}" - state: present - with_items: - - nfs-common - - open-iscsi - - bash - - curl - - jq -- name: make shure that modules are loaded - modprobe: - name: iscsi_tcp - state: present diff --git a/deployment/ansible/roles/k8s/tasks/main.yml b/deployment/ansible/roles/k8s/tasks/main.yml deleted file mode 100644 index d866c16ed..000000000 --- a/deployment/ansible/roles/k8s/tasks/main.yml +++ /dev/null @@ -1,19 +0,0 @@ ---- -# -# Tasks to be applied to all k8s instances -# - -- name: Setup k3s networking - include_tasks: network.yml -# Remove k3s via -#- name: remove k3s -# shell: /usr/local/bin/k3s-uninstall.sh && rm ~/.kube/config -- name: Setup k3s - include_tasks: install/k3s.yml - -# setup infrastructure to install packages to k8s -- name: Setup helm - include_tasks: install/helm.yml - -- name: Setup longhorn requirements - include_tasks: install/longhorn-requirements.yml diff --git a/deployment/ansible/roles/k8s/tasks/network.yml b/deployment/ansible/roles/k8s/tasks/network.yml deleted file mode 100644 index fa39ac9d8..000000000 --- a/deployment/ansible/roles/k8s/tasks/network.yml +++ /dev/null @@ -1,53 +0,0 @@ ---- -# ufw setup -- name: Configure http(s) in UFW - ufw: - direction: in - rule: allow - port: "{{ item.port }}" - proto: "{{ item.proto }}" - comment: "{{ item.comment }}" - with_items: - - { port: 80, proto: any, comment: "HTTP" } - - { port: 443, proto: any, comment: "HTTPS" } -- name: Allow the LB to check if k8s is online - ufw: - direction: in - rule: allow - proto: "any" - port: "6443" - from_ip: "{{ item.ip }}" - comment: "{{ item.comment }}" - with_items: - - { ip: 129.187.255.244, comment: "LRZ LB" } - - { ip: 129.187.255.245, comment: "LRZ LB" } - -- name: Configure the api server (VPN) in UFW - ufw: - direction: in - rule: allow - port: "6443" - proto: "tcp" - from_ip: "{{ item }}" - comment: "Kubernetes Controllplane (API) from VPN" - loop: "{{ vpn_ips }}" - -- name: Configure the api server (cluster) in UFW - ufw: - direction: in - rule: allow - port: "{{ item[1] }}" - proto: "tcp" - from_ip: "{{ item[0] }}" - comment: "Kubernetes Controllplane (API+Metrics) from cluster" - loop: "{{ leader_ips | product([6443, 10250]) | list }}" - -- name: Configure in-cluster etcd 2379 in UFW - ufw: - direction: in - rule: allow - port: "{{item[1]}}" - proto: "tcp" - from_ip: "{{ item[0] }}" - comment: "k3s HA with embedded etcd from cluster" - loop: "{{ leader_ips | product([2379, 2380]) | list }}" diff --git a/deployment/ansible/roles/k8s/templates/config.yaml.j2 b/deployment/ansible/roles/k8s/templates/config.yaml.j2 deleted file mode 100644 index 2c604fc80..000000000 --- a/deployment/ansible/roles/k8s/templates/config.yaml.j2 +++ /dev/null @@ -1,3 +0,0 @@ -kubelet-arg: - - "image-gc-high-threshold=60" - - "image-gc-low-threshold=40" diff --git a/deployment/ansible/site.yml b/deployment/ansible/site.yml deleted file mode 100644 index 159d42418..000000000 --- a/deployment/ansible/site.yml +++ /dev/null @@ -1,11 +0,0 @@ ---- -- hosts: - - leader - - followers - roles: - - common - - k8s -- hosts: - - localhost - roles: - - k8s-components diff --git a/deployment/k3s/files/maps/osm-liberty.json b/deployment/k3s/files/osm-liberty.json similarity index 100% rename from deployment/k3s/files/maps/osm-liberty.json rename to deployment/k3s/files/osm-liberty.json diff --git a/deployment/k3s/templates/deployments/calendar/calendar-deployment.yaml b/deployment/k3s/templates/deployments/calendar/calendar-deployment.yaml index 5c9eb2302..2d3fefd24 100644 --- a/deployment/k3s/templates/deployments/calendar/calendar-deployment.yaml +++ b/deployment/k3s/templates/deployments/calendar/calendar-deployment.yaml @@ -32,7 +32,7 @@ spec: imagePullPolicy: Always command: ["/bin/navigatum-calendar"] ports: - - containerPort: 8060 + - containerPort: 3005 name: calendar env: - name: POSTGRES_URL diff --git a/deployment/k3s/templates/deployments/data-deployment.yaml b/deployment/k3s/templates/deployments/data-deployment.yaml index 800af8c4b..43ecf5167 100644 --- a/deployment/k3s/templates/deployments/data-deployment.yaml +++ b/deployment/k3s/templates/deployments/data-deployment.yaml @@ -30,7 +30,7 @@ spec: image: "ghcr.io/tum-dev/navigatum-data:{{ $.Values.tag }}" imagePullPolicy: Always ports: - - containerPort: 8000 + - containerPort: 3002 name: http resources: requests: diff --git a/deployment/k3s/templates/deployments/feedback-deployment.yaml b/deployment/k3s/templates/deployments/feedback-deployment.yaml index b16b9c531..db539a31f 100644 --- a/deployment/k3s/templates/deployments/feedback-deployment.yaml +++ b/deployment/k3s/templates/deployments/feedback-deployment.yaml @@ -26,7 +26,7 @@ spec: {{- if eq "nav.tum.de" $.Values.url }} annotations: prometheus.io/path: /metrics - prometheus.io/port: '8070' + prometheus.io/port: '3004' prometheus.io/scrape: 'true' {{- end }} spec: @@ -56,7 +56,7 @@ spec: name: feedback-api-keys # GITHUB_TOKEN, JWT_KEY {{ end }} ports: - - containerPort: 8070 + - containerPort: 3004 name: feedback securityContext: allowPrivilegeEscalation: false diff --git a/deployment/k3s/templates/deployments/server-deployment.yaml b/deployment/k3s/templates/deployments/server-deployment.yaml index 3f0e6ceef..7aca8ca5e 100644 --- a/deployment/k3s/templates/deployments/server-deployment.yaml +++ b/deployment/k3s/templates/deployments/server-deployment.yaml @@ -45,7 +45,7 @@ spec: - name: DB_LOCATION value: api_data.db ports: - - containerPort: 8080 + - containerPort: 3003 name: api securityContext: allowPrivilegeEscalation: false diff --git a/deployment/k3s/templates/deployments/webclient-deployment.yaml b/deployment/k3s/templates/deployments/webclient-deployment.yaml index b37151c91..067c31d55 100644 --- a/deployment/k3s/templates/deployments/webclient-deployment.yaml +++ b/deployment/k3s/templates/deployments/webclient-deployment.yaml @@ -30,7 +30,7 @@ spec: image: "ghcr.io/tum-dev/navigatum-webclient:{{ $.Values.tag }}" imagePullPolicy: Always ports: - - containerPort: 9000 + - containerPort: 3000 name: webclient resources: requests: diff --git a/deployment/k3s/templates/networking/ingress.yaml b/deployment/k3s/templates/networking/ingress.yaml index 4e1cf191f..0082e2417 100644 --- a/deployment/k3s/templates/networking/ingress.yaml +++ b/deployment/k3s/templates/networking/ingress.yaml @@ -13,17 +13,17 @@ spec: match: Host(`{{ $.Values.url }}`) && PathPrefix(`/api/feedback/`) services: - name: feedback-svc - port: 8070 + port: 3004 - kind: Rule match: Host(`{{ $.Values.url }}`) && PathPrefix(`/api/calendar/`) services: - name: calendar-svc - port: 8060 + port: 3005 - kind: Rule match: Host(`{{ $.Values.url }}`) && PathPrefix(`/api/`) services: - name: api-svc - port: 7000 + port: 3003 - kind: Rule match: Host(`{{ $.Values.url }}`) && PathPrefix(`/maps/vol/`) services: @@ -33,7 +33,7 @@ spec: match: Host(`{{ $.Values.url }}`) && PathPrefix(`/maps/`) services: - name: maps-svc - port: 7770 + port: 3001 middlewares: - name: stripprefix - name: cache-2-months @@ -41,14 +41,14 @@ spec: match: Host(`{{ $.Values.url }}`) && PathPrefix(`/cdn/`) services: - name: cdn-svc - port: 8000 + port: 3002 middlewares: - name: stripprefix - kind: Rule match: Host(`{{ $.Values.url }}`) services: - name: webclient-svc - port: 9000 + port: 3000 - kind: Rule match: Host(`nav.tum.sexy`) || Host(`www.nav.tum.de`) services: diff --git a/deployment/k3s/templates/networking/service.yaml b/deployment/k3s/templates/networking/service.yaml index 07698c328..869bd1bcf 100644 --- a/deployment/k3s/templates/networking/service.yaml +++ b/deployment/k3s/templates/networking/service.yaml @@ -13,8 +13,8 @@ spec: app.kubernetes.io/name: api ports: - name: http - port: 7000 - targetPort: 8080 + port: 3003 + targetPort: 3003 --- apiVersion: v1 kind: Service @@ -31,8 +31,8 @@ spec: app.kubernetes.io/name: feedback ports: - name: http - port: 8070 - targetPort: 8070 + port: 3004 + targetPort: 3004 --- apiVersion: v1 kind: Service @@ -49,8 +49,8 @@ spec: app.kubernetes.io/name: calendar ports: - name: http - port: 8060 - targetPort: 8060 + port: 3005 + targetPort: 3005 --- apiVersion: v1 kind: Service @@ -67,7 +67,7 @@ spec: app.kubernetes.io/name: maps ports: - name: http - port: 7770 + port: 3001 targetPort: 8080 - name: src port: 7771 @@ -88,8 +88,8 @@ spec: app.kubernetes.io/name: cdn ports: - name: http - port: 8000 - targetPort: 8000 + port: 3002 + targetPort: 3002 --- apiVersion: v1 kind: Service @@ -106,8 +106,8 @@ spec: app.kubernetes.io/name: web ports: - name: http - port: 9000 - targetPort: 9000 + port: 3000 + targetPort: 3000 {{- if eq "nav.tum.de" $.Values.url }} --- apiVersion: v1 diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 000000000..e091bc090 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,136 @@ +services: + webclient: + image: ghcr.io/tum-dev/navigatum-webclient:latest + restart: always + build: ./webclient + ports: + - "3000:3000" + # maps + tileserver-init-sprites: + image: alpine:latest + restart: on-failure + command: + - sh + - -c + - "mkdir -p /sprites/ && rm -f /sprites/* && wget -P /sprites ${TILE_SPRITES_URL}/osm-liberty.json ${TILE_SPRITES_URL}/osm-liberty@2x.json ${TILE_SPRITES_URL}/osm-liberty.png ${TILE_SPRITES_URL}/osm-liberty@2x.png" + volumes: + - tileserver-sprites:/sprites + tileserver-init-src: + image: alpine:latest + restart: on-failure + command: wget -P /map --continue https://nav.tum.de/maps/vol/output.mbtiles + volumes: + - ./map:/map + tileserver: + image: maptiler/tileserver-gl:latest + restart: always + command: /usr/src/app/docker-entrypoint.sh --public_url=https://nav.tum.de/maps/ + tmpfs: + - /tmp + volumes: + - ./deployment/k3s/files/osm-liberty.json:/data/styles/osm-liberty.json:ro + - ./map/tileserver-config.json:/data/config.json:ro + - tileserver-sprites:/data/sprites:ro + - tileserver-fonts:/data/fonts:ro + - ./map/output.mbtiles:/data/output.mbtiles:ro + read_only: true + ports: + - "3001:8080" + depends_on: + tileserver-init-sprites: + condition: service_completed_successfully + tileserver-init-src: + condition: service_completed_successfully + # cdn + data: + image: ghcr.io/tum-dev/navigatum-cdn:latest + restart: always + build: ./data + ports: + - "3002:3002" + # server + main-api: + image: ghcr.io/tum-dev/navigatum-main-api:latest + restart: always + build: ./server + command: /bin/navigatum-main-api + ports: + - "3003:3003" + volumes: + - type: tmpfs + target: /home/navigatum/.cache + user: 1000:3000 + environment: + MIELI_URL: http://meilisearch:7700 + depends_on: + meilisearch: + condition: service_healthy + healthcheck: + test: wget -q --spider http://localhost:3003/api/status + retries: 5 + interval: 10s + start_period: 30s + meilisearch: + image: getmeili/meilisearch:v1.4.1 + restart: always + healthcheck: + test: wget -q --spider http://localhost:7700/health + retries: 5 + interval: 10s + start_period: 10s + feedback-api: + image: ghcr.io/tum-dev/navigatum-server:latest + restart: always + build: ./server + command: /bin/navigatum-feedback + ports: + - "3004:3004" + healthcheck: + test: wget -q --spider http://localhost:3004/api/feedback/status + retries: 5 + start_period: 10s + calendar-api: + image: ghcr.io/tum-dev/navigatum-server:latest + restart: always + build: ./server + command: /bin/navigatum-calendar + environment: + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + POSTGRES_USER: ${POSTGRES_USER} + POSTGRES_DB: ${POSTGRES_DB} + POSTGRES_URL: postgres:5432 + depends_on: + db: + condition: service_healthy + ports: + - "3005:3005" + healthcheck: + test: wget -q --spider http://localhost:3005/api/calendar/status + retries: 5 + start_period: 10s + db: + image: postgres:15 + restart: unless-stopped + environment: + PGDATA: /var/lib/postgresql/data/pgdata + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + POSTGRES_USER: ${POSTGRES_USER} + POSTGRES_DB: ${POSTGRES_DB} + volumes: + - postgres-data:/var/lib/postgresql/data + healthcheck: + test: ["CMD", "pg_isready", "-U", "${POSTGRES_USER}"] + retries: 5 + interval: 10s + start_period: 10s + + +volumes: + db-data: + driver: local + tileserver-sprites: + driver: local + tileserver-fonts: + driver: local + postgres-data: + driver: local diff --git a/map/.gitignore b/map/.gitignore index aeef35d1e..903fe6078 100644 --- a/map/.gitignore +++ b/map/.gitignore @@ -1,3 +1,5 @@ -output.mbtiles +output.mbtiles* +tile_weights.tsv.gz sources/ tmp/ +data/ diff --git a/map/README.md b/map/README.md index 4a24193cb..9587af60f 100644 --- a/map/README.md +++ b/map/README.md @@ -11,7 +11,7 @@ A tileserver takes these two components and produces a variety of formats (png, ### generate your own tileset -Sadly tilesets are really large (`europe` is ca. 30GB, `planet` ca. 80GB). +Sadly tilesets are really large (`germany` is ~10GB, `planet` ~90GB). Because of limited badwith and storage space we can't provide a tileset for everyone. You can generate your own tileset from [OpenStreetMap Data](https://osmdata.openstreetmap.de/) via [planettiler](https://github.com/onthegomap/planetiler) or other equivalent tools. @@ -24,24 +24,11 @@ Generating `europe` takes 3h10m on a modern laptop with 32GB RAM and an SSD. The From the root of the repository, run: ```bash -docker run -it -e JAVA_TOOL_OPTIONS="-Xmx10g" -v "$(pwd)/map":/data ghcr.io/onthegomap/planetiler:latest --download --area=europe --languages=de,en --Xmx10g --storage=mmap +docker run -it -e JAVA_TOOL_OPTIONS="-Xmx10g" -v "$(pwd)/map":/data ghcr.io/onthegomap/planetiler:latest --download --area=bavaria --languages=de,en --Xmx10g --storage=mmap ``` For `planet`, you might want to increase the `--Xmx` parameter to 20GB. For 128GB of RAM or more you will want to use `--storage=ram` instead of `--storage=mmap`. -### Copy the currently deployed style - -```bash -cp config.json ../deployment/k3s/files/maps/config.json -``` - -### Copy the currently deployed configuration - -```bash -mkdir -p styles -cp styles/osm-liberty.json ../deployment/k3s/files/maps/osm-liberty.json -``` - ### Serve the tileset After generating `output.mbtiles` you can serve it with a tileserver. @@ -51,7 +38,7 @@ This may be one optimisation point in the future. From the root of the repository, run: ```bash -docker run --rm -it -v $(pwd)/map:/data -p 7770:80 maptiler/tileserver-gl +docker compose up --build ``` ### Edit the style @@ -60,31 +47,17 @@ For editing the style we use [Maputnik](https://github.com/maputnik/editor). It is a web-based editor for Maplibre styles. You can use it to edit the style and see the changes live. -Sadly, it is not fully compatible with tileserver-gl. - -While maputnik expects the data on an url, tileserver-gl expects it to be a file. -More concretely, maputnik expects this: - -```json -{ -"openmaptiles": { - "type": "vector", - "url": "http://localhost:7770/data/openmaptiles.json" -}, -... -} -``` - -tileserver-gl expects this +> [!NOTE] +> Maputnik is not fully compatible with tileserver-gl +> Maputnik expects the data on an url, tileserver-gl expects it to be a file. +> For maputnik to accept the file, you need to do the following: -```json -{ +```diff "openmaptiles": { "type": "vector", - "url": "mbtiles://output.mbtiles" +- "url": "mbtiles://output.mbtiles" ++ "url": "http://localhost:7770/data/openmaptiles.json" }, -... -} ``` To edit the style you thus need to run maputnik and tileserver-gl at the same time. @@ -95,7 +68,9 @@ You cannot preview the style in tileserver-gl, but you can see the changes in ma docker run -it --rm -p 8888:8888 maputnik/editor ``` -![Where in Maputnik to click to import a style](/resources/documentation/maputnik-import1.png) -![Where in Maputnik to click then to import a style](/resources/documentation/maputnik-import2.png) +> [!WARNING] +> After exporting the edited style don't forget to revert the change to the vector url 😉 -After exporting the edited style don't forget to revert the change to the vector url 😉 +| Step 1 | Step 2 | +|------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------| +| ![Where in Maputnik to click to import a style](/resources/documentation/maputnik-import1.png) | ![Where in Maputnik to click then to import a style](/resources/documentation/maputnik-import2.png) | diff --git a/map/tileserver-config.json b/map/tileserver-config.json new file mode 100644 index 000000000..dbc331285 --- /dev/null +++ b/map/tileserver-config.json @@ -0,0 +1,44 @@ +{ + "options": { + "paths": { + "root": "", + "fonts": "fonts", + "sprites": "sprites", + "styles": "styles", + "mbtiles": "" + }, + "domains": [ + "nav.tum.de", + "localhost:8080", + "127.0.0.1:8080" + ], + "formatQuality": { + "jpeg": 80, + "webp": 90 + }, + "maxScaleFactor": 2, + "minRendererPoolSizes": [2, 4], + "maxRendererPoolSizes": [2, 4], + "maxSize": 2048, + "pbfAlias": "pbf", + "serveAllFonts": true, + "serveAllStyles": true, + "serveStaticMaps": true, + "tileMargin": 0 + }, + "styles": { + "osm-liberty": { + "style": "osm-liberty.json", + "serve_rendered": true, + "serve_data": true, + "tilejson": { + "format": "png" + } + } + }, + "data": { + "openmaptiles": { + "mbtiles": "output.mbtiles" + } + } +} diff --git a/server/calendar/src/main.rs b/server/calendar/src/main.rs index d9c23fa0d..f26aa1bae 100644 --- a/server/calendar/src/main.rs +++ b/server/calendar/src/main.rs @@ -6,7 +6,12 @@ mod utils; use actix_cors::Cors; use actix_web::{get, middleware, web, App, HttpResponse, HttpServer}; use actix_web_prom::PrometheusMetricsBuilder; +use diesel_migrations::{embed_migrations, EmbeddedMigrations, MigrationHarness}; +use log::info; use std::collections::HashMap; +use std::error::Error; +use structured_logger::async_json::new_writer; +use structured_logger::Builder; const MAX_JSON_PAYLOAD: usize = 1024 * 1024; // 1 MB @@ -21,24 +26,22 @@ async fn health_status_handler() -> HttpResponse { .body(format!("healthy\nsource_code: {github_link}")) } -use diesel_migrations::{embed_migrations, EmbeddedMigrations, MigrationHarness}; -use structured_logger::async_json::new_writer; -use structured_logger::Builder; - pub const MIGRATIONS: EmbeddedMigrations = embed_migrations!("migrations"); -fn apply_db_migrations() { +fn apply_db_migrations() -> Result<(), Box> { + info!("Applying database migrations"); let con = &mut utils::establish_connection(); - con.run_pending_migrations(MIGRATIONS) - .expect("Migrations could not be applied"); + con.run_pending_migrations(MIGRATIONS)?; + info!("database migrations applied"); + Ok(()) } -#[actix_web::main] -async fn main() -> std::io::Result<()> { +#[tokio::main] +async fn main() -> Result<(), Box> { Builder::with_level("info") .with_target_writer("*", new_writer(tokio::io::stdout())) .init(); - apply_db_migrations(); + apply_db_migrations()?; // metrics let labels = HashMap::from([( @@ -67,7 +70,8 @@ async fn main() -> std::io::Result<()> { .service(health_status_handler) .service(calendar::calendar_handler) }) - .bind(std::env::var("BIND_ADDRESS").unwrap_or_else(|_| "0.0.0.0:8060".to_string()))? + .bind(std::env::var("BIND_ADDRESS").unwrap_or_else(|_| "0.0.0.0:3005".to_string()))? .run() - .await + .await?; + Ok(()) } diff --git a/server/feedback/README.md b/server/feedback/README.md index bdda70d6d..25b7831df 100644 --- a/server/feedback/README.md +++ b/server/feedback/README.md @@ -19,7 +19,7 @@ The following environment variables are required for all features to work: | `JWT_KEY` | A key used to sign JWTs. This is used to authenticate that feedback tokens were given out by us. | Run `cargo run` to start the server. -The server should now be available on `localhost:8070`. +The server should now be available on `localhost:3004`. Note that `cargo run --release` is used to start the server for an optimised production build (use this if you want to profile performance, it makes quite a difference). @@ -43,11 +43,11 @@ To make sure that this specification is up-to-date and without holes, we run [sc python -m venv venv source venv/bin/activate pip install schemathesis -st run --workers=auto --base-url=http://localhost:8070 --checks=all ../openapi.yaml +st run --workers=auto --base-url=http://localhost:3004 --checks=all ../openapi.yaml ``` Some fuzzing-goals may not be available for you locally, as they require prefix-routing (f.ex.`/cdn` to the CDN) and some fuzzing-goals are automatically tested in our CI. -You can exchange `--base-url=http://localhost:8070` to `--base-url=https://nav.tum.sexy` for the full public API, or restrict your scope using a option like `--endpoint=/api/feedback/`. +You can exchange `--base-url=http://localhost:3004` to `--base-url=https://nav.tum.sexy` for the full public API, or restrict your scope using a option like `--endpoint=/api/feedback/`. ## License diff --git a/server/feedback/src/main.rs b/server/feedback/src/main.rs index 6ae4e8026..40eae54b1 100644 --- a/server/feedback/src/main.rs +++ b/server/feedback/src/main.rs @@ -74,7 +74,7 @@ async fn main() -> std::io::Result<()> { .route("", web::post().to(tokens::get_token)), ) }) - .bind(std::env::var("BIND_ADDRESS").unwrap_or_else(|_| "0.0.0.0:8070".to_string()))? + .bind(std::env::var("BIND_ADDRESS").unwrap_or_else(|_| "0.0.0.0:3004".to_string()))? .run() .await } diff --git a/server/main-api/src/main.rs b/server/main-api/src/main.rs index 38c774e49..bec3932c4 100644 --- a/server/main-api/src/main.rs +++ b/server/main-api/src/main.rs @@ -1,7 +1,6 @@ use actix_cors::Cors; use actix_web::{get, middleware, web, App, HttpResponse, HttpServer}; use actix_web_prom::PrometheusMetricsBuilder; -use futures::try_join; use log::{debug, info}; use std::collections::HashMap; use structured_logger::async_json::new_writer; @@ -33,11 +32,10 @@ async fn main() -> Result<(), Box> { Builder::with_level("info") .with_target_writer("*", new_writer(tokio::io::stdout())) .init(); - info!("setting up dependency's"); - try_join!( - setup::meilisearch::setup_meilisearch(), - setup::database::setup_database(), - )?; + info!("setting up meilisearch"); + setup::meilisearch::setup_meilisearch().await?; + info!("setting up the database"); + setup::database::setup_database().await?; debug!("setting up metrics"); let labels = HashMap::from([( @@ -69,7 +67,7 @@ async fn main() -> Result<(), Box> { .service(entries::get::get_handler) .service(search::search_handler) }) - .bind(std::env::var("BIND_ADDRESS").unwrap_or_else(|_| "0.0.0.0:8080".to_string()))? + .bind(std::env::var("BIND_ADDRESS").unwrap_or_else(|_| "0.0.0.0:3003".to_string()))? .run() .await?; Ok(()) diff --git a/server/main-api/src/setup/meilisearch.rs b/server/main-api/src/setup/meilisearch.rs index 93ef1d189..2ec183a62 100644 --- a/server/main-api/src/setup/meilisearch.rs +++ b/server/main-api/src/setup/meilisearch.rs @@ -46,8 +46,11 @@ async fn wait_for_healthy(client: &Client) { pub(crate) async fn setup_meilisearch() -> Result<(), Box> { let start = std::time::Instant::now(); let ms_url = std::env::var("MIELI_URL").unwrap_or_else(|_| "http://localhost:7700".to_string()); + info!("connecting to Meilisearch at {ms_url}", ms_url = ms_url); let client = Client::new(ms_url, std::env::var("MEILI_MASTER_KEY").ok()); + info!("waiting for Meilisearch to be healthy"); wait_for_healthy(&client).await; + info!("Meilisearch is healthy"); client .create_index("entries", Some("ms_id")) diff --git a/webclient/Dockerfile b/webclient/Dockerfile index 1166b16eb..60f28555a 100644 --- a/webclient/Dockerfile +++ b/webclient/Dockerfile @@ -23,6 +23,6 @@ COPY nginx.conf /etc/nginx/nginx.conf RUN mkdir /app && apt update && apt upgrade -y COPY --from=build-stage /dist /app -EXPOSE 9000 -HEALTHCHECK CMD curl --fail localhost:9000/health || exit 1 +EXPOSE 3000 +HEALTHCHECK CMD curl --fail localhost:3000/health || exit 1 CMD ["nginx", "-g", "daemon off;"] diff --git a/webclient/build.sh b/webclient/build.sh index b0a0b8aec..0c4b0b097 100755 --- a/webclient/build.sh +++ b/webclient/build.sh @@ -5,19 +5,15 @@ set -e # fail on first error mkdir -p ../dist rm -fr ../dist -for LANG in en de +for THEME in light dark do - for THEME in light dark - do - # make sure we are really only building the right theme and language - sed -i "s/\$theme: .*/\$theme: \"${THEME}\";/" src/assets/variables.scss - sed -i "s/locale: .*/locale: \"${LANG}\",/" src/main.ts + # make sure we are really only building the right theme and language + sed -i "s/\$theme: .*/\$theme: \"${THEME}\";/" src/assets/variables.scss - echo "Building ${LANG}-${THEME}" - npm run build-only - mv dist/index.html dist/${LANG}-${THEME}.html - rsync -r dist/* ../dist - done + echo "Building ${THEME}" + npm run build-only + mv dist/index.html dist/${THEME}.html + rsync -r dist/* ../dist done diff --git a/webclient/cypress/e2e/feedback.cy.ts b/webclient/cypress/e2e/feedback.cy.ts index 3f6ca3b17..9244aee89 100644 --- a/webclient/cypress/e2e/feedback.cy.ts +++ b/webclient/cypress/e2e/feedback.cy.ts @@ -1,7 +1,7 @@ describe("Check if opening the feedback form works from every subview", () => { it("main page", () => { cy.intercept("GET", "/api/get/root?lang=de", { fixture: "get/root.de.json" }); - cy.visit("http://localhost:8000/"); + cy.visit("http://localhost:3000/"); cy.contains("Standorte"); cy.get('[data-cy="main-footer"]').scrollIntoView(); @@ -11,13 +11,13 @@ describe("Check if opening the feedback form works from every subview", () => { cy.intercept("GET", "/api/search?q=fsmb&limit_buildings=10&limit_rooms=30&limit_all=30&lang=de", { fixture: "search/fsmb.long.de.json", }); - cy.visit("http://localhost:8000/search?q=fsmb"); + cy.visit("http://localhost:3000/search?q=fsmb"); checkFeedbackForm('[data-cy="open-feedback-search"]'); }); it("details page (general feedback)", () => { cy.intercept("GET", "/api/get/mi?lang=de", { fixture: "get/mi.de.json" }); - cy.visit("http://localhost:8000/view/mi"); + cy.visit("http://localhost:3000/view/mi"); cy.get('[data-cy="open-feedback-details"]').should("exist", { timeout: 10_000 }); // wait for the site to be interactive checkFeedbackForm('[data-cy="open-feedback-details"]'); diff --git a/webclient/cypress/e2e/frontpage.cy.ts b/webclient/cypress/e2e/frontpage.cy.ts index c78cd5cd4..c18c784d4 100644 --- a/webclient/cypress/e2e/frontpage.cy.ts +++ b/webclient/cypress/e2e/frontpage.cy.ts @@ -1,14 +1,14 @@ describe("Check if navigating from the frontpage works as expected", () => { it("navigating to the mi", () => { cy.intercept("GET", "/api/get/root?lang=de", { fixture: "get/root.de.json" }); - cy.visit("http://localhost:8000/"); + cy.visit("http://localhost:3000/"); cy.intercept("GET", "/api/get/mi?lang=de", { fixture: "get/mi.de.json" }); cy.contains("Informatik").click(); cy.url().should("include", "/building/mi"); }); it("navigating to an initally hidden entry", () => { cy.intercept("GET", "/api/get/root?lang=de", { fixture: "get/root.de.json" }); - cy.visit("http://localhost:8000/"); + cy.visit("http://localhost:3000/"); cy.contains("mehr").click(); cy.intercept("GET", "/api/get/garching-interims?lang=de", { fixture: "get/garching-interims.de.json" }); cy.contains("Interims").click(); @@ -16,7 +16,7 @@ describe("Check if navigating from the frontpage works as expected", () => { }); it("navigate to an campus", () => { cy.intercept("GET", "/api/get/root?lang=de", { fixture: "get/root.de.json" }); - cy.visit("http://localhost:8000/"); + cy.visit("http://localhost:3000/"); cy.intercept("GET", "/api/get/garching?lang=de", { fixture: "get/garching.de.json" }); cy.contains("Garching Forschungszentrum").click({ scrollBehavior: false }); cy.url().should("include", "/campus/garching"); diff --git a/webclient/cypress/e2e/search.cy.ts b/webclient/cypress/e2e/search.cy.ts index f10252782..f5e58510f 100644 --- a/webclient/cypress/e2e/search.cy.ts +++ b/webclient/cypress/e2e/search.cy.ts @@ -9,7 +9,7 @@ describe("Check if the search page works as expected", () => { cy.intercept("GET", "/api/search?q=fsmb&limit_buildings=10&limit_rooms=30&limit_all=30&lang=de", { fixture: "search/fsmb.long.de.json", }); - cy.visit("http://localhost:8000/"); + cy.visit("http://localhost:3000/"); cy.get("input").type("fsmb"); cy.contains("Go").click(); cy.url().should("include", "/search?q=fsmb"); @@ -36,7 +36,7 @@ describe("Check if the search page works as expected", () => { fixture: "search/fsmb.long.de.json", }); cy.intercept("GET", "/api/get/5502.U1.234M?lang=de", { fixture: "get/5502.U1.234M.de.json" }); - cy.visit("http://localhost:8000/search?q=fsmb"); + cy.visit("http://localhost:3000/search?q=fsmb"); cy.contains("5502.U1.234M").click({ force: true }); cy.url().should("include", "/5502.U1.234M"); }); diff --git a/webclient/nginx.conf b/webclient/nginx.conf index 3532b2eed..f84378403 100644 --- a/webclient/nginx.conf +++ b/webclient/nginx.conf @@ -27,26 +27,9 @@ http { "light" "light"; } - # language detection. The accept_language header sucks. - # This map will only be used if $cookie_lang is unset - map $http_accept_language $ACCEPT_LANG { - default "de"; - - "~.*de.*en.*" "de"; - "~.*en.*de.*" "en"; - "~.*de.*" "de"; - "~.*en.*" "en"; - } - - map $cookie_lang $LANG { - default "${ACCEPT_LANG}"; - "en" "en"; - "de" "de"; - } - server { # default_server makes nginx not care about HOST, we hande this upstream by Traefik - listen 9000 default_server; + listen 3000 default_server; # compression configuration gzip on; @@ -73,10 +56,27 @@ http { return 200 'healthy'; } + # for development + location /api/ { + proxy_pass http://main-api:3003; + } + location /api/feedback { + proxy_pass http://feedback-api:3004; + } + location /api/calendar { + proxy_pass http://calendar-api:3005; + } + location /cdn { + proxy_pass http://data:3002; + } + location /maps/ { + proxy_pass http://tileserver:3001; + } + location / { add_header Cache-Control no-cache; # disable caching, as we do not want to have theme/language related issues expires 360s; # 360s=5min - try_files /$LANG-$THEME.html /404.html; + try_files /$THEME.html /404.html; } location /assets/ { @@ -97,7 +97,7 @@ http { root /usr/share/nginx/html; } - error_page 404 /$THEME-$LANG.html; + error_page 404 /$THEME.html; location = /404.html { return 404 'Requested Resource Not Found'; } diff --git a/webclient/package.json b/webclient/package.json index 2070c43d0..3a1c6a2f8 100644 --- a/webclient/package.json +++ b/webclient/package.json @@ -8,7 +8,7 @@ "test": "run-p cy:run:chrome cy:run:firefox", "dev": "vite", "build": "run-p type-check build-only", - "preview": "vite preview --port 8000", + "preview": "vite preview --port 3000", "build-only": "vite build", "type-check": "vue-tsc --noEmit", "lint": "eslint . --ext .vue,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore", diff --git a/webclient/vite.config.ts b/webclient/vite.config.ts index 96fe21ca9..1760236ad 100644 --- a/webclient/vite.config.ts +++ b/webclient/vite.config.ts @@ -14,7 +14,7 @@ export default defineConfig({ envDir: path.resolve(__dirname, "./env"), appType: "spa", server: { - port: 8000, + port: 3000, strictPort: true, open: false, proxy: {