Compare commits

..

431 Commits

Author SHA1 Message Date
danijel.simeunovic 5879c84a05 Merge branch 'feature/multi-cloud' of https://git.forteapps.net/Forte/launchpad into feature/multi-cloud
AI Code Review / ai-review (pull_request) Has been skipped
2026-04-24 10:48:08 +02:00
danijel.simeunovic c7cbfc712e overlays 2026-04-24 10:48:03 +02:00
gitea_admin ddccdacd6d Merge branch 'main' into feature/multi-cloud
AI Code Review / ai-review (pull_request) Has been skipped
2026-04-24 08:24:34 +00:00
danijel.simeunovic 65598c9297 karpor diffs 2026-04-24 09:47:52 +02:00
danijel.simeunovic 3f0f70699b karpor 2026-04-24 09:43:16 +02:00
danijel.simeunovic 06522b2f19 ts-mcp 2026-04-23 14:44:33 +02:00
danijel.simeunovic 4c65035485 ns 2026-04-23 14:11:45 +02:00
danijel.simeunovic 84f4bebc08 ts-mcp 2026-04-23 13:41:51 +02:00
danijel.simeunovic 5394b2c714 ts-mcp 2026-04-23 13:40:33 +02:00
danijel.simeunovic c4e586a7be ts-mcp 2026-04-23 13:38:47 +02:00
danijel.simeunovic 1fa070b041 argo 2026-04-23 13:35:42 +02:00
danijel.simeunovic 9c905355e3 argocd known host 2026-04-23 13:28:34 +02:00
danijel.simeunovic 6b1115ec28 argocd disable submodule 2026-04-23 13:09:02 +02:00
danijel.simeunovic 2fb276a62c ts-mcp 2026-04-23 13:02:00 +02:00
danijel.simeunovic 3efe1b68ef auth doc 2026-04-23 10:05:15 +02:00
danijel.simeunovic a89f2f30ce details 2026-04-22 22:26:57 +02:00
danijel.simeunovic 9a7e03b794 Merge branch 'feature/cloud-agnostic' into feature/multi-cloud 2026-04-22 22:06:31 +02:00
danijel.simeunovic f1dd61cece sync 2026-04-22 21:56:43 +02:00
danijel.simeunovic acc9bb1a85 sync 2026-04-22 21:53:44 +02:00
danijel.simeunovic c8c2dedea5 rename 2026-04-22 21:48:02 +02:00
danijel.simeunovic a471f11740 repo url 2026-04-22 14:45:23 +02:00
danijel.simeunovic 92ddc22322 azure>aks 2026-04-22 14:42:02 +02:00
danijel.simeunovic 7d2fb8bc0c azure>aks 2026-04-22 14:41:42 +02:00
danijel.simeunovic 79f9c62012 azure>aks 2026-04-22 14:35:59 +02:00
danijel.simeunovic dea54e469e repo url 2026-04-22 14:34:20 +02:00
danijel.simeunovic 333acdea26 multi-cloud overlays
AI Code Review / ai-review (pull_request) Successful in 6s
2026-04-22 14:30:13 +02:00
gitea_admin 03d526208b Merge branch 'main' into feature/cloud-agnostic
AI Code Review / ai-review (pull_request) Successful in 7s
2026-04-22 12:08:08 +00:00
gitea_admin 458f7b23ad Merge branch 'main' into feature/multi-cloud
AI Code Review / ai-review (pull_request) Successful in 28s
2026-04-22 11:55:05 +00:00
danijel.simeunovic 5df104beec sp 2026-04-22 13:54:51 +02:00
gitea_admin 41c8b85bf8 Merge branch 'main' into feature/multi-cloud
AI Code Review / ai-review (pull_request) Successful in 26s
2026-04-22 11:52:22 +00:00
danijel.simeunovic 0ecfee3cf8 prompts 2026-04-22 13:51:38 +02:00
danijel.simeunovic c3f723333b Merge branch 'feature/cloud-agnostic' of ssh://git.forteapps.net:2222/Forte/launchpad into feature/cloud-agnostic
AI Code Review / ai-review (pull_request) Successful in 1m3s
2026-04-22 13:43:09 +02:00
danijel.simeunovic 4144b1c1ac token 2026-04-22 13:39:43 +02:00
danijel.simeunovic 16eadbe181 Merge remote-tracking branch 'origin/main' into feature/cloud-agnostic 2026-04-22 13:38:55 +02:00
danijel.simeunovic 4e6a84785a token
AI Code Review / ai-review (pull_request) Successful in 28s
2026-04-22 13:37:32 +02:00
danijel.simeunovic e0bdaab422 multi-cloud + mcp
AI Code Review / ai-review (pull_request) Failing after 2s
2026-04-22 13:34:48 +02:00
danijel.simeunovic 230ea7ebeb Merge branch 'main' into feature/cloud-agnostic
AI Code Review / ai-review (pull_request) Failing after 3s
2026-04-22 11:33:03 +00:00
danijel.simeunovic cab0866e14 multi-cloud no mcp 2026-04-22 13:31:09 +02:00
danijel.simeunovic c88938adb5 feature/ai-review (#7)
Co-authored-by: gitea_admin <admin@forteapps.net>
Reviewed-on: #7
Co-authored-by: Danijel Simeunovic <danijel.simeunovic@fortedigital.com>
Co-committed-by: Danijel Simeunovic <danijel.simeunovic@fortedigital.com>
2026-04-22 09:30:02 +00:00
danijel.simeunovic d05a16840e pr trigger 2026-04-22 09:11:40 +02:00
danijel.simeunovic d7c7242aa1 submodule 2026-04-22 09:10:38 +02:00
danijel.simeunovic 3bf9fa7837 pr label 2026-04-22 08:48:05 +02:00
danijel.simeunovic d2596568f2 version tag 2026-04-21 15:17:52 +02:00
danijel.simeunovic 2a3539350b AI-review (#6)
Co-authored-by: gitea_admin <admin@forteapps.net>
Reviewed-on: #6
Co-authored-by: Danijel Simeunovic <danijel.simeunovic@fortedigital.com>
Co-committed-by: Danijel Simeunovic <danijel.simeunovic@fortedigital.com>
2026-04-21 08:20:41 +00:00
danijel.simeunovic f97b613c12 remove unneeded yml 2026-04-20 22:46:44 +02:00
danijel.simeunovic 9c7db11470 remove unneeded yml 2026-04-20 22:45:53 +02:00
danijel.simeunovic 723072bd1e cleanup 2026-04-19 13:47:29 +02:00
danijel.simeunovic 046b78446b add opencost 2026-04-19 13:41:44 +02:00
danijel.simeunovic 56a1b49d10 missing manifest 2026-04-19 13:39:26 +02:00
danijel.simeunovic d557eb1865 revert 2026-04-19 13:28:40 +02:00
danijel.simeunovic a51ed84124 Merge branch 'main' of https://git.forteapps.net/Forte/launchpad 2026-04-19 13:28:03 +02:00
danijel.simeunovic 73e253a579 traefik 2026-04-19 13:27:59 +02:00
danijel.simeunovic d7c1341eab don't sync users with cron job 2026-04-19 11:43:47 +02:00
danijel.simeunovic eed53006c1 docs 2026-04-18 23:12:18 +02:00
danijel.simeunovic 395ca70c2a prod values 2026-04-18 23:02:02 +02:00
danijel.simeunovic ea04ec20c9 remove docs wf 2026-04-18 20:54:48 +02:00
danijel.simeunovic 03a0d7c9ae feature/multicluster
Deploy Gitea Pages / build-and-deploy (push) Failing after 5s
Co-authored-by: Danijel Simeunovic <danijel.simeunovic@trumf.no>
Reviewed-on: #4
Reviewed-by: gitea_admin <admin@forteapps.net>
2026-04-18 18:14:00 +00:00
danijel.simeunovic 72a65f0e06 client cloner (#3)
Deploy Gitea Pages / build-and-deploy (push) Failing after 7s
Reviewed-on: #3
Reviewed-by: gitea_admin <admin@forteapps.net>
Co-authored-by: Danijel Simeunovic <danijel.simeunovic@fortedigital.com>
Co-committed-by: Danijel Simeunovic <danijel.simeunovic@fortedigital.com>
2026-04-17 13:42:44 +00:00
danijel.simeunovic 44fc242ae8 doc
Deploy Gitea Pages / build-and-deploy (push) Failing after 7s
2026-04-17 11:43:50 +02:00
danijel.simeunovic b2f601e950 doc
Deploy Gitea Pages / build-and-deploy (push) Failing after 6s
2026-04-17 11:42:46 +02:00
danijel.simeunovic f8b17cc030 log level info renovate 2026-04-17 10:59:52 +02:00
danijel.simeunovic 6639d0e3ff renovate prs
Deploy Gitea Pages / build-and-deploy (push) Failing after 5m15s
2026-04-17 09:58:52 +02:00
danijel.simeunovic 4485731ab5 smtp+starttls 2026-04-16 15:57:59 +02:00
danijel.simeunovic 439b8516f0 smtps auth 2026-04-16 15:46:54 +02:00
danijel.simeunovic 0eccd2d439 smtp auth 2026-04-16 15:43:10 +02:00
danijel.simeunovic 3e1029a557 mail notification 2026-04-16 15:39:51 +02:00
danijel.simeunovic 61c2801e0a smtp 2026-04-16 15:32:10 +02:00
gitea_admin 8902a0e51e Merge pull request 'SMTP config Gitea' (#2) from feature/smtp into main
Reviewed-on: #2
2026-04-16 13:17:28 +00:00
danijel.simeunovic 4486279eab smtp config 2026-04-16 15:13:18 +02:00
danijel.simeunovic 020dfeffd4 client secret fixes
Deploy Gitea Pages / build-and-deploy (push) Failing after 6m6s
2026-04-16 15:04:27 +02:00
danijel.simeunovic 7e10954a8f client secret bootstrapping
Deploy Gitea Pages / build-and-deploy (push) Failing after 39m32s
2026-04-16 13:55:13 +02:00
danijel.simeunovic 88c29565b6 smtp 2026-04-16 10:42:35 +02:00
danijel.simeunovic 87ee0588a7 renovate pr targets 2026-04-15 16:33:58 +02:00
danijel.simeunovic db8a1de797 10x repo PRs 2026-04-15 13:46:13 +02:00
danijel.simeunovic 177150e069 gitea protocol mapper
Deploy Gitea Pages / build-and-deploy (push) Failing after 7s
2026-04-15 13:27:14 +02:00
danijel.simeunovic c63a9242f0 renovate loglevel 2026-04-14 12:44:47 +02:00
danijel.simeunovic 1d43ecddad renovate daily and more mem 2026-04-14 12:26:46 +02:00
danijel.simeunovic a702a16155 renovate token 2026-04-14 12:17:53 +02:00
danijel.simeunovic 8b403736a9 secret renovate 2026-04-14 12:14:43 +02:00
danijel.simeunovic 0e8524b84a renovate
Deploy Gitea Pages / build-and-deploy (push) Failing after 6s
2026-04-14 12:05:14 +02:00
danijel.simeunovic 58ccc9fd2e Merge branch 'main' of https://git.forteapps.net/Forte/launchpad 2026-04-14 10:53:49 +02:00
danijel.simeunovic 08d870d44c oauth fix 2026-04-14 10:53:45 +02:00
gitea_admin 2b7d441803 Update infra/gitea.yaml
ignoreDifferences
2026-04-14 08:33:47 +00:00
gitea_admin e74a8cb9d8 Update infra/values/gitea-values.yaml
ENABLE_BASIC_AUTH_CHALLENGE: true
2026-04-14 08:23:09 +00:00
danijel.simeunovic f5166b3797 readme 2026-04-13 16:08:30 +02:00
danijel.simeunovic 18fb0ca3da repo names fix
Deploy Gitea Pages / build-and-deploy (push) Failing after 6s
2026-04-13 16:08:01 +02:00
danijel.simeunovic 4abd528b19 launchpad 2026-04-13 15:55:25 +02:00
danijel.simeunovic a9a3e0e8ab Merge branch 'main' of https://git.forteapps.net/Forte/launchpad
Deploy Gitea Pages / build-and-deploy (push) Failing after 6s
2026-04-13 15:54:23 +02:00
danijel.simeunovic 827213c883 migration 2026-04-13 15:54:14 +02:00
gitea_admin 02d5b3eb5a Update .github/workflows/docs.yml 2026-04-09 09:11:16 +00:00
gitea_admin f90833711d Update .github/workflows/docs.yml 2026-04-09 09:05:12 +00:00
gitea_admin 1c6a0a1b2f Update .github/workflows/docs.yml 2026-04-09 09:02:58 +00:00
gitea_admin 665e4020ba Update .github/workflows/docs.yml 2026-04-09 09:01:37 +00:00
gitea_admin 643c0aaf9b Update .github/workflows/docs.yml 2026-04-09 09:00:24 +00:00
gitea_admin 61184f6fdf Update .github/workflows/docs.yml 2026-04-09 08:58:00 +00:00
gitea_admin 84698ab743 Update .github/workflows/docs.yml 2026-04-09 08:54:15 +00:00
snothub cb548ee09a gitea actions 2026-04-08 12:56:07 +02:00
snothub 9f130a8dc4 gitea runner token 2026-04-08 12:51:11 +02:00
snothub ab136ea8f2 gitea recreate 2026-04-08 12:44:56 +02:00
snothub b3d4a26a07 gitea runners 2026-04-08 12:40:13 +02:00
snothub 5e205944c6 kc creds 2026-04-08 12:21:37 +02:00
snothub 463a96054d kyverno policy remove 2026-04-08 12:12:09 +02:00
snothub 118cae656a gitea pg 2026-04-08 12:04:13 +02:00
snothub 2e725ffcdd gitea 2026-04-08 12:00:15 +02:00
snothub dcfa104948 disable results cache 2026-04-07 10:26:27 +02:00
snothub 43699b9bbd MkDocs 2026-04-04 17:46:08 +02:00
snothub 97aeba8275 docs 2026-04-04 17:30:16 +02:00
snothub f7897bc2bf kc resources 2026-04-02 22:56:18 +02:00
snothub b281556808 mcp def scope 2026-04-02 22:45:15 +02:00
snothub 010d29ff11 argo notifications 2026-03-29 21:44:25 +02:00
snothub 369d5453e0 notification fix 2026-03-29 21:07:26 +02:00
snothub 212dc66fab PSS dash 2026-03-29 16:20:48 +02:00
snothub 38433f62ce del mcpcoder 2026-03-29 15:20:27 +02:00
snothub ede14d9ec6 degraded message fix 2026-03-29 14:57:30 +02:00
snothub 9edbe3d0ef argocd status sync update 2026-03-29 14:53:55 +02:00
snothub e199b00137 dash opt 2026-03-27 14:25:34 +01:00
snothub ce5094c1c8 egress 2026-03-27 11:49:03 +01:00
snothub 5e8448cfd2 dashboards json 2026-03-27 09:05:06 +01:00
snothub 875db6721e keycloak resource lowering 2026-03-26 18:34:10 +01:00
snothub 87cd2401c5 resource lowering on monitoring 2026-03-26 18:31:28 +01:00
snothub e938bf2467 new grafana dash 2026-03-26 16:04:32 +01:00
snothub ca8127802b doc 2026-03-26 15:25:14 +01:00
snothub 1609f6afde exclude trivy-system from kyverno policies 2026-03-26 13:34:00 +01:00
snothub c33abcc357 default port 2026-03-26 13:26:31 +01:00
snothub 8029b7816d rename annotation 2026-03-26 13:25:53 +01:00
snothub 5640a5ca4a sidecar port 2026-03-26 13:24:06 +01:00
snothub b9d8470a52 oauth env sidecar 2026-03-26 11:48:28 +01:00
danijel.simeunovic 279bc8b273 traefik default time span 2026-03-23 13:11:28 +01:00
danijel.simeunovic c914498590 line format 2026-03-23 12:27:58 +01:00
danijel.simeunovic 5d8437bd01 filter logs 2026-03-23 12:24:27 +01:00
danijel.simeunovic 684b35c009 service graph 2026-03-23 12:16:44 +01:00
danijel.simeunovic db8fb09fe1 sm 2026-03-23 12:10:31 +01:00
danijel.simeunovic 7a204e367c time ranges 2026-03-23 11:55:00 +01:00
danijel.simeunovic bdfada0838 opencost disable ui 2026-03-23 11:49:30 +01:00
danijel.simeunovic 7269eb3121 title 2026-03-23 11:42:25 +01:00
danijel.simeunovic fca94cde94 fix 2026-03-23 11:41:13 +01:00
danijel.simeunovic 161dc52d4a refresh 2026-03-23 11:07:52 +01:00
danijel.simeunovic 76b39241c1 oc yaml indenting 2026-03-23 10:50:44 +01:00
danijel.simeunovic f50f03d8e0 typo 2026-03-23 10:44:46 +01:00
danijel.simeunovic 4266327d35 rates fix 2026-03-23 10:41:21 +01:00
danijel.simeunovic 8f71d159ff currency and rates 2026-03-23 10:36:02 +01:00
danijel.simeunovic f8ecc54b86 panel 2026-03-23 09:39:34 +01:00
danijel.simeunovic b1b75c77c5 cost values 2026-03-23 09:37:44 +01:00
danijel.simeunovic c2aa680a0f opencost grafana json 2026-03-23 09:23:16 +01:00
danijel.simeunovic d0ab490eb5 datasource 2026-03-22 16:01:04 +01:00
danijel.simeunovic fd0e578131 opencost scraping 2026-03-22 15:51:11 +01:00
danijel.simeunovic c6bc723b8a opencost scrapes 2026-03-22 00:17:12 +01:00
danijel.simeunovic 1983c80f15 opencost 2026-03-21 23:55:33 +01:00
danijel.simeunovic 5dc12cfaa2 new api token 2026-03-21 23:36:33 +01:00
danijel.simeunovic 258ece5f85 dot ai secrets 2026-03-21 23:32:32 +01:00
danijel.simeunovic 2f88b2d16c svc graph fix 2026-03-20 14:41:10 +01:00
danijel.simeunovic b4ffae5078 service graph 2026-03-20 14:31:52 +01:00
danijel.simeunovic 7aa69f6a7f cleanup 2026-03-20 14:29:32 +01:00
danijel.simeunovic d394dfd55e host fix 2026-03-20 14:23:46 +01:00
danijel.simeunovic f728f9dbd3 Tempo doc 2026-03-20 14:22:14 +01:00
danijel.simeunovic 7522b88cfb fix tempo 2026-03-20 14:19:55 +01:00
danijel.simeunovic afb39f99a7 Grafana Tempo 2026-03-20 14:04:20 +01:00
danijel.simeunovic e4f8f2c071 traefik grafana dash 2026-03-20 13:46:13 +01:00
danijel.simeunovic 2ecd0c8a44 traefik metrics 2026-03-20 13:32:06 +01:00
danijel.simeunovic 3c81fd1e3a cleanup 2026-03-20 13:11:38 +01:00
danijel.simeunovic b665faaa7b sidecar image ref 2026-03-20 13:06:11 +01:00
danijel.simeunovic 5071110c72 repo url fix 2026-03-20 13:02:48 +01:00
danijel.simeunovic 016e70a998 argocd repo secret 2026-03-20 12:59:13 +01:00
Danijel Simeunovic 8b1931fa9d traefik access logging 2026-03-20 11:12:48 +01:00
Danijel Simeunovic ec4082de93 otel 2026-03-20 11:09:42 +01:00
Danijel Simeunovic d50b790082 otel 2026-03-20 11:08:04 +01:00
Danijel Simeunovic 29e644510c traefik tracing 2026-03-20 10:57:18 +01:00
Danijel Simeunovic 3264f879b0 fortedigital/forte-helm 2026-03-20 09:42:32 +01:00
Danijel Simeunovic 36460b5cac kcprom 2026-03-19 20:28:42 +01:00
Danijel Simeunovic 4c0ec63ec3 apikey 2026-03-19 12:51:07 +01:00
Danijel Simeunovic 2b71f63740 dot-ai 2026-03-19 12:46:51 +01:00
Danijel Simeunovic 0de4e381c7 mm secret 2026-03-19 10:38:02 +01:00
Danijel Simeunovic 2c0b6b5ea9 authn: public paths 2026-03-18 22:41:12 +01:00
Danijel Simeunovic 08fe2c447d FC token 2026-03-18 11:00:52 +01:00
Danijel Simeunovic 852b906bb2 mcpcoder 2026-03-18 09:27:08 +01:00
Danijel Simeunovic 5e62acf63d image 2026-03-17 19:35:14 +01:00
Danijel Simeunovic eb99e5420c kc 2026-03-17 18:03:36 +01:00
Danijel Simeunovic 66b477bd3b kc host 2026-03-17 17:16:58 +01:00
Danijel Simeunovic 070e3c9662 legacy 2026-03-17 16:27:55 +01:00
Danijel Simeunovic 1ccfb713e0 del 2026-03-17 15:42:06 +01:00
Danijel Simeunovic f615d32282 bitnami images 2026-03-17 15:41:15 +01:00
Danijel Simeunovic 5a801e0651 kc db 2026-03-17 15:37:00 +01:00
Danijel Simeunovic a294016e84 keycloak 2026-03-17 15:24:24 +01:00
Danijel Simeunovic 91d0b592ca fix doc 2026-03-17 13:16:01 +01:00
Danijel Simeunovic eacce3a8c1 mcp auth doc 2026-03-17 13:14:15 +01:00
Danijel Simeunovic fc2ab655b1 env sections 2026-03-17 12:22:19 +01:00
Danijel Simeunovic aa08a66dae mcp auth sidecar 2026-03-17 12:19:30 +01:00
Danijel Simeunovic 77bcb8fdbb docs 2026-03-17 09:53:42 +01:00
Danijel Simeunovic e71e408c6f path 2026-03-16 16:07:42 +01:00
Danijel Simeunovic 4aa212cbc5 imagePullPolicy 2026-03-16 15:37:20 +01:00
Danijel Simeunovic 57cab7d3aa loglevel 2026-03-16 15:24:36 +01:00
Danijel Simeunovic 10f4e4c2fc url in doc 2026-03-16 15:08:08 +01:00
Danijel Simeunovic 2f5eee3e73 fix repo url in doc 2026-03-16 15:06:46 +01:00
Danijel Simeunovic 7036cedfa2 secret 2026-03-16 14:25:47 +01:00
Danijel Simeunovic 93d3778605 secret 2026-03-16 13:48:21 +01:00
Danijel Simeunovic 865013a2af invalidate fc token 2026-03-16 13:29:07 +01:00
Danijel Simeunovic de36a44ee1 FC token 2026-03-16 12:20:08 +01:00
Danijel Simeunovic a77cd4d257 git ssh 2026-03-16 12:07:15 +01:00
Danijel Simeunovic b4aef11546 rev 2026-03-16 12:03:24 +01:00
Danijel Simeunovic 8eeacfbc0b git ssh 2026-03-16 12:01:58 +01:00
Danijel Simeunovic fae0826400 ssh access 2026-03-16 11:54:32 +01:00
Danijel Simeunovic 7aff19ccab fix 2026-03-16 11:45:43 +01:00
Danijel Simeunovic ae075bbc48 docs auth 2026-03-16 11:14:12 +01:00
Danijel Simeunovic d02da33700 docs 2026-03-16 11:00:42 +01:00
Danijel Simeunovic 275c100af5 secrets 2026-03-16 10:14:21 +01:00
Danijel Simeunovic f75b83977d secrets 2026-03-16 10:01:51 +01:00
Danijel Simeunovic 6b181b8d78 del mcpcoder 2026-03-16 08:30:28 +01:00
Danijel Simeunovic bd264fe074 new repo 2026-03-15 22:19:26 +01:00
Danijel Simeunovic 58a5c0c333 10x cred 2026-03-15 22:17:36 +01:00
Danijel Simeunovic cb071b96d2 mcp10x app creds 2026-03-15 21:50:28 +01:00
Danijel Simeunovic e56a506eab mcp10x forteapp 2026-03-15 21:28:41 +01:00
Danijel Simeunovic 63f6b34bb5 mm 2026-03-15 15:22:18 +01:00
Danijel Simeunovic e87bfa5abd musicman forteapp 2026-03-15 14:31:50 +01:00
Danijel Simeunovic d077300d03 annot 2026-03-15 12:25:05 +01:00
Danijel Simeunovic 350714fd3c mcpcoder forteapp 2026-03-15 11:53:38 +01:00
Danijel Simeunovic 0e7f6e94b8 ssh 2026-03-15 01:26:29 +01:00
Danijel Simeunovic acc2c4c8f9 repo 2026-03-15 01:22:46 +01:00
Danijel Simeunovic 47b170e1cb ssh 2026-03-15 01:18:53 +01:00
Danijel Simeunovic 9e9329d085 cred 2026-03-15 01:06:27 +01:00
Danijel Simeunovic 91f7436eb7 source 2026-03-15 00:50:32 +01:00
Danijel Simeunovic 0d5f66ce05 cleanup 2026-03-15 00:40:56 +01:00
Danijel Simeunovic 9ff65c8e66 path 2026-03-15 00:10:33 +01:00
Danijel Simeunovic 8b348ed5de path 2026-03-15 00:04:05 +01:00
Danijel Simeunovic 8da4c80fa3 change chart 2026-03-15 00:01:38 +01:00
Danijel Simeunovic acc8cf483b callback param 2026-03-13 22:36:35 +01:00
Danijel Simeunovic 0c9c4b6b0d sidecar oidc 2026-03-13 21:57:51 +01:00
Danijel Simeunovic 36ba7023f4 policies.forteapps.io/auth-token-secret-name 2026-03-13 13:36:47 +01:00
Danijel Simeunovic 61f623e3c7 order 2026-03-13 13:24:09 +01:00
Danijel Simeunovic 2e3232ecb9 loop 2026-03-13 13:05:22 +01:00
Danijel Simeunovic 58673feeb0 sidecar 2026-03-13 12:59:26 +01:00
Danijel Simeunovic 5e15b7e0f2 nonroot 2026-03-13 12:36:42 +01:00
Danijel Simeunovic edbbb52bc6 rule 2026-03-13 12:33:14 +01:00
Danijel Simeunovic 0a803cda11 method: GET 2026-03-13 12:26:44 +01:00
Danijel Simeunovic 4624cc7278 secret gen 2026-03-13 12:21:21 +01:00
Danijel Simeunovic cc7c5fea70 name 2026-03-13 12:16:52 +01:00
Danijel Simeunovic cbd25568c0 auth sidecar 2026-03-13 12:03:23 +01:00
Danijel Simeunovic 6d59897fe3 rw 2026-03-13 08:57:06 +01:00
Danijel Simeunovic 0989a6d6cc auth 2026-03-13 08:54:37 +01:00
Danijel Simeunovic 0eb6d8d774 ro 2026-03-12 20:46:18 +01:00
Danijel Simeunovic bd1945d105 write 2026-03-12 20:36:00 +01:00
Danijel Simeunovic 16580ea871 disable auth 2026-03-12 20:19:55 +01:00
Danijel Simeunovic 0ea45cd664 annotations 2026-03-12 18:27:22 +01:00
Danijel Simeunovic 235612bc17 host 2026-03-12 18:17:10 +01:00
Danijel Simeunovic 4825c540b9 ns 2026-03-12 18:14:44 +01:00
Danijel Simeunovic bd40ffece4 argomcp 2026-03-12 18:12:09 +01:00
Danijel Simeunovic bc94cd13d5 reduce more noise 2026-03-12 11:22:38 +01:00
Danijel Simeunovic 5c6269c58b reduce sync noise 2026-03-12 11:21:48 +01:00
Danijel Simeunovic a803ef7438 icon 2026-03-12 11:09:47 +01:00
Danijel Simeunovic 639278d485 clustername 2026-03-12 09:53:20 +01:00
Danijel Simeunovic b517a84990 del 2026-03-10 12:51:16 +01:00
Danijel Simeunovic 193b1aa28b credentials 2026-03-10 10:59:36 +01:00
Danijel Simeunovic 3b0eb5c1d5 Merge branch 'main' of https://github.com/fortedigital/sturdy-adventure 2026-03-10 10:26:59 +01:00
Danijel Simeunovic e06901bd7b mcp10x 2026-03-10 10:24:37 +01:00
Danijel Simeunovic 67da1be2d3 mcp10x 2026-03-10 10:24:26 +01:00
Danijel Simeunovic 135839c54c mcp coder 2026-03-09 13:22:57 +01:00
Danijel Simeunovic 0644998f16 dot-ai 2026-03-09 13:11:53 +01:00
Danijel Simeunovic 1a0d787766 ns 2026-03-09 11:58:35 +01:00
Danijel Simeunovic 7f1a842611 wave 2026-03-09 11:36:49 +01:00
Danijel Simeunovic caa3c2ccaf undot 2026-03-09 09:40:33 +01:00
Danijel Simeunovic e14f22f29f adjust 2026-03-09 09:40:04 +01:00
Danijel Simeunovic 4f4c26f58c finalizers 2026-03-06 15:25:51 +01:00
Danijel Simeunovic 02b879b576 cleanup 2026-03-06 09:54:07 +01:00
Danijel Simeunovic 2fac718488 readme 2026-03-06 09:51:20 +01:00
Danijel Simeunovic 2a1bc88ce5 details 2026-03-06 09:44:45 +01:00
Danijel Simeunovic e1ee176277 details 2026-03-06 09:44:29 +01:00
Danijel Simeunovic fdd013c1c8 apps group 2026-03-06 09:41:05 +01:00
Danijel Simeunovic 0955767ae6 shuffle 2026-03-06 09:32:36 +01:00
Danijel Simeunovic 33dd0a06c7 perm2 2026-03-06 09:30:04 +01:00
Danijel Simeunovic b23a23d385 permissions 2026-03-06 09:18:12 +01:00
Danijel Simeunovic cc69346de9 permissions 2026-03-06 09:15:19 +01:00
Danijel Simeunovic 671ae6e702 fix 2026-03-06 09:10:07 +01:00
Danijel Simeunovic 1f772ef7f5 policies 2026-03-06 08:58:04 +01:00
Danijel Simeunovic 2da39f7c67 default blocker 2026-03-06 08:50:51 +01:00
Danijel Simeunovic 1a621c038f secret cloner 2026-03-06 08:48:33 +01:00
Danijel Simeunovic daec2b1bb2 refine 2026-03-05 21:59:51 +01:00
Danijel Simeunovic 72d88ca533 trivy_vulnerability_id 2026-03-05 21:53:07 +01:00
Danijel Simeunovic eb084ef5cf new key 2026-03-05 19:08:34 +01:00
Danijel Simeunovic cfb456e705 cve 2026-03-05 16:04:55 +01:00
Danijel Simeunovic b4e735bfb8 exclude ns 2026-03-05 15:59:16 +01:00
Danijel Simeunovic 5e8712dbfb trivy reinstall 2026-03-05 15:51:11 +01:00
Danijel Simeunovic 893aab6877 uninstall trivy 2026-03-05 15:34:03 +01:00
Danijel Simeunovic a9b1287db0 new api key 2026-03-05 14:29:23 +01:00
Danijel Simeunovic bfc527bee4 dot-ai secret 2026-03-05 14:17:31 +01:00
Danijel Simeunovic df1359fe82 trivy config 2026-03-05 13:48:32 +01:00
Danijel Simeunovic 020b046859 trivy unfixed 2026-03-05 13:36:07 +01:00
Danijel Simeunovic 59eff39149 cve 2026-03-05 13:18:39 +01:00
Danijel Simeunovic ecf8bd6f12 trivy prom 2026-03-05 12:36:44 +01:00
Danijel Simeunovic 35e9b0c739 diffs 2026-03-05 11:43:13 +01:00
Danijel Simeunovic 24f9c956bc readme 2026-03-05 10:53:43 +01:00
Danijel Simeunovic d86eead4c4 remove stale lines 2026-03-05 10:45:08 +01:00
Danijel Simeunovic 1af57ea5c1 bootstrap main app 2026-03-05 10:28:15 +01:00
Danijel Simeunovic 04d39c71aa keys 2026-03-04 14:10:08 +01:00
Danijel Simeunovic 3ec8f48996 mcp- 2026-03-04 13:58:18 +01:00
Danijel Simeunovic b7fb5e2064 keys 2026-03-04 13:57:40 +01:00
Danijel Simeunovic dc246a46e8 mcp 2026-03-04 13:45:36 +01:00
Danijel Simeunovic 89753324dc finalizers 2026-03-04 13:36:23 +01:00
Danijel Simeunovic c4746047cd del 2026-03-04 13:29:17 +01:00
Danijel Simeunovic 449bf19c10 ns 2026-03-04 13:26:48 +01:00
Danijel Simeunovic 85650148f6 dot 2026-03-04 12:58:57 +01:00
Danijel Simeunovic 5f09242ebd clean 2026-03-04 12:28:22 +01:00
Danijel Simeunovic b1f01a6ff8 mcpcoder 2026-03-04 12:25:50 +01:00
Danijel Simeunovic cc2ed9e91a annot 2026-03-04 12:16:29 +01:00
Danijel Simeunovic 4a623fd3b4 payload 2026-03-04 12:05:10 +01:00
Danijel Simeunovic ef78bfa9c5 argo notifications 2026-03-04 11:13:41 +01:00
Danijel Simeunovic 5f99aed97a triggers 2026-03-04 11:10:44 +01:00
Danijel Simeunovic bea55380d5 kyverno diffs 2026-03-04 10:56:31 +01:00
Danijel Simeunovic ab58c8a62a argocd notifications 2026-03-04 10:50:35 +01:00
Danijel Simeunovic 4d3269a24c dot 2026-03-04 09:51:39 +01:00
Danijel Simeunovic e7b80014c3 del 2026-03-03 20:16:33 +01:00
Danijel Simeunovic 5d3f21170e audit 2026-03-03 20:05:42 +01:00
Danijel Simeunovic 86a7994bf8 mcpcoder 2026-03-03 19:13:04 +01:00
Danijel Simeunovic fa8b6dc0de dot-ai 2026-03-03 17:39:44 +01:00
Danijel Simeunovic edd468e239 sync 2026-02-27 14:12:09 +01:00
Danijel Simeunovic e7168373aa app of apps 2026-02-27 13:49:51 +01:00
Danijel Simeunovic 11fb039e23 comment 2026-02-27 13:43:00 +01:00
Danijel Simeunovic b2642c051f loki mem 2026-02-26 14:36:42 +01:00
Danijel Simeunovic c7b0dbe4a7 show pod in logs 2026-02-25 10:11:23 +01:00
Danijel Simeunovic 355fabcfd6 more refining 2026-02-25 10:04:26 +01:00
Danijel Simeunovic b17c790946 grafana refining 2026-02-25 09:51:32 +01:00
Danijel Simeunovic 6bb3440d8b loki fix 2026-02-25 09:43:27 +01:00
Danijel Simeunovic 748c491d4e fluentbit fixes 2026-02-25 09:34:27 +01:00
Danijel Simeunovic 143f115236 log fixes 2026-02-25 09:24:54 +01:00
Danijel Simeunovic bd1f347164 audit policy 2026-02-24 10:58:42 +01:00
Copilot 940cd66a6a Update README repository structure with missing files (#1)
* Initial plan

* Update README.md repository structure to reflect actual files

Co-authored-by: snothub <12095691+snothub@users.noreply.github.com>

* Fix spelling and tree structure formatting in README.md

Co-authored-by: snothub <12095691+snothub@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: snothub <12095691+snothub@users.noreply.github.com>
2026-02-19 15:46:26 +01:00
Danijel Simeunovic 4987b582f4 promfix 2026-02-18 15:11:24 +01:00
Danijel Simeunovic 480be6fef4 indent 2026-02-18 15:02:08 +01:00
Danijel Simeunovic f5c1dc0cbc enforce 2026-02-18 13:17:39 +01:00
Danijel Simeunovic a962fd6450 rule 2026-02-18 13:13:52 +01:00
Danijel Simeunovic e06a080eb5 bck 2026-02-18 12:38:20 +01:00
Danijel Simeunovic 259b43f642 skip 2026-02-18 12:35:02 +01:00
Danijel Simeunovic 74eadaeffb tune 2026-02-18 12:31:32 +01:00
Danijel Simeunovic f676379176 enforce 2026-02-18 12:27:33 +01:00
Danijel Simeunovic 5858a8b7d1 pre 2026-02-18 12:22:52 +01:00
Danijel Simeunovic 67a47528cc fix2 2026-02-18 12:19:19 +01:00
Danijel Simeunovic 788a3392bf fix 2026-02-18 12:15:51 +01:00
Danijel Simeunovic b27b5ad789 check 2026-02-18 12:11:44 +01:00
Danijel Simeunovic 79f48af2b5 depl checker 2026-02-18 12:06:11 +01:00
Danijel Simeunovic 08a2b3a807 enforce pod label 2026-02-18 10:44:13 +01:00
Danijel Simeunovic cb0766ffdd kyverno scraper 2026-02-17 15:26:02 +01:00
Danijel Simeunovic b7987caee8 diff 2026-02-17 14:45:04 +01:00
Danijel Simeunovic 691fd9926d name 2026-02-17 14:41:52 +01:00
Danijel Simeunovic 126eb7c01c kyvernopolicies 2026-02-17 14:40:59 +01:00
Danijel Simeunovic 706d15476c label checker audit 2026-02-17 14:38:00 +01:00
Danijel Simeunovic f32ae3d79f fbvals 2026-02-16 13:47:22 +01:00
Danijel Simeunovic 0f26bbda69 log fixes 2026-02-16 13:19:05 +01:00
Danijel Simeunovic 90fae4c415 simplify 2026-02-14 16:26:01 +01:00
Danijel Simeunovic 0db4f69bd7 loki fixes 2026-02-13 13:56:35 +01:00
Danijel Simeunovic 1ba2271ba2 fb config 2026-02-13 13:46:33 +01:00
Danijel Simeunovic 370261fe58 fluent bit config fix 2026-02-13 13:07:54 +01:00
Danijel Simeunovic 5437af59d3 kyverno diff 2026-02-13 12:30:39 +01:00
Danijel Simeunovic 7568280464 loki fix 2026-02-13 10:39:27 +01:00
Danijel Simeunovic 88d9f94736 Traefik health check fix 2026-02-13 10:00:37 +01:00
Danijel Simeunovic bad5ce2304 readme 2026-02-12 20:52:57 +01:00
Danijel Simeunovic bd754a016c app 2026-02-12 20:50:59 +01:00
Danijel Simeunovic c806decbb7 musicman 2026-02-12 15:37:27 +01:00
Danijel Simeunovic 26d4c3e236 values 2026-02-12 13:54:13 +01:00
Danijel Simeunovic 561ab00e66 helm values 2026-02-12 13:49:39 +01:00
Danijel Simeunovic af1591073a metrics 2026-02-12 11:38:42 +01:00
Danijel Simeunovic c8dfdeb170 no port 2026-02-12 11:31:19 +01:00
Danijel Simeunovic 8502395521 tr yaml 2026-02-12 11:29:21 +01:00
Danijel Simeunovic c73d24aff6 clean 2026-02-12 11:21:35 +01:00
Danijel Simeunovic 6fb0652efc add params 2026-02-12 11:17:28 +01:00
Danijel Simeunovic 23de8285ec traefik trustedIps 2026-02-11 23:21:35 +01:00
Danijel Simeunovic 4ec763ac65 traefik dash 2026-02-11 18:04:05 +01:00
Danijel Simeunovic 7b694ef16c traefik svc 2026-02-11 17:37:58 +01:00
Danijel Simeunovic 133619818b readme 2026-02-11 13:54:50 +01:00
Danijel Simeunovic 058a3cba67 trivy 2026-02-11 13:42:06 +01:00
Danijel Simeunovic 3f981e156e readme 2026-02-11 13:03:30 +01:00
Danijel Simeunovic d431bf9dac traefik annotations 2026-02-11 09:00:02 +01:00
Danijel Simeunovic 5ec64dede6 readme 2026-02-10 15:24:01 +01:00
Danijel Simeunovic 04a34b77d2 readme 2026-02-10 15:09:25 +01:00
Danijel Simeunovic 300651ce8f trivy ver 2026-02-10 10:31:46 +01:00
Danijel Simeunovic 94dc33e936 labels 2026-02-10 10:03:24 +01:00
Danijel Simeunovic c57a3f0db2 loki dns 2026-02-10 09:59:46 +01:00
Danijel Simeunovic dcfd9c8901 loki config 2026-02-09 21:48:53 +01:00
Danijel Simeunovic 98da1fd070 fluent bit loki config 2026-02-09 21:44:12 +01:00
Danijel Simeunovic 66bb754979 feedback app 2026-02-09 15:58:24 +01:00
Danijel Simeunovic 089f1cae17 grafana host 2026-02-09 15:50:01 +01:00
Danijel Simeunovic 0170c5e4bf remove policy 2026-02-09 15:38:40 +01:00
Danijel Simeunovic d35bbeadab remove presync hook 2026-02-09 15:18:15 +01:00
Danijel Simeunovic 10c0d19bfb fixes 2026-02-09 15:14:00 +01:00
Danijel Simeunovic e4434a40bd target rev 2026-02-09 15:06:41 +01:00
Danijel Simeunovic 0f229a9360 kyverno ver 2026-02-09 15:04:51 +01:00
Danijel Simeunovic fa0b715efb sh 2026-02-09 15:02:55 +01:00
Danijel Simeunovic 1813777146 cleanup 2026-02-09 09:42:50 +01:00
Danijel Simeunovic e62eb606cd readme 2026-02-09 09:05:00 +01:00
Danijel Simeunovic 52bc288081 values 2026-02-08 23:54:32 +01:00
Danijel Simeunovic e2cb0e85f1 labels 2026-02-08 23:52:08 +01:00
Danijel Simeunovic 3e9528dd6f folderstructure 2026-02-08 23:48:12 +01:00
Danijel Simeunovic 0bd3f0cb63 folder 2026-02-08 23:46:33 +01:00
Danijel Simeunovic 193a402906 labels 2026-02-08 23:45:30 +01:00
Danijel Simeunovic 2c4e75aafb folders 2026-02-08 23:42:42 +01:00
Danijel Simeunovic 19b61d8308 move 2026-02-08 23:34:57 +01:00
Danijel Simeunovic 94843f86f9 hook delete 2026-02-08 23:32:51 +01:00
Danijel Simeunovic cc8d815d5a infra 2026-02-08 23:30:36 +01:00
Danijel Simeunovic da984196f5 move 2026-02-08 23:28:44 +01:00
Danijel Simeunovic 5c2038353f backup 2026-02-08 23:27:16 +01:00
Danijel Simeunovic 81ef533fc6 wave 2026-02-08 23:16:38 +01:00
Danijel Simeunovic db6478b794 simplify 2026-02-08 23:15:47 +01:00
Danijel Simeunovic eed88fe233 test apps 2026-02-08 23:03:16 +01:00
Danijel Simeunovic fe3794f691 simplify 2026-02-08 17:07:45 +01:00
Danijel Simeunovic b54ed92f7c path 2026-02-08 17:06:53 +01:00
Danijel Simeunovic ba90ecac6d repo 2026-02-08 17:00:29 +01:00
Danijel Simeunovic fa4e7c1984 simplify 2026-02-08 16:59:38 +01:00
Danijel Simeunovic 65171ddcb7 spacing 2026-02-08 16:52:13 +01:00
Danijel Simeunovic 9eb7cdae1b kust2 2026-02-08 16:51:20 +01:00
Danijel Simeunovic 4ffd7b91a0 kust 2026-02-08 16:50:42 +01:00
Danijel Simeunovic 2b9365438a path 2026-02-08 16:06:22 +01:00
Danijel Simeunovic b9392f572c repo 2026-02-08 16:04:49 +01:00
Danijel Simeunovic 0abb69d017 kustomize 2 2026-02-08 16:03:47 +01:00
Danijel Simeunovic fd248d5e89 timeout 2026-02-08 16:02:30 +01:00
Danijel Simeunovic 7f2b904669 kustomize 2026-02-08 16:01:53 +01:00
Danijel Simeunovic 3e943b5405 repo fix 2026-02-08 13:39:31 +01:00
Danijel Simeunovic f9f5806419 timeout 2026-02-08 13:37:33 +01:00
Danijel Simeunovic 08931e4677 app set 2026-02-08 13:36:48 +01:00
Danijel Simeunovic 774852bd1b recurse 2026-02-08 13:32:10 +01:00
Danijel Simeunovic ddcb324bf0 timeout 2026-02-08 13:27:40 +01:00
Danijel Simeunovic 0992b7b1c9 argocd hooks and phases 2026-02-08 12:39:54 +01:00
Danijel Simeunovic f690a1264d remove istio ref 2026-02-08 10:45:04 +01:00
Danijel Simeunovic b371ebb453 edit 2026-02-08 10:42:39 +01:00
Danijel Simeunovic bec3b6310a reorg 2026-02-08 10:42:10 +01:00
Danijel Simeunovic a42e94672e md 2026-02-07 21:41:35 +01:00
Danijel Simeunovic bbc863995d argo report 2026-02-07 21:40:13 +01:00
Danijel Simeunovic 1722807d7c readme 2026-02-07 21:39:16 +01:00
Danijel Simeunovic d487dffef0 delete app 2026-02-07 21:38:20 +01:00
Danijel Simeunovic 45d03792c6 minor adjustments 2026-02-07 21:35:40 +01:00
Danijel Simeunovic bc52bfd3f1 adjustments to argo apps 2026-02-07 21:31:56 +01:00
Danijel Simeunovic 2b591593c0 fluentbit values 2026-02-07 21:28:19 +01:00
Danijel Simeunovic d57387b1e8 readme 2026-02-07 21:21:36 +01:00
Danijel Simeunovic 3e3c806949 readme.md 2026-02-07 21:21:08 +01:00
Danijel Simeunovic a42a07b669 initial 2026-02-07 21:16:15 +01:00
230 changed files with 17910 additions and 25160 deletions
+47
View File
@@ -0,0 +1,47 @@
name: AI Code Review
on:
pull_request:
types: [ labeled, synchronize ]
jobs:
ai-review:
if: >-
(github.event.action == 'synchronized' && contains(toJSON(github.event.pull_request.labels), 'ai-review')) || contains(toJSON(gitea.event.changes.added_labels), 'ai-review')
runs-on: ubuntu-latest
env:
AI_REVIEW_CONFIG_FILE_YAML: ./shared-prompts/iac/.ai-review.yaml
# VCS configuration
VCS__PROVIDER: GITEA
VCS__PIPELINE__OWNER: ${{ github.repository_owner }}
VCS__PIPELINE__REPO: ${{ github.event.repository.name }}
VCS__PIPELINE__PULL_NUMBER: ${{ github.event.pull_request.number }}
VCS__HTTP_CLIENT__API_URL: https://git.forteapps.net/api/v1
VCS__HTTP_CLIENT__API_TOKEN: ${{ secrets.AI_REVIEW_TOKEN }}
# Review — disable fallback to see real Gitea API errors
REVIEW__INLINE_COMMENT_FALLBACK: "false"
# LLM configuration
LLM__PROVIDER: CLAUDE
LLM__META__MODEL: claude-sonnet-4-20250514
LLM__META__MAX_TOKENS: "4096"
LLM__HTTP_CLIENT__API_URL: https://api.anthropic.com
LLM__HTTP_CLIENT__API_TOKEN: ${{ secrets.ANTHROPIC_API_KEY }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: true
fetch-depth: 0
token: ${{ secrets.AI_REVIEW_TOKEN }}
- name: Run inline review
uses: docker://nikitafilonov/ai-review:v0.64.0
with:
args: ai-review run-inline
- name: Run summary review
uses: docker://nikitafilonov/ai-review:v0.64.0
with:
args: ai-review run-summary
+18
View File
@@ -0,0 +1,18 @@
# User-specific files
*.user
*.lock
*.userosscache
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
private/
.helm/
temp/
*.orig
CLAUDE.md
.claude/
devbox.d/
devbox.lock
.devbox/
bash.exe.stackdump
+3
View File
@@ -0,0 +1,3 @@
[submodule "shared-prompts"]
path = shared-prompts
url = https://git.forteapps.net/Forte/ai-review-prompts.git
-460
View File
@@ -1,460 +0,0 @@
<!doctype html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="description" content="Documentation for the GitOps-managed Kubernetes cluster">
<link rel="icon" href="/assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.6">
<title>K8s Launchpad</title>
<link rel="stylesheet" href="/assets/stylesheets/main.484c7ddc.min.css">
<link rel="stylesheet" href="/assets/stylesheets/palette.ab4e12ef.min.css">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback">
<style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style>
<script>__md_scope=new URL("/",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
</head>
<body dir="ltr" data-md-color-scheme="default" data-md-color-primary="indigo" data-md-color-accent="indigo">
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" for="__drawer"></label>
<div data-md-component="skip">
</div>
<div data-md-component="announce">
</div>
<header class="md-header md-header--shadow" data-md-component="header">
<nav class="md-header__inner md-grid" aria-label="Header">
<a href="/." title="K8s Launchpad" class="md-header__button md-logo" aria-label="K8s Launchpad" data-md-component="logo">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"/></svg>
</a>
<label class="md-header__button md-icon" for="__drawer">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg>
</label>
<div class="md-header__title" data-md-component="header-title">
<div class="md-header__ellipsis">
<div class="md-header__topic">
<span class="md-ellipsis">
K8s Launchpad
</span>
</div>
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
</span>
</div>
</div>
</div>
<form class="md-header__option" data-md-component="palette">
<input class="md-option" data-md-color-media="" data-md-color-scheme="default" data-md-color-primary="indigo" data-md-color-accent="indigo" aria-label="Switch to dark mode" type="radio" name="__palette" id="__palette_0">
<label class="md-header__button md-icon" title="Switch to dark mode" for="__palette_1" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a4 4 0 0 0-4 4 4 4 0 0 0 4 4 4 4 0 0 0 4-4 4 4 0 0 0-4-4m0 10a6 6 0 0 1-6-6 6 6 0 0 1 6-6 6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z"/></svg>
</label>
<input class="md-option" data-md-color-media="" data-md-color-scheme="slate" data-md-color-primary="indigo" data-md-color-accent="indigo" aria-label="Switch to light mode" type="radio" name="__palette" id="__palette_1">
<label class="md-header__button md-icon" title="Switch to light mode" for="__palette_0" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 18c-.89 0-1.74-.2-2.5-.55C11.56 16.5 13 14.42 13 12s-1.44-4.5-3.5-5.45C10.26 6.2 11.11 6 12 6a6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z"/></svg>
</label>
</form>
<script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
<label class="md-header__button md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
</label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
<label class="md-search__icon md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
</label>
<nav class="md-search__options" aria-label="Search">
<button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
</button>
</nav>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" tabindex="0" data-md-scrollfix>
<div class="md-search-result" data-md-component="search-result">
<div class="md-search-result__meta">
Initializing search
</div>
<ol class="md-search-result__list" role="presentation"></ol>
</div>
</div>
</div>
</div>
</div>
<div class="md-header__source">
<a href="https://git.forteapps.net/Forte/launchpad" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M439.6 236.1 244 40.5c-5.4-5.5-12.8-8.5-20.4-8.5s-15 3-20.4 8.4L162.5 81l51.5 51.5c27.1-9.1 52.7 16.8 43.4 43.7l49.7 49.7c34.2-11.8 61.2 31 35.5 56.7-26.5 26.5-70.2-2.9-56-37.3L240.3 199v121.9c25.3 12.5 22.3 41.8 9.1 55-6.4 6.4-15.2 10.1-24.3 10.1s-17.8-3.6-24.3-10.1c-17.6-17.6-11.1-46.9 11.2-56v-123c-20.8-8.5-24.6-30.7-18.6-45L142.6 101 8.5 235.1C3 240.6 0 247.9 0 255.5s3 15 8.5 20.4l195.6 195.7c5.4 5.4 12.7 8.4 20.4 8.4s15-3 20.4-8.4l194.7-194.7c5.4-5.4 8.4-12.8 8.4-20.4s-3-15-8.4-20.4"/></svg>
</div>
<div class="md-source__repository">
Forte/launchpad
</div>
</a>
</div>
</nav>
</header>
<div class="md-container" data-md-component="container">
<main class="md-main" data-md-component="main">
<div class="md-main__inner md-grid">
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary" aria-label="Navigation" data-md-level="0">
<label class="md-nav__title" for="__drawer">
<a href="/." title="K8s Launchpad" class="md-nav__button md-logo" aria-label="K8s Launchpad" data-md-component="logo">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"/></svg>
</a>
K8s Launchpad
</label>
<div class="md-nav__source">
<a href="https://git.forteapps.net/Forte/launchpad" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M439.6 236.1 244 40.5c-5.4-5.5-12.8-8.5-20.4-8.5s-15 3-20.4 8.4L162.5 81l51.5 51.5c27.1-9.1 52.7 16.8 43.4 43.7l49.7 49.7c34.2-11.8 61.2 31 35.5 56.7-26.5 26.5-70.2-2.9-56-37.3L240.3 199v121.9c25.3 12.5 22.3 41.8 9.1 55-6.4 6.4-15.2 10.1-24.3 10.1s-17.8-3.6-24.3-10.1c-17.6-17.6-11.1-46.9 11.2-56v-123c-20.8-8.5-24.6-30.7-18.6-45L142.6 101 8.5 235.1C3 240.6 0 247.9 0 255.5s3 15 8.5 20.4l195.6 195.7c5.4 5.4 12.7 8.4 20.4 8.4s15-3 20.4-8.4l194.7-194.7c5.4-5.4 8.4-12.8 8.4-20.4s-3-15-8.4-20.4"/></svg>
</div>
<div class="md-source__repository">
Forte/launchpad
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="/." class="md-nav__link">
<span class="md-ellipsis">
Home
</span>
</a>
</li>
<li class="md-nav__item">
<a href="/GITOPS-ARCHITECTURE/" class="md-nav__link">
<span class="md-ellipsis">
GitOps Architecture
</span>
</a>
</li>
<li class="md-nav__item">
<a href="/DEVELOPER-GUIDE/" class="md-nav__link">
<span class="md-ellipsis">
Developer Guide
</span>
</a>
</li>
<li class="md-nav__item">
<a href="/OPERATIONS-RUNBOOK/" class="md-nav__link">
<span class="md-ellipsis">
Operations Runbook
</span>
</a>
</li>
<li class="md-nav__item">
<a href="/REFERENCE/" class="md-nav__link">
<span class="md-ellipsis">
Technical Reference
</span>
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
</nav>
</div>
</div>
</div>
<div class="md-content" data-md-component="content">
<article class="md-content__inner md-typeset">
<h1>404 - Not found</h1>
</article>
</div>
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
</div>
<button type="button" class="md-top md-icon" data-md-component="top" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8z"/></svg>
Back to top
</button>
</main>
<footer class="md-footer">
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-copyright">
Made with
<a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
Material for MkDocs
</a>
</div>
</div>
</div>
</footer>
</div>
<div class="md-dialog" data-md-component="dialog">
<div class="md-dialog__inner md-typeset"></div>
</div>
<script id="__config" type="application/json">{"annotate": null, "base": "/", "features": ["navigation.instant", "navigation.sections", "navigation.top", "search.highlight", "content.code.copy"], "search": "/assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
<script src="/assets/javascripts/bundle.79ae519e.min.js"></script>
</body>
</html>
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+520
View File
@@ -0,0 +1,520 @@
# Kubernetes Cluster - GitOps Configuration
> **Kubernetes cluster bootstrapping and GitOps configuration repository** using ArgoCD for multi-cloud Kubernetes (UpCloud, AWS EKS, Azure AKS, GCP GKE)
[![GitOps](https://img.shields.io/badge/GitOps-ArgoCD-blue)](https://argoproj.github.io/cd/)
[![Kubernetes](https://img.shields.io/badge/Kubernetes-Multi--Cloud-orange)]()
---
## 📚 Complete Documentation
**New developers and operators**: Please refer to our comprehensive documentation for detailed guides and references:
### 🎯 [**START HERE: Documentation Index**](docs/README.md)
| Document | Description | Audience |
|----------|-------------|----------|
| **[GitOps Architecture](docs/GITOPS-ARCHITECTURE.md)** | System architecture, repository structure, GitOps workflows, security model | Everyone (start here) |
| **[Developer Guide](docs/DEVELOPER-GUIDE.md)** | Local setup, deploying apps, managing secrets, troubleshooting | Developers |
| **[Operations Runbook](docs/OPERATIONS-RUNBOOK.md)** | Cluster bootstrap, day-to-day operations, incident response, maintenance | Platform Engineers, SREs |
| **[Technical Reference](docs/REFERENCE.md)** | Component specs, Helm charts, ArgoCD config, Kyverno policies, API docs | Everyone (reference) |
---
## 🚀 Quick Start
### For New Developers
```bash
# 1. Clone repositories
git clone https://git.forteapps.net/Forte/launchpad.git
git clone ssh://git@git.forteapps.net:2222/Forte/helm-prod-values.git
# 2. Read the guides
# - Start: docs/GITOPS-ARCHITECTURE.md
# - Follow: docs/DEVELOPER-GUIDE.md
# 3. Deploy your first app (see Developer Guide)
```
### For Operators
```bash
# 1. Bootstrap new cluster
./bootstrap.sh
# 2. Verify deployment
kubectl get applications -n argocd
kubectl get pods --all-namespaces
# 3. Read Operations Runbook for day-to-day tasks
```
---
## 📋 Overview
This repository contains the complete GitOps configuration for our Kubernetes cluster, using the **App-of-Apps pattern** with ArgoCD.
### What's Inside
- **Infrastructure Applications**: Traefik, Cert-Manager, Kyverno, Prometheus, Grafana, Loki, Tempo, Sealed Secrets
- **Business Applications**: MCP10X, MusicMan, Dot-AI Stack, ArgoCD MCP
- **Policies**: Kyverno security policies for secret management, namespace controls, pod verification
- **Monitoring**: Full observability stack with metrics, logs, traces, and alerting
- **Secrets**: Sealed Secrets for secure Git storage
### Key Features
**GitOps-Native**: Git is the single source of truth
**Auto-Sync**: Changes automatically deployed (60s reconciliation)
**Self-Healing**: Manual cluster changes are reverted
**Multi-Source**: Separate chart templates from configuration
**Policy Enforcement**: Kyverno ensures security and compliance
**Authentication**: Automatic sidecar injection (token & OIDC support)
**TLS Everywhere**: Automatic Let's Encrypt certificates
**Full Observability**: Prometheus, Grafana, Loki, Tempo integration
---
## 🗂️ Repository Structure
```
.
├── bootstrap.sh # Cluster initialization script
├── _app-of-apps.yaml # Root ArgoCD Application (App-of-Apps pattern)
├── infra/ # Infrastructure ArgoCD Applications (Kustomize multi-cluster)
│ ├── base/ # Base ArgoCD Application manifests (EU defaults)
│ │ ├── kustomization.yaml
│ │ ├── traefik-application.yaml
│ │ ├── keycloak.yaml
│ │ ├── grafana.yaml
│ │ ├── gitea.yaml
│ │ ├── gitea-actions.yaml
│ │ ├── tempo.yaml
│ │ ├── renovate.yaml
│ │ ├── ... # All other Application manifests
│ │ └── secrets.yaml
│ ├── overlays/ # Per-cluster overrides (Kustomize)
│ │ ├── upc-dev/ # UpCloud Dev (uses base as-is)
│ │ ├── upc-prod/ # UpCloud Prod (patches value paths)
│ │ ├── eks-dev/ # AWS EKS Dev
│ │ ├── eks-prod/ # AWS EKS Prod
│ │ ├── aks-dev/ # Azure AKS Dev
│ │ ├── aks-prod/ # Azure AKS Prod
│ │ ├── gke-dev/ # GCP GKE Dev
│ │ └── gke-prod/ # GCP GKE Prod
│ ├── dashboards/ # Grafana dashboard ConfigMaps
│ └── values/ # Helm value overrides
│ ├── base/ # Shared cloud-agnostic values
│ ├── upc-dev/ # UpCloud Dev (storage, LB, pricing)
│ ├── upc-prod/ # UpCloud Prod
│ ├── eks-dev/ # AWS EKS Dev
│ ├── eks-prod/ # AWS EKS Prod
│ ├── aks-dev/ # Azure AKS Dev
│ ├── aks-prod/ # Azure AKS Prod
│ ├── gke-dev/ # GCP GKE Dev
│ └── gke-prod/ # GCP GKE Prod
├── apps/ # Business Applications
│ ├── mcp10x.yaml
│ ├── musicman.yaml
│ ├── dot-ai-stack.yaml
│ └── argo-mcp.yaml
├── cluster-resources/ # Cluster-wide Kubernetes resources
│ ├── letsencrypt-issuer.yaml
│ ├── kyverno-config.yaml
│ ├── *-sealed.yaml # Sealed secrets
│ └── policies/ # Kyverno policies
│ ├── secret-cloner.yaml
│ ├── default-ns-blocker.yaml
│ ├── bare-pod-cleaner.yaml
│ └── auth-sidecar-injector.yaml
├── secrets/ # Application secrets (sealed)
│ └── *-credentials-sealed.yaml
├── private/ # Local-only files (Git-ignored)
│ └── *.yaml # Unsealed secrets (never committed)
└── docs/ # 📚 Comprehensive documentation
├── README.md # Documentation index
├── GITOPS-ARCHITECTURE.md # Architecture guide
├── DEVELOPER-GUIDE.md # Developer onboarding
├── OPERATIONS-RUNBOOK.md # Operations procedures
└── REFERENCE.md # Technical reference
```
**See [GitOps Architecture - Repository Structure](docs/GITOPS-ARCHITECTURE.md#repository-structure) for detailed explanation.**
---
## 🏗️ Architecture
### Three-Repository Pattern
| Repository | Purpose | Who Edits | How Often |
|------------|---------|-----------|-----------|
| **[launchpad](https://git.forteapps.net/Forte/launchpad)** (this repo) | ArgoCD Applications, cluster resources | Platform / DevOps engineers | ✅ Often |
| **[forte-helm](https://git.forteapps.net/Forte/forte-helm)** | Generic Helm chart templates | Platform engineers | ❌ Rarely |
| **[helm-prod-values](ssh://git@git.forteapps.net:2222/Forte/helm-prod-values.git)** | App-specific configuration & versions | Developers / CI pipelines | ✅ Sometimes |
### GitOps Workflow
```
Developer commits code → CI/CD builds image → Updates helm-prod-values → ArgoCD syncs → Deployed to cluster
```
**Learn more**: [GitOps Architecture - GitOps Workflow](docs/GITOPS-ARCHITECTURE.md#gitops-workflow)
---
## 🔧 Common Tasks
### Deploy a New Application
**See detailed guide**: [Developer Guide - Deploying Your First Application](docs/DEVELOPER-GUIDE.md#deploying-your-first-application)
**Quick version**:
1. Create `apps/myapp.yaml` (ArgoCD Application manifest)
2. Create `helm-prod-values/myapp/values.yaml` (configuration)
3. Create sealed secrets if needed
4. Commit and push - ArgoCD auto-syncs!
### Update an Existing Application
**See detailed guide**: [Developer Guide - Updating an Existing Application](docs/DEVELOPER-GUIDE.md#updating-an-existing-application)
**Quick version**:
- **Update code**: Push to app repo → CI/CD updates image tag in helm-prod-values
- **Update config**: Edit `helm-prod-values/myapp/values.yaml` → commit → push
### Manage Secrets
**See detailed guide**: [Developer Guide - Working with Secrets](docs/DEVELOPER-GUIDE.md#working-with-secrets)
```bash
# Create plain secret
kubectl create secret generic myapp-creds \
--from-literal=KEY=value \
--dry-run=client -o yaml > private/myapp-creds.yaml
# Seal it
kubeseal --format=yaml --cert=pub-cert.pem \
< private/myapp-creds.yaml > secrets/myapp-creds-sealed.yaml
# Commit sealed version
git add secrets/myapp-creds-sealed.yaml
git commit -m "Add myapp credentials"
git push
```
### Enable Authentication
**See detailed guide**: [Developer Guide - Enabling Authentication](docs/DEVELOPER-GUIDE.md#enabling-authentication-for-applications)
**Quick version**:
```yaml
# In helm-prod-values/myapp/values.yaml
# Token-based auth (simple)
auth:
enabled: true
type: token
tokens:
- your-secret-token-here
# OIDC auth (SSO)
auth:
enabled: true
type: oidc
oidc:
authority: https://auth.example.com/realms/master
clientId: myapp
```
Then create OIDC secret (if using OIDC):
```bash
kubectl create secret generic auth-oidc \
--from-literal=client-secret=your-oidc-secret \
--from-literal=cookie-secret=$(openssl rand -hex 32) \
--namespace=myapp | \
kubeseal --format=yaml --cert=pub-cert.pem --namespace=myapp | \
kubectl apply -f -
```
### Bootstrap Cluster
**See detailed guide**: [Operations Runbook - Cluster Bootstrap](docs/OPERATIONS-RUNBOOK.md#cluster-bootstrap)
```bash
# Initialize new cluster
./bootstrap.sh
# Verify
kubectl get applications -n argocd
kubectl get pods --all-namespaces
```
---
## 🛠️ Quick Reference
### Monitor Applications
```bash
# List all ArgoCD applications
kubectl get applications -n argocd
# Watch sync status
kubectl get applications -n argocd -w
# Check specific application
kubectl describe application myapp -n argocd
# View application logs
kubectl logs -n myapp <pod-name>
```
### Access UIs
```bash
# ArgoCD UI
kubectl port-forward svc/argocd-server -n argocd 8080:443
# Access: https://localhost:8080 (no auth required)
# Grafana
kubectl port-forward -n monitoring svc/grafana 3000:80
# Access: http://localhost:3000
# Prometheus
kubectl port-forward -n monitoring svc/prometheus-server 9090:80
# Access: http://localhost:9090
```
### Troubleshooting
```bash
# Check pod status
kubectl get pods -n myapp
# View pod logs
kubectl logs -n myapp <pod-name>
# Check pod events
kubectl describe pod -n myapp <pod-name>
# Check ArgoCD sync errors
kubectl describe application myapp -n argocd
# Force sync
kubectl patch application myapp -n argocd \
--type merge -p '{"metadata":{"annotations":{"argocd.argoproj.io/refresh":"hard"}}}'
```
**Full troubleshooting guide**: [Developer Guide - Troubleshooting](docs/DEVELOPER-GUIDE.md#troubleshooting)
---
## 🔐 Security
### Secret Management
- ✅ Sealed Secrets for Git storage
- ✅ Kyverno auto-clones secrets to namespaces
- ❌ Never commit plain secrets
### Network Security
- ✅ All traffic TLS-encrypted (Let's Encrypt)
- ✅ HTTP → HTTPS redirect
- ✅ Traefik IngressRoute per application
### Policy Enforcement
- ✅ Kyverno policies for security
- ✅ Default namespace blocked
- ✅ Bare pods not allowed
- ✅ Optional authentication sidecar injection
**Learn more**: [GitOps Architecture - Security Model](docs/GITOPS-ARCHITECTURE.md#security-model)
---
## 📊 Infrastructure Components
| Component | Purpose | Namespace | Replicas |
|-----------|---------|-----------|----------|
| **ArgoCD** | GitOps controller | `argocd` | 1 |
| **Traefik** | Ingress controller | `traefik` | 2 |
| **Cert-Manager** | TLS certificates | `cert-manager` | 1 |
| **Kyverno** | Policy engine | `kyverno` | 1 |
| **Sealed Secrets** | Secret encryption | `kube-system` | 1 |
| **Prometheus** | Metrics | `monitoring` | 1 |
| **Grafana** | Dashboards | `monitoring` | 1 |
| **Loki** | Logs | `monitoring` | 1 |
| **Tempo** | Distributed tracing | `monitoring` | 1 |
| **Fluent-Bit** | Log shipping | `monitoring` | DaemonSet |
| **OpenCost** | Cost monitoring | `monitoring` | 1 |
| **Renovate** | Dependency updates | `renovate` | CronJob |
| **Trivy** | Vulnerability scanning | `trivy-system` | 1 |
**Full specs**: [Technical Reference - Infrastructure Components](docs/REFERENCE.md#infrastructure-components)
---
## 🌐 Domains & Networking
- **Local development**: `*.127.0.0.1.nip.io`
- **Production**: `*.forteapps.net`
- **DNS**: Manual configuration (contact platform team)
- **TLS**: Automatic via Let's Encrypt
---
## 📖 Key Concepts
### App-of-Apps Pattern
`_app-of-apps-{cluster}.yaml` is the root Application that manages all other Applications in `infra/`. Kustomize overlays in `infra/overlays/{cluster}/` render the base Applications with per-cluster patches (e.g., swapping value file paths). Supported clusters: `upc-dev`, `upc-prod`, `eks-dev`, `eks-prod`, `aks-dev`, `aks-prod`, `gke-dev`, `gke-prod`.
### Multi-Source Pattern
Applications reference both:
1. **Helm charts** from `forte-helm` (templates)
2. **Values** from `helm-prod-values` (configuration)
This separates reusable templates from environment-specific config.
### Sync Waves
Applications deploy in order using `argocd.argoproj.io/sync-wave`:
- Wave `-1`: Namespaces
- Wave `0`: Kyverno (policies)
- Wave `1`: Infrastructure
- Wave `2+`: Applications
### Auto-Sync & Self-Heal
- **Auto-Sync**: ArgoCD automatically deploys Git changes (60s polling)
- **Self-Heal**: Manual cluster changes are reverted to match Git
- **Prune**: Deleted resources in Git are removed from cluster
**Learn more**: [GitOps Architecture - GitOps Workflow](docs/GITOPS-ARCHITECTURE.md#gitops-workflow)
---
## ⚙️ Configuration
### ArgoCD Settings
- **Reconciliation**: Every 60 seconds
- **Sync timeout**: 5 minutes per application
- **Retry policy**: 5 attempts with exponential backoff
- **Authentication**: Disabled (internal use only)
### Application Defaults
- **Auto-sync**: Enabled
- **Self-heal**: Enabled
- **Prune**: Enabled
- **Validation**: Server-side validation enabled
- **Server-side apply**: Enabled
**Full configuration**: [Technical Reference - ArgoCD Configuration](docs/REFERENCE.md#argocd-configuration)
---
## 🆘 Getting Help
### Documentation
1. **Start here**: [Documentation Index](docs/README.md)
2. **For development**: [Developer Guide](docs/DEVELOPER-GUIDE.md)
3. **For operations**: [Operations Runbook](docs/OPERATIONS-RUNBOOK.md)
4. **For reference**: [Technical Reference](docs/REFERENCE.md)
### Support
- **Slack**: #platform-support
- **Issues**: Contact platform team
- **Emergencies**: Escalate via Slack
### Common Questions
| Question | Answer |
|----------|--------|
| How do I deploy an app? | [Developer Guide - Deploying Your First Application](docs/DEVELOPER-GUIDE.md#deploying-your-first-application) |
| How do I manage secrets? | [Developer Guide - Working with Secrets](docs/DEVELOPER-GUIDE.md#working-with-secrets) |
| App won't sync? | [Developer Guide - Troubleshooting](docs/DEVELOPER-GUIDE.md#troubleshooting) |
| How do I bootstrap a cluster? | [Operations Runbook - Cluster Bootstrap](docs/OPERATIONS-RUNBOOK.md#cluster-bootstrap) |
| Where are the logs? | [Operations Runbook - Monitoring & Alerting](docs/OPERATIONS-RUNBOOK.md#monitoring--alerting) |
---
## 🤝 Contributing
### Adding a New Application
1. Read [Developer Guide - Deploying Your First Application](docs/DEVELOPER-GUIDE.md#deploying-your-first-application)
2. Create ArgoCD Application manifest in `apps/`
3. Create Helm values in `helm-prod-values/`
4. Create sealed secrets if needed
5. Commit and push - ArgoCD handles the rest!
### Modifying Infrastructure
1. Read [Operations Runbook](docs/OPERATIONS-RUNBOOK.md)
2. Update relevant files in `infra/` or `cluster-resources/`
3. Test changes in isolated namespace if possible
4. Commit and push
5. Monitor sync status in Slack/ArgoCD UI
### Updating Documentation
Documentation lives in `docs/`. To update:
1. Edit relevant markdown file
2. Update "Last Updated" date
3. Submit PR or push directly
4. Notify team of significant changes
---
## 📝 Notes
### Current Environment
- **Provider**: Multi-cloud (UpCloud, AWS EKS, Azure AKS, GCP GKE)
- **Active clusters**: UpCloud (upc-dev, upc-prod)
- **Environment**: Production (internal use only)
- **Auth**: Disabled for ArgoCD (internal access)
- **Backup**: Gitea daily backup to S3-compatible storage
### Known Limitations
- Secret rotation not automated
- DNS management is manual
**Future improvements**: See [Operations Runbook - Disaster Recovery](docs/OPERATIONS-RUNBOOK.md#disaster-recovery)
---
## 📚 Additional Resources
### External Documentation
- [ArgoCD Documentation](https://argo-cd.readthedocs.io/)
- [Kyverno Documentation](https://kyverno.io/docs/)
- [Traefik Documentation](https://doc.traefik.io/traefik/)
- [Cert-Manager Documentation](https://cert-manager.io/docs/)
- [Grafana Tempo Documentation](https://grafana.com/docs/tempo/)
- [Sealed Secrets](https://github.com/bitnami-labs/sealed-secrets)
### Related Repositories
- [forte-helm](https://git.forteapps.net/Forte/forte-helm) - Helm chart templates
- [helm-prod-values](git@github.com:fortedigital/helm-prod-values.git) - Application values
---
## 📄 License
Internal use only. Not for public distribution.
---
## 👥 Maintainers
**Platform Team**
- Contact: #platform-support on Slack
- Issues: Create issue in repository or contact team directly
---
**Last Updated**: 2026-04-22
**Documentation Version**: 1.0.0
**🚀 Ready to get started? Check out the [Documentation Index](docs/README.md)!**
-4220
View File
File diff suppressed because it is too large Load Diff
+32
View File
@@ -0,0 +1,32 @@
apiVersion: v1
kind: Namespace
metadata:
name: monitoring
annotations:
argocd.argoproj.io/sync-wave: "-1"
---
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: infrastructure-apps
namespace: argocd
labels:
app.kubernetes.io/name: infrastructure-apps
app.kubernetes.io/part-of: platform
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
source:
repoURL: ssh://git@git.forteapps.net:2222/Forte/launchpad.git
targetRevision: HEAD
path: infra/overlays/aks-dev
destination:
server: https://kubernetes.default.svc
namespace: default
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
+32
View File
@@ -0,0 +1,32 @@
apiVersion: v1
kind: Namespace
metadata:
name: monitoring
annotations:
argocd.argoproj.io/sync-wave: "-1"
---
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: infrastructure-apps
namespace: argocd
labels:
app.kubernetes.io/name: infrastructure-apps
app.kubernetes.io/part-of: platform
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
source:
repoURL: ssh://git@git.forteapps.net:2222/Forte/launchpad.git
targetRevision: HEAD
path: infra/overlays/aks-prod
destination:
server: https://kubernetes.default.svc
namespace: default
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
+32
View File
@@ -0,0 +1,32 @@
apiVersion: v1
kind: Namespace
metadata:
name: monitoring
annotations:
argocd.argoproj.io/sync-wave: "-1"
---
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: infrastructure-apps
namespace: argocd
labels:
app.kubernetes.io/name: infrastructure-apps
app.kubernetes.io/part-of: platform
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
source:
repoURL: ssh://git@git.forteapps.net:2222/Forte/launchpad.git
targetRevision: HEAD
path: infra/overlays/eks-dev
destination:
server: https://kubernetes.default.svc
namespace: default
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
+32
View File
@@ -0,0 +1,32 @@
apiVersion: v1
kind: Namespace
metadata:
name: monitoring
annotations:
argocd.argoproj.io/sync-wave: "-1"
---
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: infrastructure-apps
namespace: argocd
labels:
app.kubernetes.io/name: infrastructure-apps
app.kubernetes.io/part-of: platform
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
source:
repoURL: ssh://git@git.forteapps.net:2222/Forte/launchpad.git
targetRevision: HEAD
path: infra/overlays/eks-prod
destination:
server: https://kubernetes.default.svc
namespace: default
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
+32
View File
@@ -0,0 +1,32 @@
apiVersion: v1
kind: Namespace
metadata:
name: monitoring
annotations:
argocd.argoproj.io/sync-wave: "-1"
---
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: infrastructure-apps
namespace: argocd
labels:
app.kubernetes.io/name: infrastructure-apps
app.kubernetes.io/part-of: platform
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
source:
repoURL: ssh://git@git.forteapps.net:2222/Forte/launchpad.git
targetRevision: HEAD
path: infra/overlays/gke-dev
destination:
server: https://kubernetes.default.svc
namespace: default
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
+32
View File
@@ -0,0 +1,32 @@
apiVersion: v1
kind: Namespace
metadata:
name: monitoring
annotations:
argocd.argoproj.io/sync-wave: "-1"
---
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: infrastructure-apps
namespace: argocd
labels:
app.kubernetes.io/name: infrastructure-apps
app.kubernetes.io/part-of: platform
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
source:
repoURL: ssh://git@git.forteapps.net:2222/Forte/launchpad.git
targetRevision: HEAD
path: infra/overlays/gke-prod
destination:
server: https://kubernetes.default.svc
namespace: default
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
+32
View File
@@ -0,0 +1,32 @@
apiVersion: v1
kind: Namespace
metadata:
name: monitoring
annotations:
argocd.argoproj.io/sync-wave: "-1"
---
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: infrastructure-apps
namespace: argocd
labels:
app.kubernetes.io/name: infrastructure-apps
app.kubernetes.io/part-of: platform
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
source:
repoURL: ssh://git@git.forteapps.net:2222/Forte/launchpad.git
targetRevision: HEAD
path: infra/overlays/upc-dev
destination:
server: https://kubernetes.default.svc
namespace: default
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
+32
View File
@@ -0,0 +1,32 @@
apiVersion: v1
kind: Namespace
metadata:
name: monitoring
annotations:
argocd.argoproj.io/sync-wave: "-1"
---
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: infrastructure-apps
namespace: argocd
labels:
app.kubernetes.io/name: infrastructure-apps
app.kubernetes.io/part-of: platform
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
source:
repoURL: ssh://git@git.forteapps.net:2222/Forte/launchpad.git
targetRevision: HEAD
path: infra/overlays/upc-prod
destination:
server: https://kubernetes.default.svc
namespace: default
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
+38
View File
@@ -0,0 +1,38 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: argocd-mcp
namespace: argocd
annotations:
argocd.argoproj.io/sync-wave: "1"
notifications.argoproj.io/subscribe.on-sync-failed.slack: ""
notifications.argoproj.io/subscribe.on-degraded.slack: ""
labels:
app.kubernetes.io/name: argocd-mcp
app.kubernetes.io/part-of: apps
app.kubernetes.io/managed-by: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
sources:
- repoURL: ssh://git@git.forteapps.net:2222/Forte/forte-helm.git
path: forteapp
targetRevision: HEAD
helm:
valueFiles:
- $values/argocd-mcp/values.yaml
- repoURL: ssh://git@git.forteapps.net:2222/Forte/helm-prod-values.git
targetRevision: HEAD
ref: values
destination:
server: https://kubernetes.default.svc
namespace: argocd-mcp
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
+70
View File
@@ -0,0 +1,70 @@
---
# Namespace must be created first (sync-wave: -1)
apiVersion: v1
kind: Namespace
metadata:
name: dot-ai
annotations:
argocd.argoproj.io/sync-wave: "-1"
---
# ArgoCD Application syncs last (sync-wave: 1)
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: dot-ai-stack
namespace: argocd
annotations:
argocd.argoproj.io/sync-wave: "1"
notifications.argoproj.io/subscribe.on-sync-succeeded.slack: ""
notifications.argoproj.io/subscribe.on-sync-failed.slack: ""
notifications.argoproj.io/subscribe.on-degraded.slack: ""
labels:
app.kubernetes.io/name: dot-ai-stack
app.kubernetes.io/part-of: apps
app.kubernetes.io/managed-by: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
sources:
- repoURL: ghcr.io/vfarcic/dot-ai-stack/charts
chart: dot-ai-stack
targetRevision: "0.56.0"
helm:
releaseName: dot-ai-stack
valueFiles:
- $values/infra/values/base/dot-ai-stack-values.yaml
- $values/infra/values/upc-dev/dot-ai-stack-values.yaml
- repoURL: ssh://git@git.forteapps.net:2222/Forte/launchpad.git
targetRevision: HEAD
ref: values
destination:
server: https://kubernetes.default.svc
namespace: dot-ai
syncPolicy:
automated:
prune: true
selfHeal: true
allowEmpty: false
syncOptions:
- Validate=true
- ServerSideApply=true
- Replace=false
retry:
limit: 5
backoff:
duration: 5s
factor: 2
maxDuration: 3m
ignoreDifferences:
- group: apps
kind: StatefulSet
jsonPointers:
- /spec/volumeClaimTemplates
+8
View File
@@ -0,0 +1,8 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- dot-ai-stack.yaml
- mcp10x.yaml
- musicman.yaml
- ts-mcp.yaml
- argo-mcp.yaml
+39
View File
@@ -0,0 +1,39 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: mcp10x
namespace: argocd
annotations:
argocd.argoproj.io/sync-wave: "1"
notifications.argoproj.io/subscribe.on-sync-succeeded.slack: ""
notifications.argoproj.io/subscribe.on-sync-failed.slack: ""
notifications.argoproj.io/subscribe.on-degraded.slack: ""
labels:
app.kubernetes.io/name: mcp10x
app.kubernetes.io/part-of: apps
app.kubernetes.io/managed-by: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
sources:
- repoURL: ssh://git@git.forteapps.net:2222/Forte/forte-helm.git
path: forteapp
targetRevision: HEAD
helm:
valueFiles:
- $values/mcp10x/values.yaml
- repoURL: ssh://git@git.forteapps.net:2222/Forte/helm-prod-values.git
targetRevision: HEAD
ref: values
destination:
server: https://kubernetes.default.svc
namespace: mcp10x
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
+57
View File
@@ -0,0 +1,57 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: music-man
namespace: argocd
annotations:
argocd.argoproj.io/sync-wave: "11"
notifications.argoproj.io/subscribe.on-sync-succeeded.slack: ""
notifications.argoproj.io/subscribe.on-sync-failed.slack: ""
notifications.argoproj.io/subscribe.on-degraded.slack: ""
labels:
app.kubernetes.io/name: music-man
app.kubernetes.io/part-of: apps
app.kubernetes.io/managed-by: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
sources:
- repoURL: ssh://git@git.forteapps.net:2222/Forte/forte-helm.git
path: forteapp
targetRevision: HEAD
helm:
valueFiles:
- $values/musicman/values.yaml
- repoURL: ssh://git@git.forteapps.net:2222/Forte/helm-prod-values.git
targetRevision: HEAD
ref: values
destination:
server: https://kubernetes.default.svc
namespace: music-man
syncPolicy:
automated:
prune: true
selfHeal: true
allowEmpty: false
syncOptions:
- CreateNamespace=true
- Validate=true
- ServerSideApply=false
- Replace=false
retry:
limit: 5
backoff:
duration: 5s
factor: 2
maxDuration: 3m
ignoreDifferences:
- group: apps
kind: Deployment
jsonPointers:
- /spec/replicas
+40
View File
@@ -0,0 +1,40 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: ts-mcp
namespace: argocd
annotations:
argocd.argoproj.io/sync-wave: "11"
notifications.argoproj.io/subscribe.on-sync-succeeded.slack: ""
notifications.argoproj.io/subscribe.on-sync-failed.slack: ""
notifications.argoproj.io/subscribe.on-degraded.slack: ""
labels:
app.kubernetes.io/name: ts-mcp
app.kubernetes.io/part-of: apps
app.kubernetes.io/managed-by: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
sources:
- repoURL: ssh://git@git.forteapps.net:2222/Forte/forte-helm.git
path: forteapp
targetRevision: HEAD
helm:
valueFiles:
- $values/ts-mcp/values.yaml
- repoURL: ssh://git@git.forteapps.net:2222/Forte/helm-prod-values.git
targetRevision: HEAD
ref: values
destination:
server: https://kubernetes.default.svc
namespace: ts-mcp
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
+7
View File
@@ -0,0 +1,7 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
# No patches needed — base already has "upc-dev" paths
# upc-dev is the default/base cluster
+14
View File
@@ -0,0 +1,14 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
patches:
# dot-ai-stack: swap upc-dev → upc-prod
- target:
kind: Application
name: dot-ai-stack
patch: |
- op: replace
path: /spec/sources/0/helm/valueFiles/1
value: $values/infra/values/upc-prod/dot-ai-stack-values.yaml
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
-18
View File
@@ -1,18 +0,0 @@
/*!
* Lunr languages, `Danish` language
* https://github.com/MihaiValentin/lunr-languages
*
* Copyright 2014, Mihai Valentin
* http://www.mozilla.org/MPL/
*/
/*!
* based on
* Snowball JavaScript Library v0.3
* http://code.google.com/p/urim/
* http://snowball.tartarus.org/
*
* Copyright 2010, Oleg Mazko
* http://www.mozilla.org/MPL/
*/
!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.da=function(){this.pipeline.reset(),this.pipeline.add(e.da.trimmer,e.da.stopWordFilter,e.da.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.da.stemmer))},e.da.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.da.trimmer=e.trimmerSupport.generateTrimmer(e.da.wordCharacters),e.Pipeline.registerFunction(e.da.trimmer,"trimmer-da"),e.da.stemmer=function(){var r=e.stemmerSupport.Among,i=e.stemmerSupport.SnowballProgram,n=new function(){function e(){var e,r=f.cursor+3;if(d=f.limit,0<=r&&r<=f.limit){for(a=r;;){if(e=f.cursor,f.in_grouping(w,97,248)){f.cursor=e;break}if(f.cursor=e,e>=f.limit)return;f.cursor++}for(;!f.out_grouping(w,97,248);){if(f.cursor>=f.limit)return;f.cursor++}d=f.cursor,d<a&&(d=a)}}function n(){var e,r;if(f.cursor>=d&&(r=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,e=f.find_among_b(c,32),f.limit_backward=r,e))switch(f.bra=f.cursor,e){case 1:f.slice_del();break;case 2:f.in_grouping_b(p,97,229)&&f.slice_del()}}function t(){var e,r=f.limit-f.cursor;f.cursor>=d&&(e=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,f.find_among_b(l,4)?(f.bra=f.cursor,f.limit_backward=e,f.cursor=f.limit-r,f.cursor>f.limit_backward&&(f.cursor--,f.bra=f.cursor,f.slice_del())):f.limit_backward=e)}function s(){var e,r,i,n=f.limit-f.cursor;if(f.ket=f.cursor,f.eq_s_b(2,"st")&&(f.bra=f.cursor,f.eq_s_b(2,"ig")&&f.slice_del()),f.cursor=f.limit-n,f.cursor>=d&&(r=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,e=f.find_among_b(m,5),f.limit_backward=r,e))switch(f.bra=f.cursor,e){case 1:f.slice_del(),i=f.limit-f.cursor,t(),f.cursor=f.limit-i;break;case 2:f.slice_from("løs")}}function o(){var e;f.cursor>=d&&(e=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,f.out_grouping_b(w,97,248)?(f.bra=f.cursor,u=f.slice_to(u),f.limit_backward=e,f.eq_v_b(u)&&f.slice_del()):f.limit_backward=e)}var a,d,u,c=[new r("hed",-1,1),new r("ethed",0,1),new r("ered",-1,1),new r("e",-1,1),new r("erede",3,1),new r("ende",3,1),new r("erende",5,1),new r("ene",3,1),new r("erne",3,1),new r("ere",3,1),new r("en",-1,1),new r("heden",10,1),new r("eren",10,1),new r("er",-1,1),new r("heder",13,1),new r("erer",13,1),new r("s",-1,2),new r("heds",16,1),new r("es",16,1),new r("endes",18,1),new r("erendes",19,1),new r("enes",18,1),new r("ernes",18,1),new r("eres",18,1),new r("ens",16,1),new r("hedens",24,1),new r("erens",24,1),new r("ers",16,1),new r("ets",16,1),new r("erets",28,1),new r("et",-1,1),new r("eret",30,1)],l=[new r("gd",-1,-1),new r("dt",-1,-1),new r("gt",-1,-1),new r("kt",-1,-1)],m=[new r("ig",-1,1),new r("lig",0,1),new r("elig",1,1),new r("els",-1,1),new r("løst",-1,2)],w=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,48,0,128],p=[239,254,42,3,0,0,0,0,0,0,0,0,0,0,0,0,16],f=new i;this.setCurrent=function(e){f.setCurrent(e)},this.getCurrent=function(){return f.getCurrent()},this.stem=function(){var r=f.cursor;return e(),f.limit_backward=r,f.cursor=f.limit,n(),f.cursor=f.limit,t(),f.cursor=f.limit,s(),f.cursor=f.limit,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}}(),e.Pipeline.registerFunction(e.da.stemmer,"stemmer-da"),e.da.stopWordFilter=e.generateStopWordFilter("ad af alle alt anden at blev blive bliver da de dem den denne der deres det dette dig din disse dog du efter eller en end er et for fra ham han hans har havde have hende hendes her hos hun hvad hvis hvor i ikke ind jeg jer jo kunne man mange med meget men mig min mine mit mod ned noget nogle nu når og også om op os over på selv sig sin sine sit skal skulle som sådan thi til ud under var vi vil ville vor være været".split(" ")),e.Pipeline.registerFunction(e.da.stopWordFilter,"stopWordFilter-da")}});
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
-1
View File
@@ -1 +0,0 @@
!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.hi=function(){this.pipeline.reset(),this.pipeline.add(e.hi.trimmer,e.hi.stopWordFilter,e.hi.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.hi.stemmer))},e.hi.wordCharacters="ऀ-ःऄ-एऐ-टठ-यर-िी-ॏॐ-य़ॠ-९॰-ॿa-zA-Z-zA-0-9-",e.hi.trimmer=e.trimmerSupport.generateTrimmer(e.hi.wordCharacters),e.Pipeline.registerFunction(e.hi.trimmer,"trimmer-hi"),e.hi.stopWordFilter=e.generateStopWordFilter("अत अपना अपनी अपने अभी अंदर आदि आप इत्यादि इन इनका इन्हीं इन्हें इन्हों इस इसका इसकी इसके इसमें इसी इसे उन उनका उनकी उनके उनको उन्हीं उन्हें उन्हों उस उसके उसी उसे एक एवं एस ऐसे और कई कर करता करते करना करने करें कहते कहा का काफ़ी कि कितना किन्हें किन्हों किया किर किस किसी किसे की कुछ कुल के को कोई कौन कौनसा गया घर जब जहाँ जा जितना जिन जिन्हें जिन्हों जिस जिसे जीधर जैसा जैसे जो तक तब तरह तिन तिन्हें तिन्हों तिस तिसे तो था थी थे दबारा दिया दुसरा दूसरे दो द्वारा न नके नहीं ना निहायत नीचे ने पर पहले पूरा पे फिर बनी बही बहुत बाद बाला बिलकुल भी भीतर मगर मानो मे में यदि यह यहाँ यही या यिह ये रखें रहा रहे ऱ्वासा लिए लिये लेकिन व वग़ैरह वर्ग वह वहाँ वहीं वाले वुह वे वो सकता सकते सबसे सभी साथ साबुत साभ सारा से सो संग ही हुआ हुई हुए है हैं हो होता होती होते होना होने".split(" ")),e.hi.stemmer=function(){return function(e){return"function"==typeof e.update?e.update(function(e){return e}):e}}();var r=e.wordcut;r.init(),e.hi.tokenizer=function(i){if(!arguments.length||null==i||void 0==i)return[];if(Array.isArray(i))return i.map(function(r){return isLunr2?new e.Token(r.toLowerCase()):r.toLowerCase()});var t=i.toString().toLowerCase().replace(/^\s+/,"");return r.cut(t).split("|")},e.Pipeline.registerFunction(e.hi.stemmer,"stemmer-hi"),e.Pipeline.registerFunction(e.hi.stopWordFilter,"stopWordFilter-hi")}});
File diff suppressed because one or more lines are too long
-1
View File
@@ -1 +0,0 @@
!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.hy=function(){this.pipeline.reset(),this.pipeline.add(e.hy.trimmer,e.hy.stopWordFilter)},e.hy.wordCharacters="[A-Za-z԰-֏ff-ﭏ]",e.hy.trimmer=e.trimmerSupport.generateTrimmer(e.hy.wordCharacters),e.Pipeline.registerFunction(e.hy.trimmer,"trimmer-hy"),e.hy.stopWordFilter=e.generateStopWordFilter("դու և եք էիր էիք հետո նաև նրանք որը վրա է որ պիտի են այս մեջ ն իր ու ի այդ որոնք այն կամ էր մի ես համար այլ իսկ էին ենք հետ ին թ էինք մենք նրա նա դուք եմ էի ըստ որպես ում".split(" ")),e.Pipeline.registerFunction(e.hy.stopWordFilter,"stopWordFilter-hy"),e.hy.stemmer=function(){return function(e){return"function"==typeof e.update?e.update(function(e){return e}):e}}(),e.Pipeline.registerFunction(e.hy.stemmer,"stemmer-hy")}});
File diff suppressed because one or more lines are too long
-1
View File
@@ -1 +0,0 @@
!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var r="2"==e.version[0];e.ja=function(){this.pipeline.reset(),this.pipeline.add(e.ja.trimmer,e.ja.stopWordFilter,e.ja.stemmer),r?this.tokenizer=e.ja.tokenizer:(e.tokenizer&&(e.tokenizer=e.ja.tokenizer),this.tokenizerFn&&(this.tokenizerFn=e.ja.tokenizer))};var t=new e.TinySegmenter;e.ja.tokenizer=function(i){var n,o,s,p,a,u,m,l,c,f;if(!arguments.length||null==i||void 0==i)return[];if(Array.isArray(i))return i.map(function(t){return r?new e.Token(t.toLowerCase()):t.toLowerCase()});for(o=i.toString().toLowerCase().replace(/^\s+/,""),n=o.length-1;n>=0;n--)if(/\S/.test(o.charAt(n))){o=o.substring(0,n+1);break}for(a=[],s=o.length,c=0,l=0;c<=s;c++)if(u=o.charAt(c),m=c-l,u.match(/\s/)||c==s){if(m>0)for(p=t.segment(o.slice(l,c)).filter(function(e){return!!e}),f=l,n=0;n<p.length;n++)r?a.push(new e.Token(p[n],{position:[f,p[n].length],index:a.length})):a.push(p[n]),f+=p[n].length;l=c+1}return a},e.ja.stemmer=function(){return function(e){return e}}(),e.Pipeline.registerFunction(e.ja.stemmer,"stemmer-ja"),e.ja.wordCharacters="一二三四五六七八九十百千万億兆一-龠々〆ヵヶぁ-んァ-ヴーア-ン゙a-zA-Z-zA-0-9-",e.ja.trimmer=e.trimmerSupport.generateTrimmer(e.ja.wordCharacters),e.Pipeline.registerFunction(e.ja.trimmer,"trimmer-ja"),e.ja.stopWordFilter=e.generateStopWordFilter("これ それ あれ この その あの ここ そこ あそこ こちら どこ だれ なに なん 何 私 貴方 貴方方 我々 私達 あの人 あのかた 彼女 彼 です あります おります います は が の に を で え から まで より も どの と し それで しかし".split(" ")),e.Pipeline.registerFunction(e.ja.stopWordFilter,"stopWordFilter-ja"),e.jp=e.ja,e.Pipeline.registerFunction(e.jp.stemmer,"stemmer-jp"),e.Pipeline.registerFunction(e.jp.trimmer,"trimmer-jp"),e.Pipeline.registerFunction(e.jp.stopWordFilter,"stopWordFilter-jp")}});
-1
View File
@@ -1 +0,0 @@
module.exports=require("./lunr.ja");
-1
View File
@@ -1 +0,0 @@
!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.kn=function(){this.pipeline.reset(),this.pipeline.add(e.kn.trimmer,e.kn.stopWordFilter,e.kn.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.kn.stemmer))},e.kn.wordCharacters="ಀ-಄ಅ-ಔಕ-ಹಾ-ೌ಼-ಽೕ-ೖೝ-ೞೠ-ೡೢ-ೣ೤೥೦-೯ೱ-ೳ",e.kn.trimmer=e.trimmerSupport.generateTrimmer(e.kn.wordCharacters),e.Pipeline.registerFunction(e.kn.trimmer,"trimmer-kn"),e.kn.stopWordFilter=e.generateStopWordFilter("ಮತ್ತು ಈ ಒಂದು ರಲ್ಲಿ ಹಾಗೂ ಎಂದು ಅಥವಾ ಇದು ರ ಅವರು ಎಂಬ ಮೇಲೆ ಅವರ ತನ್ನ ಆದರೆ ತಮ್ಮ ನಂತರ ಮೂಲಕ ಹೆಚ್ಚು ನ ಆ ಕೆಲವು ಅನೇಕ ಎರಡು ಹಾಗು ಪ್ರಮುಖ ಇದನ್ನು ಇದರ ಸುಮಾರು ಅದರ ಅದು ಮೊದಲ ಬಗ್ಗೆ ನಲ್ಲಿ ರಂದು ಇತರ ಅತ್ಯಂತ ಹೆಚ್ಚಿನ ಸಹ ಸಾಮಾನ್ಯವಾಗಿ ನೇ ಹಲವಾರು ಹೊಸ ದಿ ಕಡಿಮೆ ಯಾವುದೇ ಹೊಂದಿದೆ ದೊಡ್ಡ ಅನ್ನು ಇವರು ಪ್ರಕಾರ ಇದೆ ಮಾತ್ರ ಕೂಡ ಇಲ್ಲಿ ಎಲ್ಲಾ ವಿವಿಧ ಅದನ್ನು ಹಲವು ರಿಂದ ಕೇವಲ ದ ದಕ್ಷಿಣ ಗೆ ಅವನ ಅತಿ ನೆಯ ಬಹಳ ಕೆಲಸ ಎಲ್ಲ ಪ್ರತಿ ಇತ್ಯಾದಿ ಇವು ಬೇರೆ ಹೀಗೆ ನಡುವೆ ಇದಕ್ಕೆ ಎಸ್ ಇವರ ಮೊದಲು ಶ್ರೀ ಮಾಡುವ ಇದರಲ್ಲಿ ರೀತಿಯ ಮಾಡಿದ ಕಾಲ ಅಲ್ಲಿ ಮಾಡಲು ಅದೇ ಈಗ ಅವು ಗಳು ಎ ಎಂಬುದು ಅವನು ಅಂದರೆ ಅವರಿಗೆ ಇರುವ ವಿಶೇಷ ಮುಂದೆ ಅವುಗಳ ಮುಂತಾದ ಮೂಲ ಬಿ ಮೀ ಒಂದೇ ಇನ್ನೂ ಹೆಚ್ಚಾಗಿ ಮಾಡಿ ಅವರನ್ನು ಇದೇ ಯ ರೀತಿಯಲ್ಲಿ ಜೊತೆ ಅದರಲ್ಲಿ ಮಾಡಿದರು ನಡೆದ ಆಗ ಮತ್ತೆ ಪೂರ್ವ ಆತ ಬಂದ ಯಾವ ಒಟ್ಟು ಇತರೆ ಹಿಂದೆ ಪ್ರಮಾಣದ ಗಳನ್ನು ಕುರಿತು ಯು ಆದ್ದರಿಂದ ಅಲ್ಲದೆ ನಗರದ ಮೇಲಿನ ಏಕೆಂದರೆ ರಷ್ಟು ಎಂಬುದನ್ನು ಬಾರಿ ಎಂದರೆ ಹಿಂದಿನ ಆದರೂ ಆದ ಸಂಬಂಧಿಸಿದ ಮತ್ತೊಂದು ಸಿ ಆತನ ".split(" ")),e.kn.stemmer=function(){return function(e){return"function"==typeof e.update?e.update(function(e){return e}):e}}();var r=e.wordcut;r.init(),e.kn.tokenizer=function(t){if(!arguments.length||null==t||void 0==t)return[];if(Array.isArray(t))return t.map(function(r){return isLunr2?new e.Token(r.toLowerCase()):r.toLowerCase()});var n=t.toString().toLowerCase().replace(/^\s+/,"");return r.cut(n).split("|")},e.Pipeline.registerFunction(e.kn.stemmer,"stemmer-kn"),e.Pipeline.registerFunction(e.kn.stopWordFilter,"stopWordFilter-kn")}});
File diff suppressed because one or more lines are too long
-1
View File
@@ -1 +0,0 @@
!function(e,t){"function"==typeof define&&define.amd?define(t):"object"==typeof exports?module.exports=t():t()(e.lunr)}(this,function(){return function(e){e.multiLanguage=function(){for(var t=Array.prototype.slice.call(arguments),i=t.join("-"),r="",n=[],s=[],p=0;p<t.length;++p)"en"==t[p]?(r+="\\w",n.unshift(e.stopWordFilter),n.push(e.stemmer),s.push(e.stemmer)):(r+=e[t[p]].wordCharacters,e[t[p]].stopWordFilter&&n.unshift(e[t[p]].stopWordFilter),e[t[p]].stemmer&&(n.push(e[t[p]].stemmer),s.push(e[t[p]].stemmer)));var o=e.trimmerSupport.generateTrimmer(r);return e.Pipeline.registerFunction(o,"lunr-multi-trimmer-"+i),n.unshift(o),function(){this.pipeline.reset(),this.pipeline.add.apply(this.pipeline,n),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add.apply(this.searchPipeline,s))}}}});
File diff suppressed because one or more lines are too long
-18
View File
@@ -1,18 +0,0 @@
/*!
* Lunr languages, `Norwegian` language
* https://github.com/MihaiValentin/lunr-languages
*
* Copyright 2014, Mihai Valentin
* http://www.mozilla.org/MPL/
*/
/*!
* based on
* Snowball JavaScript Library v0.3
* http://code.google.com/p/urim/
* http://snowball.tartarus.org/
*
* Copyright 2010, Oleg Mazko
* http://www.mozilla.org/MPL/
*/
!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.no=function(){this.pipeline.reset(),this.pipeline.add(e.no.trimmer,e.no.stopWordFilter,e.no.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.no.stemmer))},e.no.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.no.trimmer=e.trimmerSupport.generateTrimmer(e.no.wordCharacters),e.Pipeline.registerFunction(e.no.trimmer,"trimmer-no"),e.no.stemmer=function(){var r=e.stemmerSupport.Among,n=e.stemmerSupport.SnowballProgram,i=new function(){function e(){var e,r=w.cursor+3;if(a=w.limit,0<=r||r<=w.limit){for(s=r;;){if(e=w.cursor,w.in_grouping(d,97,248)){w.cursor=e;break}if(e>=w.limit)return;w.cursor=e+1}for(;!w.out_grouping(d,97,248);){if(w.cursor>=w.limit)return;w.cursor++}a=w.cursor,a<s&&(a=s)}}function i(){var e,r,n;if(w.cursor>=a&&(r=w.limit_backward,w.limit_backward=a,w.ket=w.cursor,e=w.find_among_b(m,29),w.limit_backward=r,e))switch(w.bra=w.cursor,e){case 1:w.slice_del();break;case 2:n=w.limit-w.cursor,w.in_grouping_b(c,98,122)?w.slice_del():(w.cursor=w.limit-n,w.eq_s_b(1,"k")&&w.out_grouping_b(d,97,248)&&w.slice_del());break;case 3:w.slice_from("er")}}function t(){var e,r=w.limit-w.cursor;w.cursor>=a&&(e=w.limit_backward,w.limit_backward=a,w.ket=w.cursor,w.find_among_b(u,2)?(w.bra=w.cursor,w.limit_backward=e,w.cursor=w.limit-r,w.cursor>w.limit_backward&&(w.cursor--,w.bra=w.cursor,w.slice_del())):w.limit_backward=e)}function o(){var e,r;w.cursor>=a&&(r=w.limit_backward,w.limit_backward=a,w.ket=w.cursor,e=w.find_among_b(l,11),e?(w.bra=w.cursor,w.limit_backward=r,1==e&&w.slice_del()):w.limit_backward=r)}var s,a,m=[new r("a",-1,1),new r("e",-1,1),new r("ede",1,1),new r("ande",1,1),new r("ende",1,1),new r("ane",1,1),new r("ene",1,1),new r("hetene",6,1),new r("erte",1,3),new r("en",-1,1),new r("heten",9,1),new r("ar",-1,1),new r("er",-1,1),new r("heter",12,1),new r("s",-1,2),new r("as",14,1),new r("es",14,1),new r("edes",16,1),new r("endes",16,1),new r("enes",16,1),new r("hetenes",19,1),new r("ens",14,1),new r("hetens",21,1),new r("ers",14,1),new r("ets",14,1),new r("et",-1,1),new r("het",25,1),new r("ert",-1,3),new r("ast",-1,1)],u=[new r("dt",-1,-1),new r("vt",-1,-1)],l=[new r("leg",-1,1),new r("eleg",0,1),new r("ig",-1,1),new r("eig",2,1),new r("lig",2,1),new r("elig",4,1),new r("els",-1,1),new r("lov",-1,1),new r("elov",7,1),new r("slov",7,1),new r("hetslov",9,1)],d=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,48,0,128],c=[119,125,149,1],w=new n;this.setCurrent=function(e){w.setCurrent(e)},this.getCurrent=function(){return w.getCurrent()},this.stem=function(){var r=w.cursor;return e(),w.limit_backward=r,w.cursor=w.limit,i(),w.cursor=w.limit,t(),w.cursor=w.limit,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}}(),e.Pipeline.registerFunction(e.no.stemmer,"stemmer-no"),e.no.stopWordFilter=e.generateStopWordFilter("alle at av bare begge ble blei bli blir blitt både båe da de deg dei deim deira deires dem den denne der dere deres det dette di din disse ditt du dykk dykkar då eg ein eit eitt eller elles en enn er et ett etter for fordi fra før ha hadde han hans har hennar henne hennes her hjå ho hoe honom hoss hossen hun hva hvem hver hvilke hvilken hvis hvor hvordan hvorfor i ikke ikkje ikkje ingen ingi inkje inn inni ja jeg kan kom korleis korso kun kunne kva kvar kvarhelst kven kvi kvifor man mange me med medan meg meget mellom men mi min mine mitt mot mykje ned no noe noen noka noko nokon nokor nokre nå når og også om opp oss over på samme seg selv si si sia sidan siden sin sine sitt sjøl skal skulle slik so som som somme somt så sånn til um upp ut uten var vart varte ved vere verte vi vil ville vore vors vort vår være være vært å".split(" ")),e.Pipeline.registerFunction(e.no.stopWordFilter,"stopWordFilter-no")}});
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
-1
View File
@@ -1 +0,0 @@
!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.sa=function(){this.pipeline.reset(),this.pipeline.add(e.sa.trimmer,e.sa.stopWordFilter,e.sa.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.sa.stemmer))},e.sa.wordCharacters="ऀ-ःऄ-एऐ-टठ-यर-िी-ॏॐ-य़ॠ-९॰-ॿ꣠-꣱ꣲ-ꣷ꣸-ꣻ꣼-ꣽꣾ-ꣿᆰ0-ᆰ9",e.sa.trimmer=e.trimmerSupport.generateTrimmer(e.sa.wordCharacters),e.Pipeline.registerFunction(e.sa.trimmer,"trimmer-sa"),e.sa.stopWordFilter=e.generateStopWordFilter('तथा अयम्‌ एकम्‌ इत्यस्मिन्‌ तथा तत्‌ वा अयम्‌ इत्यस्य ते आहूत उपरि तेषाम्‌ किन्तु तेषाम्‌ तदा इत्यनेन अधिकः इत्यस्य तत्‌ केचन बहवः द्वि तथा महत्वपूर्णः अयम्‌ अस्य विषये अयं अस्ति तत्‌ प्रथमः विषये इत्युपरि इत्युपरि इतर अधिकतमः अधिकः अपि सामान्यतया ठ इतरेतर नूतनम्‌ द न्यूनम्‌ कश्चित्‌ वा विशालः द सः अस्ति तदनुसारम् तत्र अस्ति केवलम्‌ अपि अत्र सर्वे विविधाः तत्‌ बहवः यतः इदानीम्‌ द दक्षिण इत्यस्मै तस्य उपरि नथ अतीव कार्यम्‌ सर्वे एकैकम्‌ इत्यादि। एते सन्ति उत इत्थम्‌ मध्ये एतदर्थं . स कस्य प्रथमः श्री. करोति अस्मिन् प्रकारः निर्मिता कालः तत्र कर्तुं समान अधुना ते सन्ति स एकः अस्ति सः अर्थात् तेषां कृते . स्थितम् विशेषः अग्रिम तेषाम्‌ समान स्रोतः ख म समान इदानीमपि अधिकतया करोतु ते समान इत्यस्य वीथी सह यस्मिन् कृतवान्‌ धृतः तदा पुनः पूर्वं सः आगतः किम्‌ कुल इतर पुरा मात्रा स विषये उ अतएव अपि नगरस्य उपरि यतः प्रतिशतं कतरः कालः साधनानि भूत तथापि जात सम्बन्धि अन्यत्‌ ग अतः अस्माकं स्वकीयाः अस्माकं इदानीं अन्तः इत्यादयः भवन्तः इत्यादयः एते एताः तस्य अस्य इदम् एते तेषां तेषां तेषां तान् तेषां तेषां तेषां समानः सः एकः च तादृशाः बहवः अन्ये च वदन्ति यत् कियत् कस्मै कस्मै यस्मै यस्मै यस्मै यस्मै न अतिनीचः किन्तु प्रथमं सम्पूर्णतया ततः चिरकालानन्तरं पुस्तकं सम्पूर्णतया अन्तः किन्तु अत्र वा इह इव श्रद्धाय अवशिष्यते परन्तु अन्ये वर्गाः सन्ति ते सन्ति शक्नुवन्ति सर्वे मिलित्वा सर्वे एकत्र"'.split(" ")),e.sa.stemmer=function(){return function(e){return"function"==typeof e.update?e.update(function(e){return e}):e}}();var r=e.wordcut;r.init(),e.sa.tokenizer=function(t){if(!arguments.length||null==t||void 0==t)return[];if(Array.isArray(t))return t.map(function(r){return isLunr2?new e.Token(r.toLowerCase()):r.toLowerCase()});var i=t.toString().toLowerCase().replace(/^\s+/,"");return r.cut(i).split("|")},e.Pipeline.registerFunction(e.sa.stemmer,"stemmer-sa"),e.Pipeline.registerFunction(e.sa.stopWordFilter,"stopWordFilter-sa")}});
@@ -1 +0,0 @@
!function(r,t){"function"==typeof define&&define.amd?define(t):"object"==typeof exports?module.exports=t():t()(r.lunr)}(this,function(){return function(r){r.stemmerSupport={Among:function(r,t,i,s){if(this.toCharArray=function(r){for(var t=r.length,i=new Array(t),s=0;s<t;s++)i[s]=r.charCodeAt(s);return i},!r&&""!=r||!t&&0!=t||!i)throw"Bad Among initialisation: s:"+r+", substring_i: "+t+", result: "+i;this.s_size=r.length,this.s=this.toCharArray(r),this.substring_i=t,this.result=i,this.method=s},SnowballProgram:function(){var r;return{bra:0,ket:0,limit:0,cursor:0,limit_backward:0,setCurrent:function(t){r=t,this.cursor=0,this.limit=t.length,this.limit_backward=0,this.bra=this.cursor,this.ket=this.limit},getCurrent:function(){var t=r;return r=null,t},in_grouping:function(t,i,s){if(this.cursor<this.limit){var e=r.charCodeAt(this.cursor);if(e<=s&&e>=i&&(e-=i,t[e>>3]&1<<(7&e)))return this.cursor++,!0}return!1},in_grouping_b:function(t,i,s){if(this.cursor>this.limit_backward){var e=r.charCodeAt(this.cursor-1);if(e<=s&&e>=i&&(e-=i,t[e>>3]&1<<(7&e)))return this.cursor--,!0}return!1},out_grouping:function(t,i,s){if(this.cursor<this.limit){var e=r.charCodeAt(this.cursor);if(e>s||e<i)return this.cursor++,!0;if(e-=i,!(t[e>>3]&1<<(7&e)))return this.cursor++,!0}return!1},out_grouping_b:function(t,i,s){if(this.cursor>this.limit_backward){var e=r.charCodeAt(this.cursor-1);if(e>s||e<i)return this.cursor--,!0;if(e-=i,!(t[e>>3]&1<<(7&e)))return this.cursor--,!0}return!1},eq_s:function(t,i){if(this.limit-this.cursor<t)return!1;for(var s=0;s<t;s++)if(r.charCodeAt(this.cursor+s)!=i.charCodeAt(s))return!1;return this.cursor+=t,!0},eq_s_b:function(t,i){if(this.cursor-this.limit_backward<t)return!1;for(var s=0;s<t;s++)if(r.charCodeAt(this.cursor-t+s)!=i.charCodeAt(s))return!1;return this.cursor-=t,!0},find_among:function(t,i){for(var s=0,e=i,n=this.cursor,u=this.limit,o=0,h=0,c=!1;;){for(var a=s+(e-s>>1),f=0,l=o<h?o:h,_=t[a],m=l;m<_.s_size;m++){if(n+l==u){f=-1;break}if(f=r.charCodeAt(n+l)-_.s[m])break;l++}if(f<0?(e=a,h=l):(s=a,o=l),e-s<=1){if(s>0||e==s||c)break;c=!0}}for(;;){var _=t[s];if(o>=_.s_size){if(this.cursor=n+_.s_size,!_.method)return _.result;var b=_.method();if(this.cursor=n+_.s_size,b)return _.result}if((s=_.substring_i)<0)return 0}},find_among_b:function(t,i){for(var s=0,e=i,n=this.cursor,u=this.limit_backward,o=0,h=0,c=!1;;){for(var a=s+(e-s>>1),f=0,l=o<h?o:h,_=t[a],m=_.s_size-1-l;m>=0;m--){if(n-l==u){f=-1;break}if(f=r.charCodeAt(n-1-l)-_.s[m])break;l++}if(f<0?(e=a,h=l):(s=a,o=l),e-s<=1){if(s>0||e==s||c)break;c=!0}}for(;;){var _=t[s];if(o>=_.s_size){if(this.cursor=n-_.s_size,!_.method)return _.result;var b=_.method();if(this.cursor=n-_.s_size,b)return _.result}if((s=_.substring_i)<0)return 0}},replace_s:function(t,i,s){var e=s.length-(i-t),n=r.substring(0,t),u=r.substring(i);return r=n+s+u,this.limit+=e,this.cursor>=i?this.cursor+=e:this.cursor>t&&(this.cursor=t),e},slice_check:function(){if(this.bra<0||this.bra>this.ket||this.ket>this.limit||this.limit>r.length)throw"faulty slice operation"},slice_from:function(r){this.slice_check(),this.replace_s(this.bra,this.ket,r)},slice_del:function(){this.slice_from("")},insert:function(r,t,i){var s=this.replace_s(r,t,i);r<=this.bra&&(this.bra+=s),r<=this.ket&&(this.ket+=s)},slice_to:function(){return this.slice_check(),r.substring(this.bra,this.ket)},eq_v_b:function(r){return this.eq_s_b(r.length,r)}}}},r.trimmerSupport={generateTrimmer:function(r){var t=new RegExp("^[^"+r+"]+"),i=new RegExp("[^"+r+"]+$");return function(r){return"function"==typeof r.update?r.update(function(r){return r.replace(t,"").replace(i,"")}):r.replace(t,"").replace(i,"")}}}}});
-18
View File
@@ -1,18 +0,0 @@
/*!
* Lunr languages, `Swedish` language
* https://github.com/MihaiValentin/lunr-languages
*
* Copyright 2014, Mihai Valentin
* http://www.mozilla.org/MPL/
*/
/*!
* based on
* Snowball JavaScript Library v0.3
* http://code.google.com/p/urim/
* http://snowball.tartarus.org/
*
* Copyright 2010, Oleg Mazko
* http://www.mozilla.org/MPL/
*/
!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.sv=function(){this.pipeline.reset(),this.pipeline.add(e.sv.trimmer,e.sv.stopWordFilter,e.sv.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.sv.stemmer))},e.sv.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.sv.trimmer=e.trimmerSupport.generateTrimmer(e.sv.wordCharacters),e.Pipeline.registerFunction(e.sv.trimmer,"trimmer-sv"),e.sv.stemmer=function(){var r=e.stemmerSupport.Among,n=e.stemmerSupport.SnowballProgram,t=new function(){function e(){var e,r=w.cursor+3;if(o=w.limit,0<=r||r<=w.limit){for(a=r;;){if(e=w.cursor,w.in_grouping(l,97,246)){w.cursor=e;break}if(w.cursor=e,w.cursor>=w.limit)return;w.cursor++}for(;!w.out_grouping(l,97,246);){if(w.cursor>=w.limit)return;w.cursor++}o=w.cursor,o<a&&(o=a)}}function t(){var e,r=w.limit_backward;if(w.cursor>=o&&(w.limit_backward=o,w.cursor=w.limit,w.ket=w.cursor,e=w.find_among_b(u,37),w.limit_backward=r,e))switch(w.bra=w.cursor,e){case 1:w.slice_del();break;case 2:w.in_grouping_b(d,98,121)&&w.slice_del()}}function i(){var e=w.limit_backward;w.cursor>=o&&(w.limit_backward=o,w.cursor=w.limit,w.find_among_b(c,7)&&(w.cursor=w.limit,w.ket=w.cursor,w.cursor>w.limit_backward&&(w.bra=--w.cursor,w.slice_del())),w.limit_backward=e)}function s(){var e,r;if(w.cursor>=o){if(r=w.limit_backward,w.limit_backward=o,w.cursor=w.limit,w.ket=w.cursor,e=w.find_among_b(m,5))switch(w.bra=w.cursor,e){case 1:w.slice_del();break;case 2:w.slice_from("lös");break;case 3:w.slice_from("full")}w.limit_backward=r}}var a,o,u=[new r("a",-1,1),new r("arna",0,1),new r("erna",0,1),new r("heterna",2,1),new r("orna",0,1),new r("ad",-1,1),new r("e",-1,1),new r("ade",6,1),new r("ande",6,1),new r("arne",6,1),new r("are",6,1),new r("aste",6,1),new r("en",-1,1),new r("anden",12,1),new r("aren",12,1),new r("heten",12,1),new r("ern",-1,1),new r("ar",-1,1),new r("er",-1,1),new r("heter",18,1),new r("or",-1,1),new r("s",-1,2),new r("as",21,1),new r("arnas",22,1),new r("ernas",22,1),new r("ornas",22,1),new r("es",21,1),new r("ades",26,1),new r("andes",26,1),new r("ens",21,1),new r("arens",29,1),new r("hetens",29,1),new r("erns",21,1),new r("at",-1,1),new r("andet",-1,1),new r("het",-1,1),new r("ast",-1,1)],c=[new r("dd",-1,-1),new r("gd",-1,-1),new r("nn",-1,-1),new r("dt",-1,-1),new r("gt",-1,-1),new r("kt",-1,-1),new r("tt",-1,-1)],m=[new r("ig",-1,1),new r("lig",0,1),new r("els",-1,1),new r("fullt",-1,3),new r("löst",-1,2)],l=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,24,0,32],d=[119,127,149],w=new n;this.setCurrent=function(e){w.setCurrent(e)},this.getCurrent=function(){return w.getCurrent()},this.stem=function(){var r=w.cursor;return e(),w.limit_backward=r,w.cursor=w.limit,t(),w.cursor=w.limit,i(),w.cursor=w.limit,s(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return t.setCurrent(e),t.stem(),t.getCurrent()}):(t.setCurrent(e),t.stem(),t.getCurrent())}}(),e.Pipeline.registerFunction(e.sv.stemmer,"stemmer-sv"),e.sv.stopWordFilter=e.generateStopWordFilter("alla allt att av blev bli blir blivit de dem den denna deras dess dessa det detta dig din dina ditt du där då efter ej eller en er era ert ett från för ha hade han hans har henne hennes hon honom hur här i icke ingen inom inte jag ju kan kunde man med mellan men mig min mina mitt mot mycket ni nu när någon något några och om oss på samma sedan sig sin sina sitta själv skulle som så sådan sådana sådant till under upp ut utan vad var vara varför varit varje vars vart vem vi vid vilka vilkas vilken vilket vår våra vårt än är åt över".split(" ")),e.Pipeline.registerFunction(e.sv.stopWordFilter,"stopWordFilter-sv")}});
-1
View File
@@ -1 +0,0 @@
!function(e,t){"function"==typeof define&&define.amd?define(t):"object"==typeof exports?module.exports=t():t()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.ta=function(){this.pipeline.reset(),this.pipeline.add(e.ta.trimmer,e.ta.stopWordFilter,e.ta.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.ta.stemmer))},e.ta.wordCharacters="஀-உஊ-ஏஐ-ஙச-ட஠-னப-யர-ஹ஺-ிீ-௉ொ-௏ௐ-௙௚-௟௠-௩௪-௯௰-௹௺-௿a-zA-Z-zA-0-9-",e.ta.trimmer=e.trimmerSupport.generateTrimmer(e.ta.wordCharacters),e.Pipeline.registerFunction(e.ta.trimmer,"trimmer-ta"),e.ta.stopWordFilter=e.generateStopWordFilter("அங்கு அங்கே அது அதை அந்த அவர் அவர்கள் அவள் அவன் அவை ஆக ஆகவே ஆகையால் ஆதலால் ஆதலினால் ஆனாலும் ஆனால் இங்கு இங்கே இது இதை இந்த இப்படி இவர் இவர்கள் இவள் இவன் இவை இவ்வளவு உனக்கு உனது உன் உன்னால் எங்கு எங்கே எது எதை எந்த எப்படி எவர் எவர்கள் எவள் எவன் எவை எவ்வளவு எனக்கு எனது எனவே என் என்ன என்னால் ஏது ஏன் தனது தன்னால் தானே தான் நாங்கள் நாம் நான் நீ நீங்கள்".split(" ")),e.ta.stemmer=function(){return function(e){return"function"==typeof e.update?e.update(function(e){return e}):e}}();var t=e.wordcut;t.init(),e.ta.tokenizer=function(r){if(!arguments.length||null==r||void 0==r)return[];if(Array.isArray(r))return r.map(function(t){return isLunr2?new e.Token(t.toLowerCase()):t.toLowerCase()});var i=r.toString().toLowerCase().replace(/^\s+/,"");return t.cut(i).split("|")},e.Pipeline.registerFunction(e.ta.stemmer,"stemmer-ta"),e.Pipeline.registerFunction(e.ta.stopWordFilter,"stopWordFilter-ta")}});
-1
View File
@@ -1 +0,0 @@
!function(e,t){"function"==typeof define&&define.amd?define(t):"object"==typeof exports?module.exports=t():t()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.te=function(){this.pipeline.reset(),this.pipeline.add(e.te.trimmer,e.te.stopWordFilter,e.te.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.te.stemmer))},e.te.wordCharacters="ఀ-ఄఅ-ఔక-హా-ౌౕ-ౖౘ-ౚౠ-ౡౢ-ౣ౦-౯౸-౿఼ఽ్ౝ౷౤౥",e.te.trimmer=e.trimmerSupport.generateTrimmer(e.te.wordCharacters),e.Pipeline.registerFunction(e.te.trimmer,"trimmer-te"),e.te.stopWordFilter=e.generateStopWordFilter("అందరూ అందుబాటులో అడగండి అడగడం అడ్డంగా అనుగుణంగా అనుమతించు అనుమతిస్తుంది అయితే ఇప్పటికే ఉన్నారు ఎక్కడైనా ఎప్పుడు ఎవరైనా ఎవరో ఏ ఏదైనా ఏమైనప్పటికి ఒక ఒకరు కనిపిస్తాయి కాదు కూడా గా గురించి చుట్టూ చేయగలిగింది తగిన తర్వాత దాదాపు దూరంగా నిజంగా పై ప్రకారం ప్రక్కన మధ్య మరియు మరొక మళ్ళీ మాత్రమే మెచ్చుకో వద్ద వెంట వేరుగా వ్యతిరేకంగా సంబంధం".split(" ")),e.te.stemmer=function(){return function(e){return"function"==typeof e.update?e.update(function(e){return e}):e}}();var t=e.wordcut;t.init(),e.te.tokenizer=function(r){if(!arguments.length||null==r||void 0==r)return[];if(Array.isArray(r))return r.map(function(t){return isLunr2?new e.Token(t.toLowerCase()):t.toLowerCase()});var i=r.toString().toLowerCase().replace(/^\s+/,"");return t.cut(i).split("|")},e.Pipeline.registerFunction(e.te.stemmer,"stemmer-te"),e.Pipeline.registerFunction(e.te.stopWordFilter,"stopWordFilter-te")}});
-1
View File
@@ -1 +0,0 @@
!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var r="2"==e.version[0];e.th=function(){this.pipeline.reset(),this.pipeline.add(e.th.trimmer),r?this.tokenizer=e.th.tokenizer:(e.tokenizer&&(e.tokenizer=e.th.tokenizer),this.tokenizerFn&&(this.tokenizerFn=e.th.tokenizer))},e.th.wordCharacters="[฀-๿]",e.th.trimmer=e.trimmerSupport.generateTrimmer(e.th.wordCharacters),e.Pipeline.registerFunction(e.th.trimmer,"trimmer-th");var t=e.wordcut;t.init(),e.th.tokenizer=function(i){if(!arguments.length||null==i||void 0==i)return[];if(Array.isArray(i))return i.map(function(t){return r?new e.Token(t):t});var n=i.toString().replace(/^\s+/,"");return t.cut(n).split("|")}}});
File diff suppressed because one or more lines are too long
-1
View File
@@ -1 +0,0 @@
!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.vi=function(){this.pipeline.reset(),this.pipeline.add(e.vi.stopWordFilter,e.vi.trimmer)},e.vi.wordCharacters="[A-Za-ẓ̀͐́͑̉̃̓ÂâÊêÔôĂ-ăĐ-đƠ-ơƯ-ư]",e.vi.trimmer=e.trimmerSupport.generateTrimmer(e.vi.wordCharacters),e.Pipeline.registerFunction(e.vi.trimmer,"trimmer-vi"),e.vi.stopWordFilter=e.generateStopWordFilter("là cái nhưng mà".split(" "))}});
-1
View File
@@ -1 +0,0 @@
!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r(require("@node-rs/jieba")):r()(e.lunr)}(this,function(e){return function(r,t){if(void 0===r)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===r.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var i="2"==r.version[0];r.zh=function(){this.pipeline.reset(),this.pipeline.add(r.zh.trimmer,r.zh.stopWordFilter,r.zh.stemmer),i?this.tokenizer=r.zh.tokenizer:(r.tokenizer&&(r.tokenizer=r.zh.tokenizer),this.tokenizerFn&&(this.tokenizerFn=r.zh.tokenizer))},r.zh.tokenizer=function(n){if(!arguments.length||null==n||void 0==n)return[];if(Array.isArray(n))return n.map(function(e){return i?new r.Token(e.toLowerCase()):e.toLowerCase()});t&&e.load(t);var o=n.toString().trim().toLowerCase(),s=[];e.cut(o,!0).forEach(function(e){s=s.concat(e.split(" "))}),s=s.filter(function(e){return!!e});var u=0;return s.map(function(e,t){if(i){var n=o.indexOf(e,u),s={};return s.position=[n,e.length],s.index=t,u=n,new r.Token(e,s)}return e})},r.zh.wordCharacters="\\w一-龥",r.zh.trimmer=r.trimmerSupport.generateTrimmer(r.zh.wordCharacters),r.Pipeline.registerFunction(r.zh.trimmer,"trimmer-zh"),r.zh.stemmer=function(){return function(e){return e}}(),r.Pipeline.registerFunction(r.zh.stemmer,"stemmer-zh"),r.zh.stopWordFilter=r.generateStopWordFilter("的 一 不 在 人 有 是 为 為 以 于 於 上 他 而 后 後 之 来 來 及 了 因 下 可 到 由 这 這 与 與 也 此 但 并 並 个 個 其 已 无 無 小 我 们 們 起 最 再 今 去 好 只 又 或 很 亦 某 把 那 你 乃 它 吧 被 比 别 趁 当 當 从 從 得 打 凡 儿 兒 尔 爾 该 該 各 给 給 跟 和 何 还 還 即 几 幾 既 看 据 據 距 靠 啦 另 么 麽 每 嘛 拿 哪 您 凭 憑 且 却 卻 让 讓 仍 啥 如 若 使 谁 誰 虽 雖 随 隨 同 所 她 哇 嗡 往 些 向 沿 哟 喲 用 咱 则 則 怎 曾 至 致 着 著 诸 諸 自".split(" ")),r.Pipeline.registerFunction(r.zh.stopWordFilter,"stopWordFilter-zh")}});
-206
View File
@@ -1,206 +0,0 @@
/**
* export the module via AMD, CommonJS or as a browser global
* Export code from https://github.com/umdjs/umd/blob/master/returnExports.js
*/
;(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(factory)
} else if (typeof exports === 'object') {
/**
* Node. Does not work with strict CommonJS, but
* only CommonJS-like environments that support module.exports,
* like Node.
*/
module.exports = factory()
} else {
// Browser globals (root is window)
factory()(root.lunr);
}
}(this, function () {
/**
* Just return a value to define the module export.
* This example returns an object, but the module
* can return a function as the exported value.
*/
return function(lunr) {
// TinySegmenter 0.1 -- Super compact Japanese tokenizer in Javascript
// (c) 2008 Taku Kudo <taku@chasen.org>
// TinySegmenter is freely distributable under the terms of a new BSD licence.
// For details, see http://chasen.org/~taku/software/TinySegmenter/LICENCE.txt
function TinySegmenter() {
var patterns = {
"[一二三四五六七八九十百千万億兆]":"M",
"[一-龠々〆ヵヶ]":"H",
"[ぁ-ん]":"I",
"[ァ-ヴーア-ン゙ー]":"K",
"[a-zA-Z-zA-]":"A",
"[0-9-]":"N"
}
this.chartype_ = [];
for (var i in patterns) {
var regexp = new RegExp(i);
this.chartype_.push([regexp, patterns[i]]);
}
this.BIAS__ = -332
this.BC1__ = {"HH":6,"II":2461,"KH":406,"OH":-1378};
this.BC2__ = {"AA":-3267,"AI":2744,"AN":-878,"HH":-4070,"HM":-1711,"HN":4012,"HO":3761,"IA":1327,"IH":-1184,"II":-1332,"IK":1721,"IO":5492,"KI":3831,"KK":-8741,"MH":-3132,"MK":3334,"OO":-2920};
this.BC3__ = {"HH":996,"HI":626,"HK":-721,"HN":-1307,"HO":-836,"IH":-301,"KK":2762,"MK":1079,"MM":4034,"OA":-1652,"OH":266};
this.BP1__ = {"BB":295,"OB":304,"OO":-125,"UB":352};
this.BP2__ = {"BO":60,"OO":-1762};
this.BQ1__ = {"BHH":1150,"BHM":1521,"BII":-1158,"BIM":886,"BMH":1208,"BNH":449,"BOH":-91,"BOO":-2597,"OHI":451,"OIH":-296,"OKA":1851,"OKH":-1020,"OKK":904,"OOO":2965};
this.BQ2__ = {"BHH":118,"BHI":-1159,"BHM":466,"BIH":-919,"BKK":-1720,"BKO":864,"OHH":-1139,"OHM":-181,"OIH":153,"UHI":-1146};
this.BQ3__ = {"BHH":-792,"BHI":2664,"BII":-299,"BKI":419,"BMH":937,"BMM":8335,"BNN":998,"BOH":775,"OHH":2174,"OHM":439,"OII":280,"OKH":1798,"OKI":-793,"OKO":-2242,"OMH":-2402,"OOO":11699};
this.BQ4__ = {"BHH":-3895,"BIH":3761,"BII":-4654,"BIK":1348,"BKK":-1806,"BMI":-3385,"BOO":-12396,"OAH":926,"OHH":266,"OHK":-2036,"ONN":-973};
this.BW1__ = {",と":660,",同":727,"B1あ":1404,"B1同":542,"、と":660,"、同":727,"」と":1682,"あっ":1505,"いう":1743,"いっ":-2055,"いる":672,"うし":-4817,"うん":665,"から":3472,"がら":600,"こう":-790,"こと":2083,"こん":-1262,"さら":-4143,"さん":4573,"した":2641,"して":1104,"すで":-3399,"そこ":1977,"それ":-871,"たち":1122,"ため":601,"った":3463,"つい":-802,"てい":805,"てき":1249,"でき":1127,"です":3445,"では":844,"とい":-4915,"とみ":1922,"どこ":3887,"ない":5713,"なっ":3015,"など":7379,"なん":-1113,"にし":2468,"には":1498,"にも":1671,"に対":-912,"の一":-501,"の中":741,"ませ":2448,"まで":1711,"まま":2600,"まる":-2155,"やむ":-1947,"よっ":-2565,"れた":2369,"れで":-913,"をし":1860,"を見":731,"亡く":-1886,"京都":2558,"取り":-2784,"大き":-2604,"大阪":1497,"平方":-2314,"引き":-1336,"日本":-195,"本当":-2423,"毎日":-2113,"目指":-724,"B1あ":1404,"B1同":542,"」と":1682};
this.BW2__ = {"..":-11822,"11":-669,"――":-5730,"−−":-13175,"いう":-1609,"うか":2490,"かし":-1350,"かも":-602,"から":-7194,"かれ":4612,"がい":853,"がら":-3198,"きた":1941,"くな":-1597,"こと":-8392,"この":-4193,"させ":4533,"され":13168,"さん":-3977,"しい":-1819,"しか":-545,"した":5078,"して":972,"しな":939,"その":-3744,"たい":-1253,"たた":-662,"ただ":-3857,"たち":-786,"たと":1224,"たは":-939,"った":4589,"って":1647,"っと":-2094,"てい":6144,"てき":3640,"てく":2551,"ては":-3110,"ても":-3065,"でい":2666,"でき":-1528,"でし":-3828,"です":-4761,"でも":-4203,"とい":1890,"とこ":-1746,"とと":-2279,"との":720,"とみ":5168,"とも":-3941,"ない":-2488,"なが":-1313,"など":-6509,"なの":2614,"なん":3099,"にお":-1615,"にし":2748,"にな":2454,"によ":-7236,"に対":-14943,"に従":-4688,"に関":-11388,"のか":2093,"ので":-7059,"のに":-6041,"のの":-6125,"はい":1073,"はが":-1033,"はず":-2532,"ばれ":1813,"まし":-1316,"まで":-6621,"まれ":5409,"めて":-3153,"もい":2230,"もの":-10713,"らか":-944,"らし":-1611,"らに":-1897,"りし":651,"りま":1620,"れた":4270,"れて":849,"れば":4114,"ろう":6067,"われ":7901,"を通":-11877,"んだ":728,"んな":-4115,"一人":602,"一方":-1375,"一日":970,"一部":-1051,"上が":-4479,"会社":-1116,"出て":2163,"分の":-7758,"同党":970,"同日":-913,"大阪":-2471,"委員":-1250,"少な":-1050,"年度":-8669,"年間":-1626,"府県":-2363,"手権":-1982,"新聞":-4066,"日新":-722,"日本":-7068,"日米":3372,"曜日":-601,"朝鮮":-2355,"本人":-2697,"東京":-1543,"然と":-1384,"社会":-1276,"立て":-990,"第に":-1612,"米国":-4268,"11":-669};
this.BW3__ = {"あた":-2194,"あり":719,"ある":3846,"い.":-1185,"い。":-1185,"いい":5308,"いえ":2079,"いく":3029,"いた":2056,"いっ":1883,"いる":5600,"いわ":1527,"うち":1117,"うと":4798,"えと":1454,"か.":2857,"か。":2857,"かけ":-743,"かっ":-4098,"かに":-669,"から":6520,"かり":-2670,"が,":1816,"が、":1816,"がき":-4855,"がけ":-1127,"がっ":-913,"がら":-4977,"がり":-2064,"きた":1645,"けど":1374,"こと":7397,"この":1542,"ころ":-2757,"さい":-714,"さを":976,"し,":1557,"し、":1557,"しい":-3714,"した":3562,"して":1449,"しな":2608,"しま":1200,"す.":-1310,"す。":-1310,"する":6521,"ず,":3426,"ず、":3426,"ずに":841,"そう":428,"た.":8875,"た。":8875,"たい":-594,"たの":812,"たり":-1183,"たる":-853,"だ.":4098,"だ。":4098,"だっ":1004,"った":-4748,"って":300,"てい":6240,"てお":855,"ても":302,"です":1437,"でに":-1482,"では":2295,"とう":-1387,"とし":2266,"との":541,"とも":-3543,"どう":4664,"ない":1796,"なく":-903,"など":2135,"に,":-1021,"に、":-1021,"にし":1771,"にな":1906,"には":2644,"の,":-724,"の、":-724,"の子":-1000,"は,":1337,"は、":1337,"べき":2181,"まし":1113,"ます":6943,"まっ":-1549,"まで":6154,"まれ":-793,"らし":1479,"られ":6820,"るる":3818,"れ,":854,"れ、":854,"れた":1850,"れて":1375,"れば":-3246,"れる":1091,"われ":-605,"んだ":606,"んで":798,"カ月":990,"会議":860,"入り":1232,"大会":2217,"始め":1681,"市":965,"新聞":-5055,"日,":974,"日、":974,"社会":2024,"カ月":990};
this.TC1__ = {"AAA":1093,"HHH":1029,"HHM":580,"HII":998,"HOH":-390,"HOM":-331,"IHI":1169,"IOH":-142,"IOI":-1015,"IOM":467,"MMH":187,"OOI":-1832};
this.TC2__ = {"HHO":2088,"HII":-1023,"HMM":-1154,"IHI":-1965,"KKH":703,"OII":-2649};
this.TC3__ = {"AAA":-294,"HHH":346,"HHI":-341,"HII":-1088,"HIK":731,"HOH":-1486,"IHH":128,"IHI":-3041,"IHO":-1935,"IIH":-825,"IIM":-1035,"IOI":-542,"KHH":-1216,"KKA":491,"KKH":-1217,"KOK":-1009,"MHH":-2694,"MHM":-457,"MHO":123,"MMH":-471,"NNH":-1689,"NNO":662,"OHO":-3393};
this.TC4__ = {"HHH":-203,"HHI":1344,"HHK":365,"HHM":-122,"HHN":182,"HHO":669,"HIH":804,"HII":679,"HOH":446,"IHH":695,"IHO":-2324,"IIH":321,"III":1497,"IIO":656,"IOO":54,"KAK":4845,"KKA":3386,"KKK":3065,"MHH":-405,"MHI":201,"MMH":-241,"MMM":661,"MOM":841};
this.TQ1__ = {"BHHH":-227,"BHHI":316,"BHIH":-132,"BIHH":60,"BIII":1595,"BNHH":-744,"BOHH":225,"BOOO":-908,"OAKK":482,"OHHH":281,"OHIH":249,"OIHI":200,"OIIH":-68};
this.TQ2__ = {"BIHH":-1401,"BIII":-1033,"BKAK":-543,"BOOO":-5591};
this.TQ3__ = {"BHHH":478,"BHHM":-1073,"BHIH":222,"BHII":-504,"BIIH":-116,"BIII":-105,"BMHI":-863,"BMHM":-464,"BOMH":620,"OHHH":346,"OHHI":1729,"OHII":997,"OHMH":481,"OIHH":623,"OIIH":1344,"OKAK":2792,"OKHH":587,"OKKA":679,"OOHH":110,"OOII":-685};
this.TQ4__ = {"BHHH":-721,"BHHM":-3604,"BHII":-966,"BIIH":-607,"BIII":-2181,"OAAA":-2763,"OAKK":180,"OHHH":-294,"OHHI":2446,"OHHO":480,"OHIH":-1573,"OIHH":1935,"OIHI":-493,"OIIH":626,"OIII":-4007,"OKAK":-8156};
this.TW1__ = {"につい":-4681,"東京都":2026};
this.TW2__ = {"ある程":-2049,"いった":-1256,"ころが":-2434,"しょう":3873,"その後":-4430,"だって":-1049,"ていた":1833,"として":-4657,"ともに":-4517,"もので":1882,"一気に":-792,"初めて":-1512,"同時に":-8097,"大きな":-1255,"対して":-2721,"社会党":-3216};
this.TW3__ = {"いただ":-1734,"してい":1314,"として":-4314,"につい":-5483,"にとっ":-5989,"に当た":-6247,"ので,":-727,"ので、":-727,"のもの":-600,"れから":-3752,"十二月":-2287};
this.TW4__ = {"いう.":8576,"いう。":8576,"からな":-2348,"してい":2958,"たが,":1516,"たが、":1516,"ている":1538,"という":1349,"ました":5543,"ません":1097,"ようと":-4258,"よると":5865};
this.UC1__ = {"A":484,"K":93,"M":645,"O":-505};
this.UC2__ = {"A":819,"H":1059,"I":409,"M":3987,"N":5775,"O":646};
this.UC3__ = {"A":-1370,"I":2311};
this.UC4__ = {"A":-2643,"H":1809,"I":-1032,"K":-3450,"M":3565,"N":3876,"O":6646};
this.UC5__ = {"H":313,"I":-1238,"K":-799,"M":539,"O":-831};
this.UC6__ = {"H":-506,"I":-253,"K":87,"M":247,"O":-387};
this.UP1__ = {"O":-214};
this.UP2__ = {"B":69,"O":935};
this.UP3__ = {"B":189};
this.UQ1__ = {"BH":21,"BI":-12,"BK":-99,"BN":142,"BO":-56,"OH":-95,"OI":477,"OK":410,"OO":-2422};
this.UQ2__ = {"BH":216,"BI":113,"OK":1759};
this.UQ3__ = {"BA":-479,"BH":42,"BI":1913,"BK":-7198,"BM":3160,"BN":6427,"BO":14761,"OI":-827,"ON":-3212};
this.UW1__ = {",":156,"、":156,"「":-463,"あ":-941,"う":-127,"が":-553,"き":121,"こ":505,"で":-201,"と":-547,"ど":-123,"に":-789,"の":-185,"は":-847,"も":-466,"や":-470,"よ":182,"ら":-292,"り":208,"れ":169,"を":-446,"ん":-137,"・":-135,"主":-402,"京":-268,"区":-912,"午":871,"国":-460,"大":561,"委":729,"市":-411,"日":-141,"理":361,"生":-408,"県":-386,"都":-718,"「":-463,"・":-135};
this.UW2__ = {",":-829,"、":-829,"":892,"「":-645,"」":3145,"あ":-538,"い":505,"う":134,"お":-502,"か":1454,"が":-856,"く":-412,"こ":1141,"さ":878,"ざ":540,"し":1529,"す":-675,"せ":300,"そ":-1011,"た":188,"だ":1837,"つ":-949,"て":-291,"で":-268,"と":-981,"ど":1273,"な":1063,"に":-1764,"の":130,"は":-409,"ひ":-1273,"べ":1261,"ま":600,"も":-1263,"や":-402,"よ":1639,"り":-579,"る":-694,"れ":571,"を":-2516,"ん":2095,"ア":-587,"カ":306,"キ":568,"ッ":831,"三":-758,"不":-2150,"世":-302,"中":-968,"主":-861,"事":492,"人":-123,"会":978,"保":362,"入":548,"初":-3025,"副":-1566,"北":-3414,"区":-422,"大":-1769,"天":-865,"太":-483,"子":-1519,"学":760,"実":1023,"小":-2009,"市":-813,"年":-1060,"強":1067,"手":-1519,"揺":-1033,"政":1522,"文":-1355,"新":-1682,"日":-1815,"明":-1462,"最":-630,"朝":-1843,"本":-1650,"東":-931,"果":-665,"次":-2378,"民":-180,"気":-1740,"理":752,"発":529,"目":-1584,"相":-242,"県":-1165,"立":-763,"第":810,"米":509,"自":-1353,"行":838,"西":-744,"見":-3874,"調":1010,"議":1198,"込":3041,"開":1758,"間":-1257,"「":-645,"」":3145,"ッ":831,"ア":-587,"カ":306,"キ":568};
this.UW3__ = {",":4889,"1":-800,"":-1723,"、":4889,"々":-2311,"":5827,"」":2670,"〓":-3573,"あ":-2696,"い":1006,"う":2342,"え":1983,"お":-4864,"か":-1163,"が":3271,"く":1004,"け":388,"げ":401,"こ":-3552,"ご":-3116,"さ":-1058,"し":-395,"す":584,"せ":3685,"そ":-5228,"た":842,"ち":-521,"っ":-1444,"つ":-1081,"て":6167,"で":2318,"と":1691,"ど":-899,"な":-2788,"に":2745,"の":4056,"は":4555,"ひ":-2171,"ふ":-1798,"へ":1199,"ほ":-5516,"ま":-4384,"み":-120,"め":1205,"も":2323,"や":-788,"よ":-202,"ら":727,"り":649,"る":5905,"れ":2773,"わ":-1207,"を":6620,"ん":-518,"ア":551,"グ":1319,"ス":874,"ッ":-1350,"ト":521,"ム":1109,"ル":1591,"ロ":2201,"ン":278,"・":-3794,"一":-1619,"下":-1759,"世":-2087,"両":3815,"中":653,"主":-758,"予":-1193,"二":974,"人":2742,"今":792,"他":1889,"以":-1368,"低":811,"何":4265,"作":-361,"保":-2439,"元":4858,"党":3593,"全":1574,"公":-3030,"六":755,"共":-1880,"円":5807,"再":3095,"分":457,"初":2475,"別":1129,"前":2286,"副":4437,"力":365,"動":-949,"務":-1872,"化":1327,"北":-1038,"区":4646,"千":-2309,"午":-783,"協":-1006,"口":483,"右":1233,"各":3588,"合":-241,"同":3906,"和":-837,"員":4513,"国":642,"型":1389,"場":1219,"外":-241,"妻":2016,"学":-1356,"安":-423,"実":-1008,"家":1078,"小":-513,"少":-3102,"州":1155,"市":3197,"平":-1804,"年":2416,"広":-1030,"府":1605,"度":1452,"建":-2352,"当":-3885,"得":1905,"思":-1291,"性":1822,"戸":-488,"指":-3973,"政":-2013,"教":-1479,"数":3222,"文":-1489,"新":1764,"日":2099,"旧":5792,"昨":-661,"時":-1248,"曜":-951,"最":-937,"月":4125,"期":360,"李":3094,"村":364,"東":-805,"核":5156,"森":2438,"業":484,"氏":2613,"民":-1694,"決":-1073,"法":1868,"海":-495,"無":979,"物":461,"特":-3850,"生":-273,"用":914,"町":1215,"的":7313,"直":-1835,"省":792,"県":6293,"知":-1528,"私":4231,"税":401,"立":-960,"第":1201,"米":7767,"系":3066,"約":3663,"級":1384,"統":-4229,"総":1163,"線":1255,"者":6457,"能":725,"自":-2869,"英":785,"見":1044,"調":-562,"財":-733,"費":1777,"車":1835,"軍":1375,"込":-1504,"通":-1136,"選":-681,"郎":1026,"郡":4404,"部":1200,"金":2163,"長":421,"開":-1432,"間":1302,"関":-1282,"雨":2009,"電":-1045,"非":2066,"駅":1620,"":-800,"」":2670,"・":-3794,"ッ":-1350,"ア":551,"グ":1319,"ス":874,"ト":521,"ム":1109,"ル":1591,"ロ":2201,"ン":278};
this.UW4__ = {",":3930,".":3508,"―":-4841,"、":3930,"。":3508,"":4999,"「":1895,"」":3798,"〓":-5156,"あ":4752,"い":-3435,"う":-640,"え":-2514,"お":2405,"か":530,"が":6006,"き":-4482,"ぎ":-3821,"く":-3788,"け":-4376,"げ":-4734,"こ":2255,"ご":1979,"さ":2864,"し":-843,"じ":-2506,"す":-731,"ず":1251,"せ":181,"そ":4091,"た":5034,"だ":5408,"ち":-3654,"っ":-5882,"つ":-1659,"て":3994,"で":7410,"と":4547,"な":5433,"に":6499,"ぬ":1853,"ね":1413,"の":7396,"は":8578,"ば":1940,"ひ":4249,"び":-4134,"ふ":1345,"へ":6665,"べ":-744,"ほ":1464,"ま":1051,"み":-2082,"む":-882,"め":-5046,"も":4169,"ゃ":-2666,"や":2795,"ょ":-1544,"よ":3351,"ら":-2922,"り":-9726,"る":-14896,"れ":-2613,"ろ":-4570,"わ":-1783,"を":13150,"ん":-2352,"カ":2145,"コ":1789,"セ":1287,"ッ":-724,"ト":-403,"メ":-1635,"ラ":-881,"リ":-541,"ル":-856,"ン":-3637,"・":-4371,"ー":-11870,"一":-2069,"中":2210,"予":782,"事":-190,"井":-1768,"人":1036,"以":544,"会":950,"体":-1286,"作":530,"側":4292,"先":601,"党":-2006,"共":-1212,"内":584,"円":788,"初":1347,"前":1623,"副":3879,"力":-302,"動":-740,"務":-2715,"化":776,"区":4517,"協":1013,"参":1555,"合":-1834,"和":-681,"員":-910,"器":-851,"回":1500,"国":-619,"園":-1200,"地":866,"場":-1410,"塁":-2094,"士":-1413,"多":1067,"大":571,"子":-4802,"学":-1397,"定":-1057,"寺":-809,"小":1910,"屋":-1328,"山":-1500,"島":-2056,"川":-2667,"市":2771,"年":374,"庁":-4556,"後":456,"性":553,"感":916,"所":-1566,"支":856,"改":787,"政":2182,"教":704,"文":522,"方":-856,"日":1798,"時":1829,"最":845,"月":-9066,"木":-485,"来":-442,"校":-360,"業":-1043,"氏":5388,"民":-2716,"気":-910,"沢":-939,"済":-543,"物":-735,"率":672,"球":-1267,"生":-1286,"産":-1101,"田":-2900,"町":1826,"的":2586,"目":922,"省":-3485,"県":2997,"空":-867,"立":-2112,"第":788,"米":2937,"系":786,"約":2171,"経":1146,"統":-1169,"総":940,"線":-994,"署":749,"者":2145,"能":-730,"般":-852,"行":-792,"規":792,"警":-1184,"議":-244,"谷":-1000,"賞":730,"車":-1481,"軍":1158,"輪":-1433,"込":-3370,"近":929,"道":-1291,"選":2596,"郎":-4866,"都":1192,"野":-1100,"銀":-2213,"長":357,"間":-2344,"院":-2297,"際":-2604,"電":-878,"領":-1659,"題":-792,"館":-1984,"首":1749,"高":2120,"「":1895,"」":3798,"・":-4371,"ッ":-724,"ー":-11870,"カ":2145,"コ":1789,"セ":1287,"ト":-403,"メ":-1635,"ラ":-881,"リ":-541,"ル":-856,"ン":-3637};
this.UW5__ = {",":465,".":-299,"1":-514,"E2":-32768,"]":-2762,"、":465,"。":-299,"「":363,"あ":1655,"い":331,"う":-503,"え":1199,"お":527,"か":647,"が":-421,"き":1624,"ぎ":1971,"く":312,"げ":-983,"さ":-1537,"し":-1371,"す":-852,"だ":-1186,"ち":1093,"っ":52,"つ":921,"て":-18,"で":-850,"と":-127,"ど":1682,"な":-787,"に":-1224,"の":-635,"は":-578,"べ":1001,"み":502,"め":865,"ゃ":3350,"ょ":854,"り":-208,"る":429,"れ":504,"わ":419,"を":-1264,"ん":327,"イ":241,"ル":451,"ン":-343,"中":-871,"京":722,"会":-1153,"党":-654,"務":3519,"区":-901,"告":848,"員":2104,"大":-1296,"学":-548,"定":1785,"嵐":-1304,"市":-2991,"席":921,"年":1763,"思":872,"所":-814,"挙":1618,"新":-1682,"日":218,"月":-4353,"査":932,"格":1356,"機":-1508,"氏":-1347,"田":240,"町":-3912,"的":-3149,"相":1319,"省":-1052,"県":-4003,"研":-997,"社":-278,"空":-813,"統":1955,"者":-2233,"表":663,"語":-1073,"議":1219,"選":-1018,"郎":-368,"長":786,"間":1191,"題":2368,"館":-689,"":-514,"E2":-32768,"「":363,"イ":241,"ル":451,"ン":-343};
this.UW6__ = {",":227,".":808,"1":-270,"E1":306,"、":227,"。":808,"あ":-307,"う":189,"か":241,"が":-73,"く":-121,"こ":-200,"じ":1782,"す":383,"た":-428,"っ":573,"て":-1014,"で":101,"と":-105,"な":-253,"に":-149,"の":-417,"は":-236,"も":-206,"り":187,"る":-135,"を":195,"ル":-673,"ン":-496,"一":-277,"中":201,"件":-800,"会":624,"前":302,"区":1792,"員":-1212,"委":798,"学":-960,"市":887,"広":-695,"後":535,"業":-697,"相":753,"社":-507,"福":974,"空":-822,"者":1811,"連":463,"郎":1082,"":-270,"E1":306,"ル":-673,"ン":-496};
return this;
}
TinySegmenter.prototype.ctype_ = function(str) {
for (var i in this.chartype_) {
if (str.match(this.chartype_[i][0])) {
return this.chartype_[i][1];
}
}
return "O";
}
TinySegmenter.prototype.ts_ = function(v) {
if (v) { return v; }
return 0;
}
TinySegmenter.prototype.segment = function(input) {
if (input == null || input == undefined || input == "") {
return [];
}
var result = [];
var seg = ["B3","B2","B1"];
var ctype = ["O","O","O"];
var o = input.split("");
for (i = 0; i < o.length; ++i) {
seg.push(o[i]);
ctype.push(this.ctype_(o[i]))
}
seg.push("E1");
seg.push("E2");
seg.push("E3");
ctype.push("O");
ctype.push("O");
ctype.push("O");
var word = seg[3];
var p1 = "U";
var p2 = "U";
var p3 = "U";
for (var i = 4; i < seg.length - 3; ++i) {
var score = this.BIAS__;
var w1 = seg[i-3];
var w2 = seg[i-2];
var w3 = seg[i-1];
var w4 = seg[i];
var w5 = seg[i+1];
var w6 = seg[i+2];
var c1 = ctype[i-3];
var c2 = ctype[i-2];
var c3 = ctype[i-1];
var c4 = ctype[i];
var c5 = ctype[i+1];
var c6 = ctype[i+2];
score += this.ts_(this.UP1__[p1]);
score += this.ts_(this.UP2__[p2]);
score += this.ts_(this.UP3__[p3]);
score += this.ts_(this.BP1__[p1 + p2]);
score += this.ts_(this.BP2__[p2 + p3]);
score += this.ts_(this.UW1__[w1]);
score += this.ts_(this.UW2__[w2]);
score += this.ts_(this.UW3__[w3]);
score += this.ts_(this.UW4__[w4]);
score += this.ts_(this.UW5__[w5]);
score += this.ts_(this.UW6__[w6]);
score += this.ts_(this.BW1__[w2 + w3]);
score += this.ts_(this.BW2__[w3 + w4]);
score += this.ts_(this.BW3__[w4 + w5]);
score += this.ts_(this.TW1__[w1 + w2 + w3]);
score += this.ts_(this.TW2__[w2 + w3 + w4]);
score += this.ts_(this.TW3__[w3 + w4 + w5]);
score += this.ts_(this.TW4__[w4 + w5 + w6]);
score += this.ts_(this.UC1__[c1]);
score += this.ts_(this.UC2__[c2]);
score += this.ts_(this.UC3__[c3]);
score += this.ts_(this.UC4__[c4]);
score += this.ts_(this.UC5__[c5]);
score += this.ts_(this.UC6__[c6]);
score += this.ts_(this.BC1__[c2 + c3]);
score += this.ts_(this.BC2__[c3 + c4]);
score += this.ts_(this.BC3__[c4 + c5]);
score += this.ts_(this.TC1__[c1 + c2 + c3]);
score += this.ts_(this.TC2__[c2 + c3 + c4]);
score += this.ts_(this.TC3__[c3 + c4 + c5]);
score += this.ts_(this.TC4__[c4 + c5 + c6]);
// score += this.ts_(this.TC5__[c4 + c5 + c6]);
score += this.ts_(this.UQ1__[p1 + c1]);
score += this.ts_(this.UQ2__[p2 + c2]);
score += this.ts_(this.UQ3__[p3 + c3]);
score += this.ts_(this.BQ1__[p2 + c2 + c3]);
score += this.ts_(this.BQ2__[p2 + c3 + c4]);
score += this.ts_(this.BQ3__[p3 + c2 + c3]);
score += this.ts_(this.BQ4__[p3 + c3 + c4]);
score += this.ts_(this.TQ1__[p2 + c1 + c2 + c3]);
score += this.ts_(this.TQ2__[p2 + c2 + c3 + c4]);
score += this.ts_(this.TQ3__[p3 + c1 + c2 + c3]);
score += this.ts_(this.TQ4__[p3 + c2 + c3 + c4]);
var p = "O";
if (score > 0) {
result.push(word);
word = "";
p = "B";
}
p1 = p2;
p2 = p3;
p3 = p;
word += seg[i];
}
result.push(word);
return result;
}
lunr.TinySegmenter = TinySegmenter;
};
}));
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
{"version":3,"sources":["src/templates/assets/stylesheets/palette/_scheme.scss","../../../../src/templates/assets/stylesheets/palette.scss","src/templates/assets/stylesheets/palette/_accent.scss","src/templates/assets/stylesheets/palette/_primary.scss","src/templates/assets/stylesheets/utilities/_break.scss"],"names":[],"mappings":"AA2BA,cAGE,6BAME,sDAAA,CACA,6DAAA,CACA,+DAAA,CACA,gEAAA,CACA,mDAAA,CACA,6DAAA,CACA,+DAAA,CACA,gEAAA,CAGA,mDAAA,CACA,gDAAA,CACA,yDAAA,CACA,4DAAA,CAGA,0BAAA,CACA,mCAAA,CAGA,iCAAA,CACA,kCAAA,CACA,mCAAA,CACA,mCAAA,CACA,kCAAA,CACA,iCAAA,CACA,+CAAA,CACA,6DAAA,CACA,gEAAA,CACA,4DAAA,CACA,4DAAA,CACA,6DAAA,CAGA,6CAAA,CAGA,+CAAA,CAGA,uDAAA,CACA,6DAAA,CACA,2DAAA,CAGA,iCAAA,CAGA,yDAAA,CACA,iEAAA,CAGA,mDAAA,CACA,mDAAA,CAGA,qDAAA,CACA,uDAAA,CAGA,8DAAA,CAKA,8DAAA,CAKA,0DAAA,CAzEA,iBCiBF,CD6DE,kHAEE,YC3DJ,CDkFE,yDACE,4BChFJ,CD+EE,2DACE,4BC7EJ,CD4EE,gEACE,4BC1EJ,CDyEE,2DACE,4BCvEJ,CDsEE,yDACE,4BCpEJ,CDmEE,0DACE,4BCjEJ,CDgEE,gEACE,4BC9DJ,CD6DE,0DACE,4BC3DJ,CD0DE,2OACE,4BC/CJ,CDsDA,+FAGE,iCCpDF,CACF,CCjDE,2BACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCD6CN,CCvDE,4BACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCDoDN,CC9DE,8BACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCD2DN,CCrEE,mCACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCDkEN,CC5EE,8BACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCDyEN,CCnFE,4BACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCDgFN,CC1FE,kCACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCDuFN,CCjGE,4BACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCD8FN,CCxGE,4BACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCDqGN,CC/GE,6BACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCD4GN,CCtHE,mCACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCDmHN,CC7HE,4BACE,4BAAA,CACA,2CAAA,CAIE,8BAAA,CACA,qCD6HN,CCpIE,8BACE,4BAAA,CACA,2CAAA,CAIE,8BAAA,CACA,qCDoIN,CC3IE,6BACE,yBAAA,CACA,2CAAA,CAIE,8BAAA,CACA,qCD2IN,CClJE,8BACE,4BAAA,CACA,2CAAA,CAIE,8BAAA,CACA,qCDkJN,CCzJE,mCACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCDsJN,CE3JE,4BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFwJN,CEnKE,6BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFgKN,CE3KE,+BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFwKN,CEnLE,oCACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFgLN,CE3LE,+BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFwLN,CEnME,6BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFgMN,CE3ME,mCACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFwMN,CEnNE,6BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFgNN,CE3NE,6BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFwNN,CEnOE,8BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFgON,CE3OE,oCACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFwON,CEnPE,6BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAIE,+BAAA,CACA,sCFmPN,CE3PE,+BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAIE,+BAAA,CACA,sCF2PN,CEnQE,8BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAIE,+BAAA,CACA,sCFmQN,CE3QE,+BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAIE,+BAAA,CACA,sCF2QN,CEnRE,oCACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFgRN,CE3RE,8BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFwRN,CEnSE,6BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCAAA,CAKA,4BF4RN,CE5SE,kCACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCAAA,CAKA,4BFqSN,CEtRE,sEACE,4BFyRJ,CE1RE,+DACE,4BF6RJ,CE9RE,iEACE,4BFiSJ,CElSE,gEACE,4BFqSJ,CEtSE,iEACE,4BFySJ,CEhSA,8BACE,mDAAA,CACA,4DAAA,CACA,0DAAA,CACA,oDAAA,CACA,2DAAA,CAGA,4BFiSF,CE9RE,yCACE,+BFgSJ,CE7RI,kDAEE,0CAAA,CACA,sCAAA,CAFA,mCFiSN,CG7MI,mCD1EA,+CACE,8CF0RJ,CEvRI,qDACE,8CFyRN,CEpRE,iEACE,mCFsRJ,CACF,CGxNI,sCDvDA,uCACE,oCFkRJ,CACF,CEzQA,8BACE,kDAAA,CACA,4DAAA,CACA,wDAAA,CACA,oDAAA,CACA,6DAAA,CAGA,4BF0QF,CEvQE,yCACE,+BFyQJ,CEtQI,kDAEE,0CAAA,CACA,sCAAA,CAFA,mCF0QN,CEnQE,yCACE,6CFqQJ,CG9NI,0CDhCA,8CACE,gDFiQJ,CACF,CGnOI,0CDvBA,iFACE,6CF6PJ,CACF,CG3PI,sCDKA,uCACE,6CFyPJ,CACF","file":"palette.css"}
+52
View File
@@ -0,0 +1,52 @@
#!/bin/zsh
# in case of $'\r': command not found error, run command below first
# sed -i 's/\r$//' ./bootstrap.sh
CLUSTER="${1:?Usage: ./bootstrap.sh <cluster> (upc-dev|upc-prod|aks-dev|aks-prod|eks-dev|eks-prod|gke-dev|gke-prod)}"
echo "running $0 for cluster: ${CLUSTER}..."
# Source cluster config
eval $(yq -r 'to_entries[] | "export \(.key)=\"\(.value)\""' "clusters/${CLUSTER}.yaml")
echo "Bootstrapping cluster: ${clusterName} (${CLUSTER})..."
############################################################
# Bootstrap #
############################################################
Bootstrap()
{
ArgoCd
# Gitea
}
############################################################
# Gitea #
############################################################
Gitea()
{
echo "Installing secret..."
kubectl apply -f private/gitea-repo-main.yaml
kubectl apply -f private/main.key
}
############################################################
# ArgoCd #
############################################################
ArgoCd()
{
# install argocd
echo "Installing ArgoCD..."
helm upgrade --install argocd argo-cd \
--repo https://argoproj.github.io/argo-helm \
--namespace argocd --create-namespace \
--values infra/values/base/argocd-values.yaml \
--values "infra/values/${CLUSTER}/argocd-values.yaml" \
--set notifications.context.clusterName="${clusterName}" \
--timeout 60s --atomic
kubectl apply -f "_app-of-apps-${CLUSTER}.yaml" -n argocd
}
# Bootstrap
@@ -0,0 +1,16 @@
---
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
creationTimestamp: null
name: argocd-notifications-secret
namespace: argocd
spec:
encryptedData:
slack-webhook-url: AgBIIEfU1TzNNJoQMsiKqF+x0y5vGu5iMwvTADGuUcjlz7DtfExTQu86OdUO1+Gxri/NKKj+KN1Tv7WNJs5Yo/hjjLs/JTxKYuEF6S0xaqLX3sRCkMCdVpRkH079CW4ayDP2moIGrG9+nq0iGNA7qyPssjjSCeMaj6SiHAIXdV+f/5XLrwHUybL2drBp7OVsZcLQJhQRGYIM/R4PvQJGLv95L/XPn5aOK8jxhHIsaxwRlAuGpCP/Ct7mG6H2qL0zKZn/H7Vl+x/Xgx0a/VGcEMosgQY1PeSqihyTcCsSu1g2rd8A03nw8v3kIjkiMzSpIKHoEpWuoNWxDmwMYrpvy1QUnpW2nT9WkLoaoi4lczNr63Z/LT2mCTMhgC83OxF5IA/9cekWh+VMHVsS2c4qQvlDZoT2N4SwkWy++rreFwrXdaMBJHIQI2wT9rtWwRLG4sLigaxBPX7lzVlplkSxHgrVi6c329u6+2Dcw9eMOPfw7GmbnF5H+t1AmFEBbrf2LOPGRy3yd+5g5U4Eyhf7YmA9SaT7TB1w3UhacSCslVH41NLtqNV65lvAjPCyYbEEjmnV02i9rPDyHMitrZ9Z8Spzo3oiK0ZndWh98u8iA7NJY2i+L01n7OLGjRBGL364URHRqcDxCPRrc0ApRBj5aa4HEScowmWCPcoqgzwFfclAz2iNAgQ7h+7/rUN2k96V7Eo0xco+bF/XgwWX5ehIB6FQYKborWa7XHvAGEc85eD3bNOnOUF1RJB/4GzN5yu/7fyeRVnKNEAzZ2cuXD+5RA5gPyqBVgTFspl2MasbMW9KOZT4YKts0ILXqpo=
template:
metadata:
creationTimestamp: null
name: argocd-notifications-secret
namespace: argocd
type: Opaque
@@ -0,0 +1,7 @@
---
# Disable Istio sidecar injection for cert-manager namespace
# This is required for cert-manager to function properly with Istio
apiVersion: v1
kind: Namespace
metadata:
name: cert-manager
@@ -0,0 +1,20 @@
---
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
creationTimestamp: null
name: forte10x-repo-creds
namespace: argocd
spec:
encryptedData:
sshPrivateKey: AgBJ0kYo34Fd52HXd6lNo3QUUesZx/8s3f3U6VYuRP+hwLWRx/toh2+33H3FSvEJlHakMiXOnKSFePP7xS2xi7+ZnjQUviw/dueDzTMAAL6jR11VNc4wLZBmvBlISW3/lRA7dVy8vhyP5FCt1gizwx8+bCDFSJqG6Z2Ca2NuxSC+d3kYL1BTcGOda9SApht/RNM0HY11WGBVEoT/AP8zqwtG3vOTWGiqRkU/UgKbnOIzVrv0ZqwAloj/7+4LgaD7rpy5wPx6WFakjD5ON0xZF1uiusAoa5i+ukMSsmNGTko5qMhkcCyS41H0RgnLKW5UoOuY9Ewvp/8/49FN8hhmAZU0PVVfcKalZYFaei+Ka79oaoKpACHLOevCjMF2sgLEOdtow5nVMlxmsCYWb1cPtuczUH0bGwmNOAmS4Y0cuxc3++5UXZiML5n9Hnfl8K1rxeHWB0nzlRuzwj/JKItBcsjVdF9F+fAHAt8LDzxuqOt+PyyABXHk0aZ56DCvUDm90IAm8ojufLbGWXeouiudM11UxAP9ySp4FB9ou+re6F11ZFE3yVgScKlfpu0bHUFFhm+glVLF+8nlv8E6a1LCb+HOP3WwwXJ0OB9KnYaFhrTuvF9pOVwX9zUs4QCWq323jzTrK8yR3upybxIbfPTF/iMzTQliDUuA5WpK0y2/B+OoeMevuqR4HklUp/OHGpigfTo9p4JtR6f96foXpgg4ViNrl2FwKK8imSkGqTj1NoqFs0gseq3Q/9w5BB0gOd4hK9o3flXljz1wpJxwYWX8ogM05eJD83pjX0b0hvWk1fEZHx+xFLVhm6vYXNfsZ+nnwwEyLV6PdEW2gVYJQo8+e0eVX5eUnynZCL96BgjCkUa/Yvfds1L1q7vzyYOT7t4h4qqmlAwDsUwbPbdANZ26Ybehjn8kS9e9V4oPzk7yvsqzSfzX4UUoFjQsB7ETmiNVbWEYJpAkTJ6OcPQUD12SCW3BDmwmBjpwPOjwl9/zRJezKOdFVncDKtOzXtef7Q+bdNR85klOTmxpEV3GFpp+Qh6xbYuSREYm+N5B1rLcgvoA34VZDmMbQwdlfK2tXG1lO1fnM9inhdU0SDVfgqqeiPZHMhV8TaajQNWEtQJij6VW8/Lsm4yxbKs5cg6ung5I30saaM8LFTI0Njq5/TpbF753+F/v5SV275o5+0MFCZDER30Nh/uFipTpvzOFrQlG/bHrT3/rUnw1dfYz0BcUO7V0KaUQFzV2ArPsNxc=
type: AgBwM8m/1ZFU6Wdwq3riZkRBlcqLRe4t3MK3T7L6s0Cr7rVsE2QIw7JJgJWW77plgqWYUANxLd8pcXeC3uqvLH7ApYWN0kFzpPD/qK7ZVD13Tq+OnXE+zZyEYwr9YH790ca+KFrJJTewX9zN1Y3KSeyNX2ko0UndPn99PNAhtMCeMrsiJ59HgE66fnq+iGx7Ghs3xai7FVAmQADeaAd5WHkfzN0jEKFccZ/nV60cisqwVttFB0Rt+eMywAoRXw9+mmSVmwGX/bDfO6fm2C3O+GQrVa80E57iXeMO3m6G/lRCjA+9If6lg8QyuD3W+3Xnm3IC5pHEtYFjj8J4cwa4qTMcYsyfOt/NtmWD8KlLNcIFzP/uMar1WQ256PWPoN60pM9mTe6Jyz0sq3L4H/KC/5EfbOJ4tm5QN6/57mcls0eOfOP3JzV92zvC/Z4exjlvEqmKK/T/gMtXCv29ITWtmQWkXtfERuVxB13kXN4gJVuffMKKrsr5uOm5n17PQd1GLoDYo/8nRyNBu4H6+9r8LcAuaE7z4cETuYC9EM3gp4ZkeuwTwNjnNYyrs8nNxGzjVTc1HIhfKGZkJilF0BhXiSmrNczEFBZqC30vgChJ2ko/RePQsxh32rXfdZ1RBGL1B2o8Nf4FZQz6dMpuNeei0tjfo2rq7LCB3Ze8vj8q/iQDAlRbunkevYhTotXPZoZXdcs5VkA=
url: AgBT+Tyn3YN731bMBG9jJv8F+jda1vA/0DemSL9SWxZFfrH4xSGlg3IITOW+iN4lDDKNiceHFRXcxVSYrStArEnGbBy5a7GvXBuKpwshal3MXGwt1iy5fZZH4nKzKCkLRmECFI4/N/zJpqxWxmiQtXMtBYIPyf97ulaPg4R9h0CwDAfesgbfmfsxB3F6ceUj6BkKHxx36Ca6AlNc06FhqmR307kAnijdfg0Ji+geqnqpruDG2717n5s6+xQG03GiM8rWAnny/4GDkYQsuRxaaRl4skalSS0UfvsoBwdfmn5Uvem6zefbnHaP9j9r5xI5ZN23QB6dQhzMooVHz8vgzn06mj73YkLVSYCwU0cMSOgDr9RWVOxkpCqrP3p76c3Xzj91K+OzVUHfvYbxBuypNJoojCG5bP1amuwtFs8rBSiCONxSTNjStvXN3qDCRKpHmskHlVeH4Lsn20UFOd+vsQue1vfb1jMxQ6I3xi5AUZO6x8TJCGR33EswbGF6ZGvJXuW+S7XtgjUgGMgWcGpBHpjk5EAFCPO83AFf8iNlbX30th/eDsIs1tX7b+RD1+QJYuJsC6pBIU3cVdjDy1Mjb3ViadwkWy6sEytL1NMpRBh7A2T/oIZV0DFkI4wul5y5hztQrNgzzJH9MGeLLxtAxtb1ZTb+StJJjr39c+mXOZMDzl4/cv3KNoj7hTJo1H6y0KbiIjQuaEl6XZdGu/46ZmdearxEPL/60Rtonf/wUve8UV0pqYEVaadHx2ui
template:
metadata:
creationTimestamp: null
labels:
argocd.argoproj.io/secret-type: repository
name: forte10x-repo-creds
namespace: argocd
type: Opaque
@@ -0,0 +1,88 @@
apiVersion: batch/v1
kind: CronJob
metadata:
name: gitea-backup
namespace: gitea
spec:
schedule: "0 3 * * *" # daily at 03:00 UTC
concurrencyPolicy: Forbid
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 3
jobTemplate:
spec:
backoffLimit: 1
activeDeadlineSeconds: 1800
template:
spec:
restartPolicy: Never
securityContext:
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
# Must run on the same node as Gitea to share the RWO volume
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app.kubernetes.io/name: gitea
topologyKey: kubernetes.io/hostname
initContainers:
- name: gitea-dump
image: gitea/gitea:1.25.4
command:
- sh
- -c
- |
gitea dump \
-c /data/gitea/conf/app.ini \
-f /backup/gitea-dump.zip \
-t /tmp/gitea-dump && \
echo "Dump completed: $(ls -lh /backup/gitea-dump.zip)"
volumeMounts:
- name: data
mountPath: /data
readOnly: true
- name: backup
mountPath: /backup
- name: tmp
mountPath: /tmp/gitea-dump
containers:
- name: upload
image: minio/mc:latest
env:
- name: HOME
value: /tmp
command:
- sh
- -c
- |
mc alias set s3 "${S3_ENDPOINT}" "${AWS_ACCESS_KEY_ID}" "${AWS_SECRET_ACCESS_KEY}"
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
KEY="gitea-dump-${TIMESTAMP}.zip"
echo "Uploading ${KEY}..."
mc cp /backup/gitea-dump.zip "s3/${S3_BUCKET}/${KEY}" && \
echo "Upload complete."
# Prune backups older than 7 days
echo "Pruning backups older than 7 days..."
mc rm --older-than 7d --force "s3/${S3_BUCKET}/" 2>&1 || true
echo "Pruning complete."
envFrom:
- secretRef:
name: gitea-backup-s3
volumeMounts:
- name: backup
mountPath: /backup
readOnly: true
volumes:
- name: data
persistentVolumeClaim:
claimName: gitea-shared-storage
- name: backup
emptyDir:
sizeLimit: 5Gi
- name: tmp
emptyDir:
sizeLimit: 5Gi
@@ -0,0 +1,13 @@
apiVersion: traefik.io/v1alpha1
kind: IngressRouteTCP
metadata:
name: gitea-ssh
namespace: gitea
spec:
entryPoints:
- giteassh
routes:
- match: HostSNI(`*`)
services:
- name: gitea-ssh
port: 22
+54
View File
@@ -0,0 +1,54 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kyverno:pods-replicasets:manage
labels:
rbac.kyverno.io/aggregate-to-cleanup-controller: "true"
rules:
- apiGroups:
- ''
- 'apps'
resources:
- replicasets
- pods
verbs:
- get
- list
- watch
- delete
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kyverno:secrets:view
labels:
rbac.kyverno.io/aggregate-to-admission-controller: "true"
rbac.kyverno.io/aggregate-to-reports-controller: "true"
rbac.kyverno.io/aggregate-to-background-controller: "true"
rules:
- apiGroups:
- ''
resources:
- secrets
- namespaces
verbs:
- get
- list
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kyverno:secrets:manage
labels:
rbac.kyverno.io/aggregate-to-background-controller: "true"
rules:
- apiGroups:
- ''
resources:
- secrets
- namespaces
verbs:
- create
- update
- delete
+35
View File
@@ -0,0 +1,35 @@
---
# Staging ClusterIssuer for testing (higher rate limits, not browser-trusted)
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
spec:
acme:
# Let's Encrypt staging server
server: https://acme-staging-v02.api.letsencrypt.org/directory
email: danijels@gmail.com
privateKeySecretRef:
name: letsencrypt-staging-key
solvers:
- http01:
ingress:
class: traefik
---
# Production ClusterIssuer for browser-trusted certificates
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
# Let's Encrypt production server
server: https://acme-v02.api.letsencrypt.org/directory
email: danijels@gmail.com
privateKeySecretRef:
name: letsencrypt-prod-key
solvers:
- http01:
ingress:
class: traefik
@@ -0,0 +1,20 @@
---
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
creationTimestamp: null
name: mcp10x-repo-creds
namespace: argocd
spec:
encryptedData:
sshPrivateKey: AgABjxZ9fCInZErXR2rkRfn/xg3foN/k8PZaU2xeaf6SraOIoAzsEOmCZjOhml2aOxezED9jAuCyAVcnJGjULlYiwGklmRzekqy3aUNMPsswQIBhs2kDkR0py0ANudNrv1gYkmNn0Z+nMuPIvMbjKkA0avoRD9aXbY7XFP6lJfoFURGYQ6mZeUsjbsugL3m0drync5Ff5IWoPm4cs+O58RXRIiUuMQ/BSEov9DBQfugB94Dg5xA2o1IO9MoXLiHVGfXTd6JD65SnGwhtftmucTXETZjGJbDwJnwcbmC5JqOnxP+wvb9sFUm8QNaGBkODB7ET2YOFnrbhL45L1HwXkLzvteyOpuStfihtOeyKl2D1PRxyy/uwlEg2GR+TZzegrrMlEU/wY6u1nqfkw8g+VPQy2r0KCCRDWha9bBReyFz2LzJr8quTp/HmKi5l0ljVTwziZ2EI6SFdtIGjnyAhEAYWZZoCn1cYQ9Y7qTSnnm6k1f6tnqCJljfr0ls63cXosWxPaSsyHjnmxQboUs+QgpLZDGo5UZLsYJpafPeKN5lQJgZpkK0el4JzLreA1TTLSp2bVW/3Y2R6auQlOhC79A+/ctEooQq6ugPdKaiKUjDpcl9J3pIEiMw0/m6cnFRgBFZdey0hia/joYruIKjL+P6MpwMEL5nKEjnV1hSQqDraC+H4fvQOuYIHYYOPTePxcFyznK/ctcZI9ByW1zT8tSNbKJLia2fhv1Fv15MX/qrk84stW3FG4W1M9PKbmYX8gksF1PxWh+FWfOFteTU+bZPXUOvU5onEFET1L8ZaN7z8v2cYh/D7kRHVcTrLrxgvugvRnGFIsx2Wy0d48LApfDNmip4q4AjA+yhZgRR+eziyStEzFfsvU/MDK9qeQoK+cmV3RMcKUOYthjDbCzndH6TFlqcQQGEWvcbLqofpFjXz0uw9pY7Z8YRBemD6wqAM13JtaI+hF6EW3fW6Vy3QS0O1Kqgy/8bCh4R3h+DGtXPkMu/xLKuFiUQJF2XnQEZya+aYbxQUcNcxOvblWndHOMFpbce0ERIon9m4rvn8HLNeoRqC+x4iGW7ft4pFkaLr/DYOkhiNmSfd35js8TLfcxSXZg2pX+dq6lejGxVdkrvmisWm+4xpc0B8hRpwQMJGuIM4rQz5wj/XndfHSH1Z0NnorCmSubOwPIpq7VQqoyCIpOBCzBLVki4hlJeqIvm2/xJPPVzxZZ16Uy7TGbSoPWs=
type: AgC9y+ZjBL2JsaUBFhWc4wlZWnp04EzxyXwJJgwu+FyBTGWGBrA5dp7KeS7LuPW+vBcjJKcLVuYrDbxJw622RgD0m8ALEL+TQg+CnULXljb7P1inSlAVKHBg0le2bz6dZ55SmZvAItrm5MSxcwVZYFeBVjHFP5IDwF2uPv9ZQOrIGA58ZjTK9+kTsVN/XbVCnNnTaAakW6PR7YaLvpiYYfMbGlU+JmItwIJASPnqmQV40+5f+ewgCl5w0ATeNi6VOQx6quQm7HJovneE0pfYRyg/fTc3SNI6Ao/82+QP3H/7Kmme1DLncMfKSmTZ1dcLQ7AaUZFXuwaQzwzLwv1RLsyFowweJJh20TGV66526oM9zzPAAuFD+yBQln+qdn+qJnOpUZU9Ft/bbnaX2JuBHfcpXK93CvlATo9p+d2RdWvscUSN5NcQ+/szkIJmcCwPW4W7wLvst/+oy2mqJIoRY2T8VT5QclPe2Mbz0onriXx50zeGGAi2MWzNUdR60S8sfadn/6J0+3GdQnQwrgvgV1W2yuXQW6+ThzEqZZlQLZz9+LUQBTYf7DAObGw1EJE1ZdldoyiurMrrlCf88xA9grv9y1QiN0TIElTy5z10Jke8cB9yXBYMA4D/XaEAJ5juk44XjzlmOqPyyFny0xEd6LFILETr76ph1lI6TJUrE5dA9MOwRMQWwSfcMyqRob1nSwx9tBA=
url: AgCZPKVLwBsR41TulTWsw5gSnAFBCH5pQj8hoty2LlGcgM2cY+ArDCv46B8ihFdLiGY4r9hRAhlzkeC1mjgTI9GDzfmrTVs5xS4ilKG9HTt8SzleyqlYT8jZAopc1ln3j4pMLZj471th0PBRxajIxT4rv+tm02FlS+1Py+sHTochMakXLBSQxAy0fGr+Y98WuG6GYxcrHOD4yqErdmq06N9xrmGjP0KCAxTS4VJLiVvWbikANwtDFCmB63wiaqQ0uky7aeX/UrmCUi4WhuFfwUipSr6nyn2Ws3TdTOjioeRNA/LtDb6zc0k1WqgWU2Kk0YHoIJF7w4POSurNQu4yrPgeaK8Ez8k+cFQihK+/4YHZPOUS5Dzm3XhXuQOgQRMfeIFPsutYAMk7WQB8bPDjlk2CpLIg+vQicrW6JEjAgIbD4ohUNKznP2h6vTu6fcGKleDMEedp73/Pud1EinOxyOA91uYv+k54F/tndE6Jj/RJnMTBVBuw71789oBF/QZJ3glhjq/Q78v8t5Zq0QFlpuc4oXOn6WAuP79kUBiBbOVDfSaBMtztsZihf9En3RRzC5RRncOhYaLOufkPTY+qC2Myj6+T/SdxZnyohEZSzHyqSMsBOLCcWTcap79kP3ARRH8az+/7Nga95TnIEoG6f5Wt12f9ZglZtM/UJvQv0NxhSF6YY4gk8sI0Mv5A9ihnUKP7i0gxCnf+X+UJACt+Iy6MDdxFxCHJW7Gp79wrIPmOWnhRJQ==
template:
metadata:
creationTimestamp: null
labels:
argocd.argoproj.io/secret-type: repository
name: mcp10x-repo-creds
namespace: argocd
type: Opaque
@@ -0,0 +1,37 @@
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: deny-external-egress
namespace: trivy-system
labels:
app.kubernetes.io/managed-by: argocd
app.kubernetes.io/part-of: network-policies
spec:
endpointSelector: {}
egress:
# Allow DNS resolution
- toEndpoints:
- matchLabels:
io.kubernetes.pod.namespace: kube-system
k8s-app: kube-dns
toPorts:
- ports:
- port: "53"
protocol: UDP
- port: "53"
protocol: TCP
# Allow cluster-internal traffic (RFC1918)
- toCIDR:
- 10.0.0.0/8
- 172.16.0.0/12
- 192.168.0.0/16
# Allow Trivy vulnerability DB downloads (ghcr.io OCI registry)
- toFQDNs:
- matchName: ghcr.io
- matchName: pkg-containers.githubusercontent.com
toPorts:
- ports:
- port: "443"
protocol: TCP
@@ -0,0 +1,492 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: inject-auth-sidecar
annotations:
pod-policies.kyverno.io/autogen-controllers: none
policies.kyverno.io/title: Inject Auth Sidecar
policies.kyverno.io/minversion: 1.6.0
policies.kyverno.io/category: Security
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Pod
policies.kyverno.io/description: >-
Injects an auth sidecar container into Pods annotated with policies.forteapps.io/auth: "true". Supports three auth modes controlled by the policies.forteapps.io/auth-type annotation: "token" (default), "oidc", and "mcp". In token mode the sidecar reads credentials from a mounted Secret volume. In OIDC mode the sidecar uses OpenID Connect with authority and client-id provided via required annotations (policies.forteapps.io/auth-oidc-authority and policies.forteapps.io/auth-oidc-client-id) and secrets from an auth-oidc Secret. In MCP mode the sidecar implements OAuth 2.0 for MCP servers per RFC 9728 (Protected Resource Metadata) and RFC 7591 (Dynamic Client Registration), configured via policies.forteapps.io/auth-mcp-resource and policies.forteapps.io/auth-mcp-authority annotations. The sidecar port defaults to 9001 and can be overridden via the policies.forteapps.io/auth-port annotation. A NetworkPolicy is generated to restrict ingress to the sidecar port only.
spec:
background: false
rules:
- name: generate-auth-tokens-secret
skipBackgroundRequests: true
match:
any:
- resources:
kinds:
- Pod
annotations:
policies.forteapps.io/auth: "true"
exclude:
any:
- resources:
namespaces:
- kube-system
- kyverno
- argocd
- cert-manager
- monitoring
preconditions:
all:
- key: "{{ request.operation }}"
operator: In
value:
- CREATE
- key: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-type\" || 'token' }}"
operator: Equals
value: "token"
generate:
synchronize: false
apiVersion: v1
kind: Secret
name: auth-tokens
namespace: "{{ request.namespace }}"
data:
metadata:
labels:
app.kubernetes.io/managed-by: kyverno
app.kubernetes.io/created-by: inject-auth-sidecar
type: Opaque
data: {}
- name: generate-auth-oidc-secret
skipBackgroundRequests: true
match:
any:
- resources:
kinds:
- Pod
annotations:
policies.forteapps.io/auth: "true"
policies.forteapps.io/auth-type: "oidc"
exclude:
any:
- resources:
namespaces:
- kube-system
- kyverno
- argocd
- cert-manager
- monitoring
preconditions:
all:
- key: "{{ request.operation }}"
operator: In
value:
- CREATE
generate:
synchronize: false
apiVersion: v1
kind: Secret
name: auth-oidc
namespace: "{{ request.namespace }}"
data:
metadata:
labels:
app.kubernetes.io/managed-by: kyverno
app.kubernetes.io/created-by: inject-auth-sidecar
type: Opaque
data: {}
- name: inject-sidecar-token
skipBackgroundRequests: true
match:
any:
- resources:
kinds:
- Pod
annotations:
policies.forteapps.io/auth: "true"
exclude:
any:
- resources:
namespaces:
- kube-system
- kyverno
- argocd
- cert-manager
- monitoring
preconditions:
all:
- key: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-type\" || 'token' }}"
operator: Equals
value: "token"
context:
- name: appPort
variable:
jmesPath: request.object.spec.containers[?name != 'authn'] | [0].ports[0].containerPort || `3000`
- name: sidecarPort
variable:
jmesPath: to_number(request.object.metadata.annotations."policies.forteapps.io/auth-port" || '9001')
mutate:
patchStrategicMerge:
spec:
containers:
- name: authn
image: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-image\" || 'git.forteapps.net/forte/auth-sidecar' }}:{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-image-version\" || 'latest' }}"
ports:
- containerPort: "{{ sidecarPort }}"
name: auth
protocol: TCP
env:
- name: AUTH_LISTEN_ADDR
value: ":{{ sidecarPort }}"
- name: AUTH_UPSTREAM_URL
value: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-upstream-url\" || join('', ['http://localhost:', to_string(appPort)]) }}"
- name: AUTH_PUBLIC_PATHS
value: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-public-paths\" || '/healthz' }}"
- name: AUTH_TOKEN_FILE
value: "/etc/auth/tokens"
- name: AUTH_MODE
value: "token"
volumeMounts:
- name: auth-tokens
mountPath: /etc/auth
readOnly: true
resources:
limits:
cpu: 50m
memory: 64Mi
requests:
cpu: 10m
memory: 32Mi
readinessProbe:
httpGet:
path: /healthz
port: "{{ sidecarPort }}"
initialDelaySeconds: 2
periodSeconds: 5
livenessProbe:
httpGet:
path: /healthz
port: "{{ sidecarPort }}"
initialDelaySeconds: 5
periodSeconds: 10
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
volumes:
- name: auth-tokens
secret:
secretName: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-token-secret-name\" || 'auth-tokens' }}"
optional: true
- name: inject-sidecar-oidc
skipBackgroundRequests: true
match:
any:
- resources:
kinds:
- Pod
annotations:
policies.forteapps.io/auth: "true"
policies.forteapps.io/auth-type: "oidc"
exclude:
any:
- resources:
namespaces:
- kube-system
- kyverno
- argocd
- cert-manager
- monitoring
context:
- name: appPort
variable:
jmesPath: request.object.spec.containers[?name != 'authn'] | [0].ports[0].containerPort || `3000`
- name: sidecarPort
variable:
jmesPath: to_number(request.object.metadata.annotations."policies.forteapps.io/auth-port" || '9001')
mutate:
patchStrategicMerge:
spec:
containers:
- name: authn
image: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-image\" || 'git.forteapps.net/forte/auth-sidecar' }}:{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-image-version\" || 'latest' }}"
imagePullPolicy: Always
ports:
- containerPort: "{{ sidecarPort }}"
name: auth
protocol: TCP
env:
- name: AUTH_MODE
value: "oidc"
- name: AUTH_LISTEN_ADDR
value: ":{{ sidecarPort }}"
- name: AUTH_LOG_LEVEL
value: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-log-level\" || 'info' }}"
- name: AUTH_UPSTREAM_URL
value: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-upstream-url\" || join('', ['http://localhost:', to_string(appPort)]) }}"
- name: AUTH_OIDC_AUTHORITY
value: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-oidc-authority\" }}"
- name: AUTH_OIDC_CLIENT_ID
value: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-oidc-client-id\" }}"
- name: AUTH_OIDC_CALLBACK_URL
value: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-oidc-callback-path\" }}"
- name: AUTH_OIDC_CALLBACK_PATH
value: "{{ regex_replace_all('https?://[^/]*', request.object.metadata.annotations.\"policies.forteapps.io/auth-oidc-callback-path\", '') }}"
- name: AUTH_OIDC_SCOPES
value: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-oidc-scopes\" || 'openid,profile,email' }}"
- name: AUTH_PUBLIC_PATHS
value: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-public-paths\" || '/healthz' }}"
- name: AUTH_OIDC_COOKIE_SECRET
valueFrom:
secretKeyRef:
name: auth-oidc
key: cookie-secret
- name: AUTH_OIDC_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-oidc-credentials-secret\" || 'auth-oidc' }}"
key: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-oidc-credentials-secret-key\" || 'client-secret' }}"
resources:
limits:
cpu: 50m
memory: 64Mi
requests:
cpu: 10m
memory: 32Mi
readinessProbe:
httpGet:
path: /healthz
port: "{{ sidecarPort }}"
initialDelaySeconds: 2
periodSeconds: 5
livenessProbe:
httpGet:
path: /healthz
port: "{{ sidecarPort }}"
initialDelaySeconds: 5
periodSeconds: 10
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
- name: inject-sidecar-mcp
skipBackgroundRequests: true
match:
any:
- resources:
kinds:
- Pod
annotations:
policies.forteapps.io/auth: "true"
policies.forteapps.io/auth-type: "mcp"
exclude:
any:
- resources:
namespaces:
- kube-system
- kyverno
- argocd
- cert-manager
- monitoring
context:
- name: appPort
variable:
jmesPath: request.object.spec.containers[?name != 'authn'] | [0].ports[0].containerPort || `3000`
- name: sidecarPort
variable:
jmesPath: to_number(request.object.metadata.annotations."policies.forteapps.io/auth-port" || '9001')
mutate:
patchStrategicMerge:
spec:
containers:
- name: authn
image: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-image\" || 'git.forteapps.net/forte/auth-sidecar' }}:{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-image-version\" || 'latest' }}"
imagePullPolicy: Always
ports:
- containerPort: "{{ sidecarPort }}"
name: auth
protocol: TCP
env:
- name: AUTH_MODE
value: "mcp"
- name: AUTH_LISTEN_ADDR
value: ":{{ sidecarPort }}"
- name: AUTH_LOG_LEVEL
value: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-log-level\" || 'info' }}"
- name: AUTH_UPSTREAM_URL
value: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-upstream-url\" || join('', ['http://localhost:', to_string(appPort)]) }}"
- name: AUTH_MCP_RESOURCE
value: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-mcp-resource\" }}"
- name: AUTH_MCP_AUTHORIZATION_SERVERS
value: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-mcp-authority\" }}"
- name: AUTH_PUBLIC_PATHS
value: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-public-paths\" || '/healthz' }}"
- name: AUTH_MCP_SCOPES_SUPPORTED
value: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-mcp-scopes\" || 'profile' }}"
resources:
limits:
cpu: 50m
memory: 64Mi
requests:
cpu: 10m
memory: 32Mi
readinessProbe:
httpGet:
path: /healthz
port: "{{ sidecarPort }}"
initialDelaySeconds: 2
periodSeconds: 5
livenessProbe:
httpGet:
path: /healthz
port: "{{ sidecarPort }}"
initialDelaySeconds: 5
periodSeconds: 10
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
- name: inject-sidecar-oauth
skipBackgroundRequests: true
match:
any:
- resources:
kinds:
- Pod
annotations:
policies.forteapps.io/auth: "true"
policies.forteapps.io/auth-type: "oauth"
exclude:
any:
- resources:
namespaces:
- kube-system
- kyverno
- argocd
- cert-manager
- monitoring
context:
- name: appPort
variable:
jmesPath: request.object.spec.containers[?name != 'authn'] | [0].ports[0].containerPort || `3000`
- name: sidecarPort
variable:
jmesPath: to_number(request.object.metadata.annotations."policies.forteapps.io/auth-port" || '9001')
mutate:
patchStrategicMerge:
spec:
containers:
- name: authn
image: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-image\" || 'git.forteapps.net/forte/auth-sidecar' }}:{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-image-version\" || 'latest' }}"
imagePullPolicy: Always
ports:
- containerPort: "{{ sidecarPort }}"
name: auth
protocol: TCP
env:
- name: AUTH_MODE
value: "oauth"
- name: AUTH_LISTEN_ADDR
value: ":{{ sidecarPort }}"
- name: AUTH_LOG_LEVEL
value: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-log-level\" || 'info' }}"
- name: AUTH_UPSTREAM_URL
value: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-upstream-url\" || join('', ['http://localhost:', to_string(appPort)]) }}"
- name: AUTH_OAUTH_AUTHORITY
value: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-oauth-authority\" }}"
- name: AUTH_OAUTH_CLIENT_ID
value: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-oauth-client-id\" }}"
- name: AUTH_OAUTH_SCOPES
value: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-oauth-scopes\" || 'openid,profile,email' }}"
- name: AUTH_OAUTH_DELEGATION_ENABLED
value: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-oauth-delegation-enabled\" || 'false' }}"
- name: AUTH_OAUTH_DELEGATION_CLIENT_ID
value: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-oauth-delegation-client-id\" || '' }}"
- name: AUTH_OAUTH_DELEGATION_SCOPES
value: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-oauth-delegation-scopes\" || '' }}"
- name: AUTH_OAUTH_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-oauth-credentials-secret\" || 'auth-oauth' }}"
key: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-oauth-credentials-secret-key\" || 'client-secret' }}"
- name: AUTH_OAUTH_DELEGATION_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: auth-oauth
key: delegation-client-secret
resources:
limits:
cpu: 50m
memory: 64Mi
requests:
cpu: 10m
memory: 32Mi
readinessProbe:
httpGet:
path: /healthz
port: "{{ sidecarPort }}"
initialDelaySeconds: 2
periodSeconds: 5
livenessProbe:
httpGet:
path: /healthz
port: "{{ sidecarPort }}"
initialDelaySeconds: 5
periodSeconds: 10
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
- name: generate-auth-network-policy
skipBackgroundRequests: true
match:
any:
- resources:
kinds:
- Pod
annotations:
policies.forteapps.io/auth: "true"
exclude:
any:
- resources:
namespaces:
- kube-system
- kyverno
- argocd
- cert-manager
- monitoring
preconditions:
all:
- key: "{{ request.operation }}"
operator: In
value:
- CREATE
context:
- name: sidecarPort
variable:
jmesPath: to_number(request.object.metadata.annotations."policies.forteapps.io/auth-port" || '9001')
generate:
synchronize: false
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
name: "{{ request.object.metadata.name }}-auth-ingress"
namespace: "{{ request.namespace }}"
data:
metadata:
labels:
app.kubernetes.io/managed-by: kyverno
app.kubernetes.io/created-by: inject-auth-sidecar
spec:
podSelector:
matchLabels: "{{ request.object.metadata.labels }}"
policyTypes:
- Ingress
ingress:
- ports:
- port: "{{ sidecarPort }}"
protocol: TCP
@@ -0,0 +1,26 @@
apiVersion: kyverno.io/v2
kind: ClusterCleanupPolicy
metadata:
name: clean-bare-pods
annotations:
policies.kyverno.io/title: Cleanup Bare Pods
policies.kyverno.io/category: Other
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Pod
kyverno.io/kyverno-version: 1.11.1
policies.kyverno.io/minversion: 1.10.0
pod-policies.kyverno.io/autogen-controllers: none
kyverno.io/kubernetes-version: "1.27"
policies.kyverno.io/description: A bare Pod is any Pod created directly and not owned by a controller such as a Deployment or Job. Bare Pods are often create manually by users in an attempt to troubleshoot an issue. If left in the cluster, they create clutter, increase cost, and can be a security risk. Bare Pods can be cleaned up periodically through use of a policy. This policy finds and removes all bare Pods across the cluster.
spec:
match:
any:
- resources:
kinds:
- Pod
conditions:
all:
- key: "{{ target.metadata.ownerReferences[] || `[]` }}"
operator: Equals
value: []
schedule: "*/5 * * * *"
@@ -0,0 +1,45 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: disallow-default-namespace
annotations:
pod-policies.kyverno.io/autogen-controllers: none
policies.kyverno.io/title: Disallow Default Namespace
policies.kyverno.io/minversion: 1.6.0
policies.kyverno.io/category: Multi-Tenancy
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Pod
policies.kyverno.io/description: Kubernetes Namespaces are an optional feature that provide a way to segment and isolate cluster resources across multiple applications and users. As a best practice, workloads should be isolated with Namespaces. Namespaces should be required and the default (empty) Namespace should not be used. This policy validates that Pods specify a Namespace name other than `default`. Rule auto-generation is disabled here due to Pod controllers need to specify the `namespace` field under the top-level `metadata` object and not at the Pod template level.
spec:
validationFailureAction: Enforce
background: true
rules:
- name: enforce-namespace
skipBackgroundRequests: true
match:
any:
- resources:
kinds:
- Pod
validate:
allowExistingViolations: false
message: Using 'default' namespace is not allowed.
pattern:
metadata:
namespace: "!default"
- name: enforce-podcontroller-namespace
skipBackgroundRequests: true
match:
any:
- resources:
kinds:
- DaemonSet
- Deployment
- Job
- StatefulSet
validate:
allowExistingViolations: false
message: Using 'default' namespace is not allowed for pod controllers.
pattern:
metadata:
namespace: "!default"
@@ -0,0 +1,37 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: keycloak-client-config-cloner
spec:
rules:
- name: clone-client-config-to-keycloak
skipBackgroundRequests: false
match:
any:
- resources:
kinds:
- Secret
selector:
matchLabels:
keycloak.forteapps.net/client-config: "true"
exclude:
any:
- resources:
namespaces:
- keycloak
generate:
apiVersion: v1
kind: Secret
name: "{{request.object.metadata.name}}"
namespace: keycloak
synchronize: true
data:
metadata:
labels:
keycloak.forteapps.net/client-config: "true"
keycloak.forteapps.net/source-namespace: "{{request.object.metadata.namespace}}"
annotations:
keycloak.forteapps.net/source-name: "{{request.object.metadata.name}}"
keycloak.forteapps.net/source-namespace: "{{request.object.metadata.namespace}}"
data: "{{request.object.data}}"
type: "{{request.object.type}}"
@@ -0,0 +1,41 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-labels
annotations:
policies.kyverno.io/title: Require Labels
policies.kyverno.io/category: Best Practices
policies.kyverno.io/minversion: 1.6.0
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Pod, Label
policies.kyverno.io/description: Define and use labels that identify semantic attributes of your application or Deployment. A common set of labels allows tools to work collaboratively, describing objects in a common manner that all tools can understand. The recommended labels describe applications in a way that can be queried. This policy validates that the label `app.kubernetes.io/name` is specified with some value.
spec:
validationFailureAction: Audit
background: true
rules:
- name: check-for-labels
skipBackgroundRequests: true
exclude:
any:
- resources:
namespaces:
- kube-system
- istio-system
- argocd
- cert-manager
- monitoring
- secrets
- kyverno
- trivy-system
match:
any:
- resources:
kinds:
- Pod
validate:
message: The label `app.kubernetes.io/name` is required.
allowExistingViolations: true
pattern:
metadata:
labels:
app.kubernetes.io/name: "?*"
@@ -0,0 +1,33 @@
apiVersion: kyverno.io/v2
kind: ClusterCleanupPolicy
metadata:
name: cleanup-empty-replicasets
annotations:
policies.kyverno.io/title: Cleanup Empty ReplicaSets
policies.kyverno.io/category: Other
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: ReplicaSet
kyverno.io/kyverno-version: 1.11.1
policies.kyverno.io/minversion: 1.9.0
kyverno.io/kubernetes-version: "1.27"
policies.kyverno.io/description: ReplicaSets serve as an intermediate controller for various Pod controllers like Deployments. When a new version of a Deployment is initiated, it generates a new ReplicaSet with the specified number of replicas and scales down the current one to zero. Consequently, numerous empty ReplicaSets may accumulate in the cluster, leading to clutter and potential false positives in policy reports if enabled. This cleanup policy is designed to remove empty ReplicaSets across the cluster within a specified timeframe, for instance, ReplicaSets created 7 days ago, ensuring the ability to rollback to previous ReplicaSets in case of deployment issues
spec:
match:
any:
- resources:
kinds:
- ReplicaSet
exclude:
any:
- resources:
namespaces:
- kube-system
conditions:
all:
- key: "{{ target.spec.replicas }}"
operator: Equals
value: 0
- key: "{{ time_diff('{{target.metadata.creationTimestamp}}','{{ time_now_utc() }}') }}"
operator: GreaterThan
value: 0h0m30s
schedule: "*/7 * * * *"
@@ -0,0 +1,38 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: sync-secret-with-multi-clone
spec:
rules:
- name: sync-secrets
skipBackgroundRequests: true
match:
any:
- resources:
kinds:
- Namespace
exclude:
any:
- resources:
namespaces:
- kube-system
- trivy-system
- monitoring
- argocd
- cert-manager
- kyverno
- default
- cilium-secrets
- kube-public
- kyverno
generate:
generateExisting: false
namespace: "{{request.object.metadata.name}}"
synchronize: true
cloneList:
namespace: secrets
kinds:
- v1/Secret
selector:
matchLabels:
allowedToBeCloned: "true"
+7
View File
@@ -0,0 +1,7 @@
---
# Disable Istio sidecar injection for cert-manager namespace
# This is required for cert-manager to function properly with Istio
apiVersion: v1
kind: Namespace
metadata:
name: secrets
+12
View File
@@ -0,0 +1,12 @@
# Cluster config reference — values must match the corresponding overlay files.
# Read by bootstrap.sh at install time; NOT auto-propagated to ArgoCD value files.
clusterName: dev-aks # → infra/values/aks-dev/argocd-values.yaml (notifications.context.clusterName)
domain: example.com # → infra/values/base/gitea-values.yaml, renovate-values.yaml, keycloak-values.yaml (subdomains)
argocdDomain: argocd.example.com # → infra/values/aks-dev/argocd-values.yaml (global.domain)
grafanaDomain: grafana.example.com # → infra/values/aks-dev/grafana-values.yaml (ingress.hosts)
keycloakDomain: id.example.com # → infra/values/aks-dev/keycloak-values.yaml (ingress.hostname)
dotaiDomain: kubemcp.example.com # → infra/values/aks-dev/dot-ai-stack-values.yaml (dot-ai.ingress.host) — create if needed
dotaiUiDomain: kubemcpui.example.com # → infra/values/aks-dev/dot-ai-stack-values.yaml (dot-ai-ui.ingress.host) — create if needed
letsencryptEmail: admin@example.com # → cluster-resources/letsencrypt-issuer.yaml (spec.acme.email)
trustedIPs: "10.0.0.0/8,168.63.129.16/32" # → infra/values/aks-dev/traefik-values.yaml (ports.*.trustedIPs) — VNet CIDR + Azure health probe
cloudProvider: azure # → determines overlay directory and cloud-specific LB/storage annotations
+12
View File
@@ -0,0 +1,12 @@
# Cluster config reference — values must match the corresponding overlay files.
# Read by bootstrap.sh at install time; NOT auto-propagated to ArgoCD value files.
clusterName: prod-aks # → infra/values/aks-prod/argocd-values.yaml (notifications.context.clusterName)
domain: example.com # → infra/values/base/gitea-values.yaml, renovate-values.yaml, keycloak-values.yaml (subdomains)
argocdDomain: argocd.example.com # → infra/values/aks-prod/argocd-values.yaml (global.domain)
grafanaDomain: grafana.example.com # → infra/values/aks-prod/grafana-values.yaml (ingress.hosts)
keycloakDomain: id.example.com # → infra/values/aks-prod/keycloak-values.yaml (ingress.hostname)
dotaiDomain: kubemcp.example.com # → infra/values/aks-prod/dot-ai-stack-values.yaml (dot-ai.ingress.host) — create if needed
dotaiUiDomain: kubemcpui.example.com # → infra/values/aks-prod/dot-ai-stack-values.yaml (dot-ai-ui.ingress.host) — create if needed
letsencryptEmail: admin@example.com # → cluster-resources/letsencrypt-issuer.yaml (spec.acme.email)
trustedIPs: "10.0.0.0/8,168.63.129.16/32" # → infra/values/aks-prod/traefik-values.yaml (ports.*.trustedIPs) — VNet CIDR + Azure health probe
cloudProvider: azure # → determines overlay directory and cloud-specific LB/storage annotations
+12
View File
@@ -0,0 +1,12 @@
# Cluster config reference — values must match the corresponding overlay files.
# Read by bootstrap.sh at install time; NOT auto-propagated to ArgoCD value files.
clusterName: dev-eks # → infra/values/eks-dev/argocd-values.yaml (notifications.context.clusterName)
domain: example.com # → infra/values/base/gitea-values.yaml, renovate-values.yaml, keycloak-values.yaml (subdomains)
argocdDomain: argocd.example.com # → infra/values/eks-dev/argocd-values.yaml (global.domain)
grafanaDomain: grafana.example.com # → infra/values/eks-dev/grafana-values.yaml (ingress.hosts)
keycloakDomain: id.example.com # → infra/values/eks-dev/keycloak-values.yaml (ingress.hostname)
dotaiDomain: kubemcp.example.com # → infra/values/eks-dev/dot-ai-stack-values.yaml (dot-ai.ingress.host) — create if needed
dotaiUiDomain: kubemcpui.example.com # → infra/values/eks-dev/dot-ai-stack-values.yaml (dot-ai-ui.ingress.host) — create if needed
letsencryptEmail: admin@example.com # → cluster-resources/letsencrypt-issuer.yaml (spec.acme.email)
trustedIPs: "10.0.0.0/8" # → infra/values/eks-dev/traefik-values.yaml (ports.*.trustedIPs) — VPC CIDR
cloudProvider: eks # → determines overlay directory and cloud-specific LB/storage annotations
+12
View File
@@ -0,0 +1,12 @@
# Cluster config reference — values must match the corresponding overlay files.
# Read by bootstrap.sh at install time; NOT auto-propagated to ArgoCD value files.
clusterName: prod-eks # → infra/values/eks-prod/argocd-values.yaml (notifications.context.clusterName)
domain: example.com # → infra/values/base/gitea-values.yaml, renovate-values.yaml, keycloak-values.yaml (subdomains)
argocdDomain: argocd.example.com # → infra/values/eks-prod/argocd-values.yaml (global.domain)
grafanaDomain: grafana.example.com # → infra/values/eks-prod/grafana-values.yaml (ingress.hosts)
keycloakDomain: id.example.com # → infra/values/eks-prod/keycloak-values.yaml (ingress.hostname)
dotaiDomain: kubemcp.example.com # → infra/values/eks-prod/dot-ai-stack-values.yaml (dot-ai.ingress.host) — create if needed
dotaiUiDomain: kubemcpui.example.com # → infra/values/eks-prod/dot-ai-stack-values.yaml (dot-ai-ui.ingress.host) — create if needed
letsencryptEmail: admin@example.com # → cluster-resources/letsencrypt-issuer.yaml (spec.acme.email)
trustedIPs: "10.0.0.0/8" # → infra/values/eks-prod/traefik-values.yaml (ports.*.trustedIPs) — VPC CIDR
cloudProvider: eks # → determines overlay directory and cloud-specific LB/storage annotations
+12
View File
@@ -0,0 +1,12 @@
# Cluster config reference — values must match the corresponding overlay files.
# Read by bootstrap.sh at install time; NOT auto-propagated to ArgoCD value files.
clusterName: dev-gke # → infra/values/gke-dev/argocd-values.yaml (notifications.context.clusterName)
domain: example.com # → infra/values/base/gitea-values.yaml, renovate-values.yaml, keycloak-values.yaml (subdomains)
argocdDomain: argocd.example.com # → infra/values/gke-dev/argocd-values.yaml (global.domain)
grafanaDomain: grafana.example.com # → infra/values/gke-dev/grafana-values.yaml (ingress.hosts)
keycloakDomain: id.example.com # → infra/values/gke-dev/keycloak-values.yaml (ingress.hostname)
dotaiDomain: kubemcp.example.com # → infra/values/gke-dev/dot-ai-stack-values.yaml (dot-ai.ingress.host) — create if needed
dotaiUiDomain: kubemcpui.example.com # → infra/values/gke-dev/dot-ai-stack-values.yaml (dot-ai-ui.ingress.host) — create if needed
letsencryptEmail: admin@example.com # → cluster-resources/letsencrypt-issuer.yaml (spec.acme.email)
trustedIPs: "10.0.0.0/8,35.191.0.0/16,130.211.0.0/22" # → infra/values/gke-dev/traefik-values.yaml (ports.*.trustedIPs) — subnet + GCP health checks
cloudProvider: gke # → determines overlay directory and cloud-specific LB/storage annotations
+12
View File
@@ -0,0 +1,12 @@
# Cluster config reference — values must match the corresponding overlay files.
# Read by bootstrap.sh at install time; NOT auto-propagated to ArgoCD value files.
clusterName: prod-gke # → infra/values/gke-prod/argocd-values.yaml (notifications.context.clusterName)
domain: example.com # → infra/values/base/gitea-values.yaml, renovate-values.yaml, keycloak-values.yaml (subdomains)
argocdDomain: argocd.example.com # → infra/values/gke-prod/argocd-values.yaml (global.domain)
grafanaDomain: grafana.example.com # → infra/values/gke-prod/grafana-values.yaml (ingress.hosts)
keycloakDomain: id.example.com # → infra/values/gke-prod/keycloak-values.yaml (ingress.hostname)
dotaiDomain: kubemcp.example.com # → infra/values/gke-prod/dot-ai-stack-values.yaml (dot-ai.ingress.host) — create if needed
dotaiUiDomain: kubemcpui.example.com # → infra/values/gke-prod/dot-ai-stack-values.yaml (dot-ai-ui.ingress.host) — create if needed
letsencryptEmail: admin@example.com # → cluster-resources/letsencrypt-issuer.yaml (spec.acme.email)
trustedIPs: "10.0.0.0/8,35.191.0.0/16,130.211.0.0/22" # → infra/values/gke-prod/traefik-values.yaml (ports.*.trustedIPs) — subnet + GCP health checks
cloudProvider: gke # → determines overlay directory and cloud-specific LB/storage annotations
+12
View File
@@ -0,0 +1,12 @@
# Cluster config reference — values must match the corresponding overlay files.
# Read by bootstrap.sh at install time; NOT auto-propagated to ArgoCD value files.
clusterName: dev-fd-no-svg1 # → infra/values/upc-dev/argocd-values.yaml (notifications.context.clusterName)
domain: forteapps.net # → infra/values/base/gitea-values.yaml, renovate-values.yaml, keycloak-values.yaml (subdomains)
argocdDomain: argocd.127.0.0.1.nip.io # → infra/values/upc-dev/argocd-values.yaml (global.domain)
grafanaDomain: grafana.forteapps.net # → infra/values/upc-dev/grafana-values.yaml (ingress.hosts)
keycloakDomain: id.forteapps.net # → infra/values/upc-dev/keycloak-values.yaml (ingress.hostname)
dotaiDomain: kubemcp.forteapps.net # → infra/values/upc-dev/dot-ai-stack-values.yaml (dot-ai.ingress.host)
dotaiUiDomain: kubemcpui.forteapps.net # → infra/values/upc-dev/dot-ai-stack-values.yaml (dot-ai-ui.ingress.host)
letsencryptEmail: danijels@gmail.com # → cluster-resources/letsencrypt-issuer.yaml (spec.acme.email)
trustedIPs: "172.16.1.0/24" # → infra/values/upc-dev/traefik-values.yaml (ports.*.trustedIPs)
cloudProvider: upcloud # → determines overlay directory and cloud-specific LB/storage annotations
+12
View File
@@ -0,0 +1,12 @@
# Cluster config reference — values must match the corresponding overlay files.
# Read by bootstrap.sh at install time; NOT auto-propagated to ArgoCD value files.
clusterName: prod-fd-no-svg1 # → infra/values/upc-prod/argocd-values.yaml (notifications.context.clusterName)
domain: fortedigital.com # → infra/values/base/gitea-values.yaml, renovate-values.yaml, keycloak-values.yaml (subdomains)
argocdDomain: argocd.127.0.0.1.nip.io # → infra/values/upc-prod/argocd-values.yaml (global.domain)
grafanaDomain: grafana.fortedigital.com # → infra/values/upc-prod/grafana-values.yaml (ingress.hosts)
keycloakDomain: id.fortedigital.com # → infra/values/upc-prod/keycloak-values.yaml (ingress.hostname)
dotaiDomain: kubemcp.fortedigital.com # → infra/values/upc-prod/dot-ai-stack-values.yaml (dot-ai.ingress.host)
dotaiUiDomain: kubemcpui.fortedigital.com # → infra/values/upc-prod/dot-ai-stack-values.yaml (dot-ai-ui.ingress.host)
letsencryptEmail: danijel.simeunovic@fortedigital.com # → cluster-resources/letsencrypt-issuer.yaml (spec.acme.email)
trustedIPs: "172.16.1.0/24" # → infra/values/upc-prod/traefik-values.yaml (ports.*.trustedIPs)
cloudProvider: upcloud # → determines overlay directory and cloud-specific LB/storage annotations
File diff suppressed because it is too large Load Diff
+668
View File
@@ -0,0 +1,668 @@
# GitOps Architecture & Repository Guide
## Table of Contents
- [Overview](#overview)
- [Architecture Diagram](#architecture-diagram)
- [Repository Structure](#repository-structure)
- [GitOps Workflow](#gitops-workflow)
- [CI/CD Pipeline](#cicd-pipeline)
- [Security Model](#security-model)
---
## Overview
This Kubernetes cluster uses a **GitOps approach** powered by **ArgoCD**, where Git repositories serve as the single source of truth for both infrastructure and application deployments. The cluster setup is **cloud-agnostic**, with ready-to-use configurations for **UpCloud**, **AWS EKS**, **Azure AKS**, and **GCP GKE**.
### Key Characteristics
- **Environment**: Production (internal use only)
- **Cluster Type**: Multi-cloud, multi-cluster via Kustomize overlays (UpCloud, AWS, Azure, GCP)
- **GitOps Tool**: ArgoCD
- **Deployment Pattern**: App-of-Apps
- **Secret Management**: Sealed Secrets (kubeseal)
- **Ingress**: Traefik with Let's Encrypt TLS
- **Monitoring**: Prometheus + Grafana + Loki + Tempo + Fluent-Bit
- **Policy Engine**: Kyverno
- **Notifications**: Slack integration for sync status
---
## Architecture Diagram
```
┌─────────────────────────────────────────────────────────────────────────┐
│ Developer Workflow │
└─────────────────────────────────────────────────────────────────────────┘
┌─────────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ Application Code │ │ Helm Charts │ │ Helm Values │
│ Repositories │──────│ Repository │──────│ Repository │
│ (Source Code) │ │ (Templates) │ │ (Config/Env) │
└─────────────────────┘ └──────────────────┘ └─────────────────┘
│ │ │
│ │ │
GitHub Actions │ │
Build & Push Image │ │
│ │ │
│ │ │
└────────► Update image tag ─┴──────────────────────────┘
in helm-prod-values │
┌────────────────────────────────┐
│ Config Repository │
│ (ArgoCD Applications) │
│ git.forteapps.net/Forte/ │
│ launchpad │
└────────────────────────────────┘
ArgoCD monitors & syncs
┌────────────────────────────────┐
│ Kubernetes Clusters │
│ (UpCloud, AWS, Azure, GCP) │
│ │
│ ┌──────────────────────────┐ │
│ │ ArgoCD │ │
│ │ (GitOps Controller) │ │
│ └──────────────────────────┘ │
│ │
│ ┌──────────────────────────┐ │
│ │ Infrastructure Layer │ │
│ │ - Traefik (Ingress) │ │
│ │ - Cert-Manager (TLS) │ │
│ │ - Kyverno (Policies) │ │
│ │ - Sealed Secrets │ │
│ └──────────────────────────┘ │
│ │
│ ┌──────────────────────────┐ │
│ │ Monitoring Stack │ │
│ │ - Prometheus │ │
│ │ - Grafana │ │
│ │ - Loki │ │
│ │ - Tempo │ │
│ │ - Fluent-Bit │ │
│ └──────────────────────────┘ │
│ │
│ ┌──────────────────────────┐ │
│ │ Application Layer │ │
│ │ - mcp10x │ │
│ │ - musicman │ │
│ │ - dot-ai-stack │ │
│ │ - argo-mcp │ │
│ └──────────────────────────┘ │
└────────────────────────────────┘
┌──────────────────┐
│ Slack Channel │
│ (Notifications) │
└──────────────────┘
```
---
## Repository Structure
### 1. **Config Repository** (Current Repo)
**Repository**: `https://git.forteapps.net/Forte/launchpad`
**Purpose**: GitOps configuration - ArgoCD Applications and cluster resources
**Location**: `C:\dev\k8s\launchpad`
```
launchpad/
├── bootstrap.sh # Cluster initialization script
├── _app-of-apps-upc-dev.yaml # Root ArgoCD Application (upc-dev cluster)
├── _app-of-apps-upc-prod.yaml # Root ArgoCD Application (upc-prod cluster)
├── infra/ # Infrastructure ArgoCD Applications (Kustomize)
│ ├── base/ # Base Application manifests (upc-dev defaults)
│ │ ├── kustomization.yaml
│ │ ├── traefik-application.yaml
│ │ ├── keycloak.yaml
│ │ ├── grafana.yaml
│ │ ├── gitea.yaml
│ │ ├── gitea-actions.yaml
│ │ ├── tempo.yaml
│ │ ├── renovate.yaml
│ │ ├── ... # All other Application manifests
│ │ └── secrets.yaml
│ ├── overlays/ # Per-cluster Kustomize overrides
│ │ ├── upc-dev/ # UpCloud Dev (uses base as-is)
│ │ ├── upc-prod/ # UpCloud Prod (patches value paths)
│ │ ├── eks-dev/ # AWS EKS Dev
│ │ ├── eks-prod/ # AWS EKS Prod
│ │ ├── aks-dev/ # Azure AKS Dev
│ │ ├── aks-prod/ # Azure AKS Prod
│ │ ├── gke-dev/ # GCP GKE Dev
│ │ └── gke-prod/ # GCP GKE Prod
│ ├── dashboards/ # Grafana dashboard ConfigMaps
│ └── values/ # Helm value overrides for infra
│ ├── base/ # Cloud-agnostic shared values
│ ├── upc-{dev,prod}/ # UpCloud: storage class, LB, pricing
│ ├── aws-{dev,prod}/ # AWS: gp3, NLB, CUR pricing
│ ├── aks-{dev,prod}/ # Azure: managed-csi-premium, Standard LB
│ └── gcp-{dev,prod}/ # GCP: premium-rwo, L4 LB
├── apps/ # Business Application ArgoCD manifests (Kustomize)
│ ├── base/ # Base app manifests
│ │ ├── kustomization.yaml
│ │ ├── dot-ai-stack.yaml
│ │ └── ...
│ └── overlays/
│ ├── upc-dev/ # Uses base as-is
│ └── upc-prod/ # Patches value paths
├── cluster-resources/ # Cluster-wide Kubernetes resources
│ ├── ...
│ └── policies/ # Kyverno policies
├── secrets/ # Application secrets (sealed, per-cluster)
│ └── upc-dev/ # Secrets for upc-dev cluster
├── private/ # Local-only files (NOT in Git)
└── docs/ # Documentation
```
**Key Points**:
- `_app-of-apps-upc-dev.yaml` and `_app-of-apps-upc-prod.yaml` are the per-cluster root Applications
- Kustomize overlays in `infra/overlays/` render base Applications with per-cluster patches
- Helm values are split: `values/base/` (shared) + `values/upc-dev/` or `values/upc-prod/` (cluster-specific)
- `apps/` follows the same base/overlays pattern for business applications
- Changes pushed to this repo trigger automatic syncs in ArgoCD
- `private/` folder contains local-only files (Git-ignored)
---
### 2. **Helm Charts Repository**
**Repository**: `https://git.forteapps.net/Forte/forte-helm`
**Purpose**: Reusable Helm chart templates for Forte applications
**Location**: `C:\dev\k8s\forte-helm`
```
forte-helm/
└── forteapp/ # Generic Forte application chart
├── Chart.yaml # Chart metadata (v0.1.0)
├── values.yaml # Default values (base template)
├── templates/
│ ├── _helpers.tpl # Template helpers
│ ├── namespace.yaml
│ ├── deployment.yaml # Main app deployment
│ ├── service.yaml
│ ├── ingressroute.yaml # Traefik IngressRoute
│ ├── certificate.yaml # Cert-Manager Certificate
│ ├── configmap.yaml
│ ├── secret-auth-tokens.yaml
│ ├── hpa.yaml # Horizontal Pod Autoscaler
│ ├── database-statefulset.yaml # Optional PostgreSQL DB
│ └── database-service.yaml
└── README.md
```
**Key Points**:
- Single generic chart (`forteapp`) used by all Forte applications
- Supports optional PostgreSQL database (StatefulSet)
- Configurable authentication (token-based or OIDC)
- Traefik IngressRoute with automatic TLS via Cert-Manager
- Designed for microservices with similar patterns
---
### 3. **Helm Values Repository**
**Repository**: `git@github.com:fortedigital/helm-prod-values.git`
**Purpose**: Environment-specific configuration for each application
**Location**: `C:\dev\k8s\helm-prod-values`
```
helm-prod-values/
├── mcp10x/
│ └── values.yaml # MCP 10X configuration
├── musicman/
│ └── values.yaml # Music Man configuration
└── argocd-mcp/
└── values.yaml # ArgoCD MCP configuration
```
**Key Points**:
- Each app has its own folder with `values.yaml`
- Contains environment-specific settings (image tags, env vars, resources, etc.)
- Referenced by ArgoCD Applications using multi-source pattern
- Image tags are updated here by CI/CD pipelines
- Secrets are referenced by name (actual secrets stored as SealedSecrets)
**Example** (`mcp10x/values.yaml`):
```yaml
app:
image:
repository: ghcr.io/fortedigital/10x
tag: 2.0.4 # Updated by CI/CD
extraEnv:
- name: PORT
value: "3000"
envSecretName: "app-credentials" # References SealedSecret
ingress:
enabled: true
host: mcp10x.forteapps.net # Public domain
```
---
### 4. **Application Source Code Repositories**
**Purpose**: Application source code with CI/CD pipelines
**Examples**: Various private repositories
**Typical Structure**:
```
app-repository/
├── src/ # Application source code
├── Dockerfile # Container build definition
├── .github/
│ └── workflows/
│ └── build-and-deploy.yml # GitHub Actions workflow
└── package.json / requirements.txt # Dependencies
```
**CI/CD Workflow** (GitHub Actions):
1. Trigger on push to `main` branch
2. Build Docker image
3. Tag with version (e.g., `v2.0.4`)
4. Push to container registry (GHCR, Docker Hub, etc.)
5. Update image tag in `helm-prod-values` repository
6. ArgoCD detects change and syncs automatically
---
## GitOps Workflow
### The App-of-Apps Pattern
```
_app-of-apps-{cluster}.yaml (Root, per cluster — e.g. upc-dev, eks-prod, gke-dev)
├── infrastructure-apps (manages infra/)
│ ├── cluster-resources-application
│ ├── traefik-application
│ ├── cert-manager-application
│ ├── kyverno
│ ├── prometheus
│ ├── grafana
│ ├── tempo
│ └── ... (other infra apps)
└── enterprise-apps (manages apps/)
├── mcp10x
├── musicman
├── dot-ai-stack
└── argo-mcp
```
**How It Works**:
1. Bootstrap script installs ArgoCD and applies `_app-of-apps-upc-dev.yaml` (or `upc-prod`)
2. ArgoCD creates the root Application which monitors the appropriate `infra/overlays/` folder
3. Kustomize renders base Applications with cluster-specific patches
4. `enterprise-apps` Application monitors the cluster's `apps/overlays/` folder
5. ArgoCD continuously syncs (every 60s) and auto-heals drift
### Sync Waves & Ordering
Applications deploy in order using `argocd.argoproj.io/sync-wave` annotations:
```
Wave -1: Namespaces (created first)
Wave 0: Kyverno (policies ready before resources)
Wave 1: Cluster resources, infrastructure apps
Wave 2+: Business applications
```
Example:
```yaml
metadata:
annotations:
argocd.argoproj.io/sync-wave: "1"
```
### Multi-Source Pattern
Applications like `mcp10x` and `musicman` use multiple sources:
```yaml
spec:
sources:
- repoURL: https://git.forteapps.net/Forte/forte-helm
path: forteapp # Helm chart templates
helm:
valueFiles:
- $values/mcp10x/values.yaml # Reference to second source
- repoURL: git@github.com:fortedigital/helm-prod-values.git
targetRevision: HEAD
ref: values # Named reference
```
**Benefits**:
- Chart templates separated from configuration
- Single chart reused across all apps
- Easy to update all apps by changing the chart
- Environment-specific values isolated in separate repo
### Multi-Cluster Pattern
Kustomize overlays enable deploying the same Applications across clusters with different configurations:
```yaml
# infra/base/ contains default (upc-dev) Applications
# Helm values are layered: base + cluster-specific
valueFiles:
- $values/infra/values/base/traefik-values.yaml # Shared config
- $values/infra/values/upc-dev/traefik-values.yaml # Cluster-specific
# infra/overlays/upc-prod/kustomization.yaml patches the second valueFile
patches:
- target:
kind: Application
name: traefik
patch: |
- op: replace
path: /spec/sources/0/helm/valueFiles/1
value: $values/infra/values/upc-prod/traefik-values.yaml
```
Cloud-specific values (storage classes, load balancer annotations, cost model) are isolated in per-cluster value files. Base values are fully cloud-agnostic:
| Cloud | Storage Class | Load Balancer | OpenCost Provider |
|-------|--------------|---------------|-------------------|
| **UpCloud** | `upcloud-block-storage-maxiops` | UpCloud LB (ProxyProtocol v2) | Custom pricing |
| **AWS EKS** | `gp3` (EBS CSI) | NLB (ProxyProtocol v2) | AWS CUR |
| **Azure AKS** | `managed-csi-premium` | Standard LB (`externalTrafficPolicy: Local`) | Azure Billing API |
| **GCP GKE** | `premium-rwo` (PD CSI) | L4 passthrough NLB | GCP Cloud Billing |
**Benefits**:
- Single source of truth for Application definitions
- Cluster-specific values isolated per overlay
- Easy to add new clusters by creating a new overlay
- Base values shared across all clusters reduce duplication
---
## CI/CD Pipeline
### Continuous Integration
**Application Repositories** contain GitHub Actions workflows:
```yaml
name: Build and Deploy
on:
push:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build Docker image
run: docker build -t ghcr.io/fortedigital/app:$VERSION .
- name: Push to registry
run: docker push ghcr.io/fortedigital/app:$VERSION
- name: Update Helm values
run: |
git clone git@github.com:fortedigital/helm-prod-values.git
cd helm-prod-values/app
sed -i "s/tag: .*/tag: $VERSION/" values.yaml
git commit -am "Update app to $VERSION"
git push
```
### Continuous Deployment
**ArgoCD** automatically syncs when changes are detected:
1. **Config Repo Change**:
- Developer updates `apps/myapp.yaml`
- Pushes to `launchpad` repo
- ArgoCD detects change (60s reconciliation)
- Syncs application to cluster
2. **Helm Values Change**:
- CI/CD updates `helm-prod-values/myapp/values.yaml`
- ArgoCD detects change
- Pulls new Helm chart with updated values
- Applies to cluster
3. **Sync Policy**:
```yaml
syncPolicy:
automated:
prune: true # Remove deleted resources
selfHeal: true # Revert manual changes
retry:
limit: 5 # Retry up to 5 times
backoff:
duration: 5s
maxDuration: 3m
```
### Deployment Validation
Before applying, ArgoCD:
- ✅ Validates YAML syntax
- ✅ Checks Kubernetes schema
- ✅ Runs server-side dry-run
- ✅ Verifies resource quotas
- ✅ Applies Kyverno policies
After applying:
- ✅ Waits for resources to become healthy
- ✅ Sends Slack notification (success/failure)
- ✅ Tracks sync status in UI
---
## Security Model
### Secret Management
**Sealed Secrets** encrypt secrets for safe Git storage:
```bash
# Developer creates plain secret locally
kubectl create secret generic app-creds \
--from-literal=API_KEY=secret123 \
--dry-run=client -o yaml > private/app-creds.yaml
# Seal the secret using kubeseal
kubeseal --format=yaml \
--cert=pub-cert.pem \
< private/app-creds.yaml \
> secrets/app-creds-sealed.yaml
# Commit sealed secret to Git
git add secrets/app-creds-sealed.yaml
git commit -m "Add app credentials"
```
**Storage**:
- ✅ Sealed secrets committed to Git
- ❌ Plain secrets kept in `private/` (Git-ignored) or discarded
- ⚠️ Secret rotation process not yet established
### Kyverno Policies
**Policy Engine** enforces security rules:
1. **Secret Cloning**: Automatically clones secrets to new namespaces
```yaml
# cluster-resources/policies/secret-cloner.yaml
# Secrets labeled "allowedToBeCloned: true" are synced
```
2. **Default Namespace Blocker**: Prevents use of `default` namespace
3. **Bare Pod Cleaner**: Removes pods without controllers (Deployments/StatefulSets)
4. **Deployment Verifier**: Ensures pods have proper controllers
5. **Auth Sidecar Injector**: Injects authentication proxy based on annotations
### Repository Access
**Private Repository Credentials** stored as SealedSecrets:
```yaml
# cluster-resources/forte10x-repo-credentials-sealed.yaml
```
ArgoCD uses these to access private Helm values repositories.
### Network Security
**Traefik Ingress** with TLS:
- All HTTP traffic redirects to HTTPS
- Let's Encrypt automatic certificate renewal
- Cert-Manager manages certificate lifecycle
- Per-application IngressRoutes with dedicated certificates
### Authentication
**Application-Level Auth** (optional):
- Token-based authentication (static tokens)
- OIDC integration (Keycloak, Okta, etc.)
- Auth sidecar injected via Kyverno policy
- Tokens stored in SealedSecrets
Example:
```yaml
# In deployment.yaml template
annotations:
policies.forteapps.io/auth: "true"
policies.forteapps.io/auth-token-secret-name: "app-tokens"
```
---
## Monitoring & Observability
### Stack Components
1. **Prometheus**: Metrics collection and storage
2. **Grafana**: Metrics visualization and dashboards
3. **Loki**: Log aggregation
4. **Tempo**: Distributed tracing (OTLP)
5. **Fluent-Bit**: Log shipping from pods to Loki
6. **Trivy**: Container vulnerability scanning
### Slack Notifications
All ArgoCD applications send notifications to shared Slack channel:
```yaml
metadata:
annotations:
notifications.argoproj.io/subscribe.on-sync-succeeded.slack: ""
notifications.argoproj.io/subscribe.on-sync-failed.slack: ""
notifications.argoproj.io/subscribe.on-degraded.slack: ""
```
Notifications include:
- ✅ Sync succeeded
- ❌ Sync failed
- ⚠️ Application degraded
---
## Disaster Recovery
### Cluster Rebuild
**Current State**: No backup routines exist yet. Cluster can be rebuilt from Git.
**Rebuild Process**:
1. Provision new Kubernetes cluster
2. Clone `launchpad` repository
3. Run `./bootstrap.sh`
4. ArgoCD installs and syncs all applications
5. Manually recreate unsealed secrets and seal them
**Data Loss**:
- Currently: Data loss is acceptable (internal use)
- Future: One stateful application may require backup strategy
### GitOps Advantages for DR
**Infrastructure as Code**: Entire cluster defined in Git
**Reproducible**: Cluster can be rebuilt identically
**Auditable**: All changes tracked in Git history
**Rollback**: Easy to revert to previous Git commit
**Multi-Cluster**: Same config can deploy to multiple clusters
---
## Best Practices
### Repository Organization
**DO**:
- Separate infrastructure (`infra/`) from applications (`apps/`)
- Use sync waves to control deployment order
- Keep secrets in `private/` folder (Git-ignored)
- Commit only sealed secrets to Git
- Use multi-source pattern for chart/values separation
**DON'T**:
- Commit plain secrets to Git
- Mix infrastructure and application configs
- Hard-code environment-specific values in charts
- Manually modify resources in cluster (use Git)
### GitOps Workflow
**DO**:
- All changes through Git (single source of truth)
- Use PR reviews for production changes
- Test changes in isolated namespaces first
- Monitor ArgoCD sync status
- Respond to Slack notifications
**DON'T**:
- Use `kubectl apply` directly (breaks GitOps)
- Ignore sync failures
- Bypass ArgoCD for "quick fixes"
- Edit resources in place (`kubectl edit`)
### Application Development
**DO**:
- Follow the `forteapp` chart pattern
- Use semantic versioning for image tags
- Update helm-prod-values via CI/CD
- Test locally with Docker Compose
- Document environment variables
**DON'T**:
- Use `latest` image tag
- Hard-code configuration in code
- Skip local testing
- Deploy untested images to production
---
## Next Steps
📖 Continue to:
- **[Developer Guide](DEVELOPER-GUIDE.md)** - Learn how to deploy and manage applications
- **[Operations Runbook](OPERATIONS-RUNBOOK.md)** - Common operational tasks
- **[Technical Reference](REFERENCE.md)** - Detailed component documentation
---
**Last Updated**: 2026-04-22
**Maintained By**: Platform Team
**Questions?**: Contact #platform-support on Slack
File diff suppressed because it is too large Load Diff
+332
View File
@@ -0,0 +1,332 @@
# Kubernetes Cluster Documentation
Welcome to the comprehensive documentation for our Kubernetes cluster GitOps setup. This documentation covers architecture, development workflows, operations, and technical references.
## 📚 Documentation Index
### 1. [GitOps Architecture & Repository Guide](GITOPS-ARCHITECTURE.md)
**Start here to understand the system**
Learn about:
- Overall architecture and design decisions
- Repository structure and relationships
- GitOps workflow and deployment patterns
- CI/CD pipeline integration
- Security model and best practices
**Best for**: Understanding how everything fits together, architectural decisions, and the big picture.
---
### 2. [Developer Onboarding Guide](DEVELOPER-GUIDE.md)
**For developers deploying and maintaining applications**
Learn how to:
- Set up your local development environment
- Deploy your first application
- Update existing applications
- Manage secrets securely
- Troubleshoot common issues
- Follow development best practices
**Best for**: New developers joining the team, deploying applications, day-to-day development workflows.
---
### 3. [Operations Runbook](OPERATIONS-RUNBOOK.md)
**For platform engineers and operators**
Learn how to:
- Bootstrap a new cluster
- Monitor and maintain applications
- Manage infrastructure components
- Handle secrets and credentials
- Troubleshoot production issues
- Perform disaster recovery
- Execute maintenance procedures
**Best for**: Platform team members, SRE tasks, incident response, cluster maintenance.
---
### 4. [Technical Reference](REFERENCE.md)
**Detailed technical specifications**
Reference for:
- Component specifications and versions
- Helm chart templates and values
- ArgoCD configuration options
- Kyverno policy definitions
- API endpoints and interfaces
- Configuration schemas
- Complete glossary
**Best for**: Looking up specific configuration options, understanding component details, API references.
---
## 🚀 Quick Start
### For New Developers
1. Read [GitOps Architecture](GITOPS-ARCHITECTURE.md#overview) to understand the system
2. Follow [Developer Guide - Prerequisites](DEVELOPER-GUIDE.md#prerequisites) to set up your environment
3. Deploy your first application using [Deploying Your First Application](DEVELOPER-GUIDE.md#deploying-your-first-application)
### For Platform Engineers
1. Understand the architecture in [GitOps Architecture](GITOPS-ARCHITECTURE.md)
2. Learn cluster bootstrap in [Operations Runbook - Cluster Bootstrap](OPERATIONS-RUNBOOK.md#cluster-bootstrap)
3. Review [Day-to-Day Operations](OPERATIONS-RUNBOOK.md#day-to-day-operations) procedures
### For Troubleshooting
1. Check [Developer Guide - Troubleshooting](DEVELOPER-GUIDE.md#troubleshooting) for common developer issues
2. Check [Operations Runbook - Troubleshooting](OPERATIONS-RUNBOOK.md#troubleshooting) for operational issues
3. Consult [Technical Reference](REFERENCE.md) for configuration details
---
## 🗺️ Documentation Map
```
┌─────────────────────────────────────────────────────────────┐
│ GITOPS ARCHITECTURE │
│ (System Overview, Repositories, Workflows, Security) │
└─────────────────────────────────────────────────────────────┘
┌───────────┴───────────┐
│ │
▼ ▼
┌──────────────────┐ ┌──────────────────────┐
│ DEVELOPER GUIDE │ │ OPERATIONS RUNBOOK │
│ (Development) │ │ (Operations) │
└──────────────────┘ └──────────────────────┘
│ │
└───────────┬───────────┘
┌────────────────────┐
│ TECHNICAL REFERENCE│
│ (Specifications) │
└────────────────────┘
```
---
## 📖 Reading Paths
### Path 1: New Developer (No K8s Experience)
1. [GitOps Architecture - Overview](GITOPS-ARCHITECTURE.md#overview)
2. [GitOps Architecture - GitOps Workflow](GITOPS-ARCHITECTURE.md#gitops-workflow)
3. [Developer Guide - Understanding the Workflow](DEVELOPER-GUIDE.md#understanding-the-workflow)
4. [Developer Guide - Deploying Your First Application](DEVELOPER-GUIDE.md#deploying-your-first-application)
5. [Developer Guide - Troubleshooting](DEVELOPER-GUIDE.md#troubleshooting)
### Path 2: Experienced Developer (Has K8s Experience)
1. [GitOps Architecture - Repository Structure](GITOPS-ARCHITECTURE.md#repository-structure)
2. [Developer Guide - Local Development Setup](DEVELOPER-GUIDE.md#local-development-setup)
3. [Developer Guide - Deploying Your First Application](DEVELOPER-GUIDE.md#deploying-your-first-application)
4. [Technical Reference - Helm Chart Reference](REFERENCE.md#helm-chart-reference)
### Path 3: Platform Engineer / SRE
1. [GitOps Architecture](GITOPS-ARCHITECTURE.md) (entire document)
2. [Operations Runbook - Cluster Bootstrap](OPERATIONS-RUNBOOK.md#cluster-bootstrap)
3. [Operations Runbook - Day-to-Day Operations](OPERATIONS-RUNBOOK.md#day-to-day-operations)
4. [Operations Runbook - Troubleshooting](OPERATIONS-RUNBOOK.md#troubleshooting)
5. [Technical Reference](REFERENCE.md) (as needed)
### Path 4: Quick Reference
1. [Developer Guide - Quick Reference](DEVELOPER-GUIDE.md#quick-reference)
2. [Technical Reference - Configuration Reference](REFERENCE.md#configuration-reference)
3. [Technical Reference - Glossary](REFERENCE.md#glossary)
---
## 🔍 Finding Information
### How do I...?
| Task | Documentation |
|------|---------------|
| **Deploy a new application** | [Developer Guide - Deploying Your First Application](DEVELOPER-GUIDE.md#deploying-your-first-application) |
| **Update an existing application** | [Developer Guide - Updating an Existing Application](DEVELOPER-GUIDE.md#updating-an-existing-application) |
| **Create and seal secrets** | [Developer Guide - Working with Secrets](DEVELOPER-GUIDE.md#working-with-secrets) |
| **Troubleshoot deployment issues** | [Developer Guide - Troubleshooting](DEVELOPER-GUIDE.md#troubleshooting) |
| **Bootstrap a new cluster** | [Operations Runbook - Cluster Bootstrap](OPERATIONS-RUNBOOK.md#cluster-bootstrap) |
| **Scale an application** | [Operations Runbook - Scaling Applications](OPERATIONS-RUNBOOK.md#scaling-applications) |
| **Roll back a deployment** | [Operations Runbook - Rolling Back Deployments](OPERATIONS-RUNBOOK.md#rolling-back-deployments) |
| **Manage monitoring** | [Operations Runbook - Monitoring & Alerting](OPERATIONS-RUNBOOK.md#monitoring--alerting) |
| **Understand ArgoCD config** | [Technical Reference - ArgoCD Configuration](REFERENCE.md#argocd-configuration) |
| **Look up Helm values** | [Technical Reference - Helm Chart Reference](REFERENCE.md#helm-chart-reference) |
| **Find component versions** | [Technical Reference - Version Matrix](REFERENCE.md#version-matrix) |
---
## 📊 System Overview
### Cluster Architecture
```
┌──────────────────────────────────────────────────────────────┐
│ GitHub Repositories │
│ ┌────────────┐ ┌────────────┐ ┌────────────────────────┐ │
│ │ Config │ │ Charts │ │ Values │ │
│ │ (ArgoCD) │ │ (Templates)│ │ (Environment Config) │ │
│ └────────────┘ └────────────┘ └────────────────────────┘ │
└──────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────┐
│ ArgoCD (GitOps Engine) │
│ Sync every 60 seconds │
└──────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────┐
│ Kubernetes Clusters (UpCloud, AWS, Azure, GCP) │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Infrastructure: Traefik, Cert-Manager, Kyverno │ │
│ ├──────────────────────────────────────────────────────┤ │
│ │ Monitoring: Prometheus, Grafana, Loki, Fluent-Bit │ │
│ ├──────────────────────────────────────────────────────┤ │
│ │ Applications: mcp10x, musicman, dot-ai-stack │ │
│ └──────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────┘
```
### Key Technologies
- **GitOps**: ArgoCD
- **Kubernetes**: Multi-cloud (UpCloud, AWS EKS, Azure AKS, GCP GKE)
- **Ingress**: Traefik v2
- **Certificates**: Cert-Manager + Let's Encrypt
- **Policies**: Kyverno
- **Secrets**: Sealed Secrets
- **Monitoring**: Prometheus + Grafana
- **Logging**: Loki + Fluent-Bit
---
## 🛠️ Common Tasks
### Development Tasks
```bash
# Deploy new application
cd ~/dev/k8s/launchpad
# Create apps/myapp.yaml and helm-prod-values/myapp/values.yaml
git add apps/myapp.yaml
git commit -m "Add myapp"
git push
# Update application
cd ~/dev/k8s/helm-prod-values
vim myapp/values.yaml
git commit -am "Update myapp config"
git push
# Create secret
kubeseal --format=yaml --cert=pub-cert.pem \
< private/secret.yaml > secrets/secret-sealed.yaml
git add secrets/secret-sealed.yaml
git push
```
### Operations Tasks
```bash
# Check application status
kubectl get applications -n argocd
# View application details
kubectl describe application myapp -n argocd
# Force sync
kubectl patch application myapp -n argocd \
--type merge -p '{"metadata":{"annotations":{"argocd.argoproj.io/refresh":"hard"}}}'
# Check pod logs
kubectl logs -n myapp <pod-name>
# Restart deployment
kubectl rollout restart deployment myapp -n myapp
```
---
## 🆘 Getting Help
### Documentation Search Order
1. **Quick Reference**: [Developer Guide - Quick Reference](DEVELOPER-GUIDE.md#quick-reference)
2. **Troubleshooting**: [Developer Guide - Troubleshooting](DEVELOPER-GUIDE.md#troubleshooting) or [Operations Runbook - Troubleshooting](OPERATIONS-RUNBOOK.md#troubleshooting)
3. **Technical Details**: [Technical Reference](REFERENCE.md)
4. **Architecture Context**: [GitOps Architecture](GITOPS-ARCHITECTURE.md)
### Support Channels
- **Slack**: #platform-support
- **Issues**: Platform team
- **Emergencies**: Escalate via Slack
---
## 📝 Document Maintenance
### Updating Documentation
If you find:
- Outdated information
- Missing procedures
- Errors or typos
- Areas needing clarification
Please:
1. Create an issue or PR in the repository
2. Notify the platform team
3. Update the relevant documentation file
### Documentation Structure
```
docs/
├── README.md # This file (index)
├── GITOPS-ARCHITECTURE.md # Architecture overview
├── DEVELOPER-GUIDE.md # Developer workflows
├── OPERATIONS-RUNBOOK.md # Operations procedures
└── REFERENCE.md # Technical specifications
```
---
## 🔄 Documentation Versions
**Current Version**: 1.0.0
**Last Updated**: 2026-04-22
**Maintained By**: Platform Team
### Changelog
- **v1.1.0 (2026-04-22)**: Multi-cloud support
- Cloud-agnostic base values (storage, LB, pricing moved to per-cluster overlays)
- Added AWS EKS, Azure AKS, GCP GKE configurations
- Per-cloud backup scripts
- Updated all documentation
- **v1.0.0 (2026-03-16)**: Initial comprehensive documentation release
- GitOps Architecture guide
- Developer Onboarding guide
- Operations Runbook
- Technical Reference
- Documentation index
---
## 🎯 Next Steps
Choose your path:
- 👨‍💻 **New Developer?** Start with [Developer Guide](DEVELOPER-GUIDE.md)
- 🔧 **Platform Engineer?** Read [Operations Runbook](OPERATIONS-RUNBOOK.md)
- 🏗️ **Architect?** Explore [GitOps Architecture](GITOPS-ARCHITECTURE.md)
- 🔍 **Need Details?** Check [Technical Reference](REFERENCE.md)
---
**Welcome to the team! 🚀**
+1951
View File
File diff suppressed because it is too large Load Diff
-1667
View File
File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More