diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index d2c3bbb2..00000000 --- a/.eslintignore +++ /dev/null @@ -1,30 +0,0 @@ -# code -.vscode/* - -# modules -node_modules -**/node_modules - -# package -package.json -pnpm-lock.yaml - -# doc -README.md - -# github actions -!.github - -# TODO : Fix later -# socle/roles/harbor/templates/ca-cm.yaml -# 8:1 error Parsing error: Plain value cannot start with directive indicator character % - -# socle/roles/keycloak/templates/console-frontend-redirectUris.yaml -# 2:0 error Parsing error: Unexpected flow-map-start at node end - -# socle/roles/keycloak/templates/console-frontend-webOrigins.yaml -# 2:0 error Parsing error: Unexpected flow-map-start at node end - -roles/harbor/templates/ca-cm.yaml -roles/keycloak/templates/console-frontend-redirectUris.yaml -roles/keycloak/templates/console-frontend-webOrigins.yaml \ No newline at end of file diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index 74745aa4..00000000 --- a/.eslintrc.js +++ /dev/null @@ -1,15 +0,0 @@ -module.exports = { - extends: [ - "plugin:yml/standard", - ], - rules: { - "yml/no-empty-mapping-value": "off", - "yml/plain-scalar": "off", - }, - overrides: [ - { - files: ["*.yaml", "*.yml"], - parser: "yaml-eslint-parser", - }, - ], -} \ No newline at end of file diff --git a/.github/workflows/cache.yml b/.github/workflows/cache.yml index d0222805..01e2df1d 100644 --- a/.github/workflows/cache.yml +++ b/.github/workflows/cache.yml @@ -23,7 +23,7 @@ jobs: echo "Fetching list of cache key" cacheKeysForPR=$(gh actions-cache list -R $REPO -B $BRANCH -L 100 | cut -f 1 ) - ## Setting this to not fail the workflow while deleting cache keys. + ## Setting this to not fail the workflow while deleting cache keys. set +e echo "Deleting caches..." for cacheKey in $cacheKeysForPR diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 96246111..e71c44a1 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -37,7 +37,7 @@ jobs: echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_ENV - name: Setup pnpm cache - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: | ${{ env.STORE_PATH }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5525411f..d3ecfb44 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -29,8 +29,8 @@ jobs: - name: Checks-out repository uses: actions/checkout@v4 - - name: Pre release new version - uses: google-github-actions/release-please-action@v4 + - name: Release new version + uses: googleapis/release-please-action@v4 id: release with: target-branch: main diff --git a/.lintstagedrc b/.lintstagedrc index c929db74..9c855719 100644 --- a/.lintstagedrc +++ b/.lintstagedrc @@ -1,3 +1,3 @@ { - "*.{yml, yaml}": "pnpm run format" + "**/*.{yml,yaml}": "eslint" } \ No newline at end of file diff --git a/.release-please-manifest.json b/.release-please-manifest.json index d1328ca9..6ed9c801 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { ".": "2.7.0" -} \ No newline at end of file +} diff --git a/README.md b/README.md index 8ea36965..0fe26f91 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,10 @@ - [SonarQube Community Edition](#sonarqube-community-edition) - [Vault](#vault) - [Backups](#backups) +- [Offline / air gap](#offline--air-gap) +- [Platform](#platform) +- [Profile CIS](#profile-cis) +- [Utilisation de credentials Docker Hub pour le pull des images](#utilisation-de-credentials-docker-hub-pour-le-pull-des-images) - [Contributions](#contributions) - [Les commandes de l'application](#les-commandes-de-lapplication) - [Conventions](#conventions) @@ -123,6 +127,7 @@ Pour information, le playbook `install-requirements.yaml` vous installera les é - pyyaml - kubernetes - python-gitlab + - jmespath - Collection Ansible [kubernetes.core](https://github.com/ansible-collections/kubernetes.core) si elle n'est pas déjà présente. @@ -156,7 +161,7 @@ kubectl apply -f ma-conf-dso.yaml Pour vous aider à démarrer, voici un **exemple** de fichier de configuration valide, à adapter à partir de la section **spec**, notamment au niveau : * du paramètre `global.rootDomain` (votre domaine principal précédé d'un point), * des mots de passe de certains outils, -* du paramètre `global.platform` (à positionner sur `kubernetesVanilla` si vous n'utilisez pas OpenShift), +* du paramètre `global.platform` (à positionner sur `kubernetes` si vous n'utilisez pas OpenShift), * de la taille de certains PVCs, * de l'activation ou non des métriques, * du proxy ainsi que des sections CA et ingress. @@ -214,7 +219,7 @@ spec: values: {} ingress: annotations: - route.openshift.io/termination: "edge" + route.openshift.io/termination: edge tls: type: tlsSecret tlsSecret: @@ -232,7 +237,7 @@ spec: type: external proxy: enabled: false - host: "192.168.xx.xx" + host: 192.168.xx.xx http_proxy: http://192.168.xx.xx:3128/ https_proxy: http://192.168.xx.xx:3128/ no_proxy: .cluster.local,.svc,10.0.0.0/8,127.0.0.1,192.168.0.0/16,api.example.com,api-int.example.com,canary-openshift-ingress-canary.apps.example.com,console-openshift-console.apps.example.com,localhost,oauth-openshift.apps.example.com,svc.cluster.local,localdomain @@ -268,7 +273,7 @@ Voici les liens vers les documentations de chart Helm pour les outils concernés - [SonarQube](https://github.com/bitnami/charts/tree/main/bitnami/sonarqube) - [HashiCorp Vault](https://github.com/hashicorp/vault-helm) -S'agissant du gel des versions de charts ou d'images pour les outils en question, **nous vous invitons fortement à consulter la section détaillée [Gel des versions](#gel-des-versions)** située plus bas dans le présent document. +S'agissant du gel des versions de charts ou d'images pour les outils en question, **nous vous invitons fortement à consulter la section détaillée [Gel des versions](#gel-des-versions)** située plus bas dans le présent document. ## Installation @@ -305,12 +310,12 @@ Pensez également à déclarer pour chaque outil **un `namespace` et un `subDoma Exemple pour Argo CD : ```yaml - argocd: - namespace: mynamespace-argocd - subDomain: argocd-perso - admin: - enabled: true - password: PasswordForEveryone +argocd: + namespace: mynamespace-argocd + subDomain: argocd-perso + admin: + enabled: true + password: PasswordForEveryone ``` Pour mémoire, les namespaces et subDomains par défaut, déclarés lors de la première installation du socle, peuvent être listés en se positionnant préalablement dans le répertoire socle, puis en affichant le fichier « config.yaml » du role socle-config, exemple en ligne de commande : @@ -610,7 +615,7 @@ Les sections suivantes détaillent comment procéder, outil par outil. - Comme vu dans la section d'installation (sous-section [Déploiement de plusieurs forges DSO dans un même cluster](#déploiement-de-plusieurs-forges-dso-dans-un-même-cluster )), si vous utilisez votre propre ressource `dsc` de configuration, distincte de `conf-dso`, alors toutes les commandes `ansible-playbook` indiquées ci-dessous devront être complétées par l'[extra variable](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_variables.html#defining-variables-at-runtime) `dsc_cr` appropriée. - Pour le gel des versions d'images, il est recommandé, si possible, de positionner un **tag d'image en adéquation avec la version du chart Helm utilisé**, c'est à dire d'utiliser le numéro "APP VERSION" retourné par la commande `helm search repo`. -### Modification des versions de charts +### Modification des versions de charts Techniquement, la modification des versions de charts utilisés est possible mais elle **n'est pas recommandée**. @@ -651,8 +656,8 @@ helm search repo -l argo-cd Pour fixer une version de chart dans la ressource `dsc`, il vous suffira d'ajouter la ligne que vous aurez trouvée dans le fichier « releases.yaml » vu plus haut, au niveau de l'outil concerné, exemple pour Argo CD : ```yaml - argocd: - chartVersion: 4.7.19 +argocd: + chartVersion: 4.7.19 ``` ### Gel des versions d'images @@ -702,32 +707,11 @@ Les sections suivantes détaillent la façon de procéder au gel de version d'im #### Argo CD -Le composant Argo CD est installé à l'aide du chart Helm Bitnami. - -Nous utiliserons un tag dit "[immutable](https://docs.bitnami.com/kubernetes/infrastructure/argo-cd/configuration/understand-rolling-immutable-tags)" (**recommandé en production**). - -Les différents tags utilisables pour l'image d'Argo CD sont disponibles ici : - -Les tags dits "immutables" sont ceux qui possèdent un suffixe de type rXX, lequel correspond au numéro de révision. Ils pointent toujours vers la même image. Par exemple le tag "2.7.6-debian-11-r2" est un tag immutable. - -Pour spécifier un tel tag, il nous suffira d'éditer la ressource `dsc` de configuration (par défaut ce sera la `dsc` nommée `conf-dso`) et de surcharger les "values" correspondantes du chart Helm, en ajoutant celles dont nous avons besoin. Exemple : - -```yaml - argocd: - admin: - enabled: true - password: WeAreThePasswords - values: - image: - registry: docker.io - repository: bitnami/argo-cd - tag: 2.10.7-debian-12-r0 - imagePullPolicy: IfNotPresent -``` +Le composant Argo CD est installé à l'aide de son chart Helm officiel. -Pour mémoire, les values utilisables sont disponibles ici : +La version d'image utilisée est directement liée à la version de chart déployée. Elle est donc déjà gelée par défaut. -Les releases d'Argo CD et leurs changelogs se trouvent ici : +Il est recommandé de ne pas modifier cette version de chart, sauf si vous savez ce que vous faites. #### Cert-manager @@ -817,62 +801,62 @@ Les différents tags utilisables sont disponibles ici : Pour spécifier nos tags, il nous suffira d'éditer la ressource `dsc` de configuration (par défaut ce sera la `dsc` nommée `conf-dso`) et de surcharger les "values" correspondantes du chart Helm, en ajoutant celles dont nous avons besoin. Exemple, pour la version 1.14.1 du chart : ```yaml - harbor: - adminPassword: WhoWantsToPassForever - pvcRegistrySize: 50Gi - values: - nginx: +harbor: + adminPassword: WhoWantsToPassForever + pvcRegistrySize: 50Gi + values: + nginx: + image: + repository: docker.io/goharbor/nginx-photon + tag: v2.10.1 + portal: + image: + repository: docker.io/goharbor/harbor-portal + tag: v2.10.1 + core: + image: + repository: docker.io/goharbor/harbor-core + tag: v2.10.1 + jobservice: + image: + repository: docker.io/goharbor/harbor-jobservice + tag: v2.10.1 + registry: + registry: image: - repository: docker.io/goharbor/nginx-photon + repository: docker.io/goharbor/registry-photon tag: v2.10.1 - portal: + controller: image: - repository: docker.io/goharbor/harbor-portal + repository: docker.io/goharbor/harbor-registryctl tag: v2.10.1 - core: + trivy: + image: + repository: docker.io/goharbor/trivy-adapter-photon + tag: v2.10.1 + notary: + server: image: - repository: docker.io/goharbor/harbor-core + repository: docker.io/goharbor/notary-server-photon tag: v2.10.1 - jobservice: + signer: image: - repository: docker.io/goharbor/harbor-jobservice + repository: docker.io/goharbor/notary-signer-photon tag: v2.10.1 - registry: - registry: - image: - repository: docker.io/goharbor/registry-photon - tag: v2.10.1 - controller: - image: - repository: docker.io/goharbor/harbor-registryctl - tag: v2.10.1 - trivy: + database: + internal: image: - repository: docker.io/goharbor/trivy-adapter-photon + repository: docker.io/goharbor/harbor-db tag: v2.10.1 - notary: - server: - image: - repository: docker.io/goharbor/notary-server-photon - tag: v2.10.1 - signer: - image: - repository: docker.io/goharbor/notary-signer-photon - tag: v2.10.1 - database: - internal: - image: - repository: docker.io/goharbor/harbor-db - tag: v2.10.1 - redis: - internal: - image: - repository: docker.io/goharbor/redis-photon - tag: v2.10.1 - exporter: + redis: + internal: image: - repository: docker.io/goharbor/harbor-exporter + repository: docker.io/goharbor/redis-photon tag: v2.10.1 + exporter: + image: + repository: docker.io/goharbor/harbor-exporter + tag: v2.10.1 ``` Pour mémoire, les values utilisables sont disponibles et documentées ici : @@ -890,8 +874,8 @@ Si toutefois vous souhaitez la modifier, les tags d'images utilisables sont disp Pour déployer une autre version, il suffira d'éditer la `dsc`, de préférence avec le fichier YAML que vous avez initialement utilisé pendant l'installation, puis modifier la section suivante en y indiquant la version d'image désirée au niveau du paramètre **imageVersion**. Exemple : ```yaml - grafana: - imageVersion: "9.5.6" +grafana: + imageVersion: 9.5.6 ``` #### Keycloak @@ -907,12 +891,12 @@ Les tags dits "immutables" sont ceux qui possèdent un suffixe de type rXX, lequ Pour spécifier un tel tag, il nous suffira d'éditer la ressource `dsc` de configuration (par défaut ce sera la `dsc` nommée `conf-dso`) et de surcharger les "values" correspondantes du chart Helm, en ajoutant celles dont nous avons besoin. Exemple : ```yaml - keycloak: - values: - image: - registry: docker.io - repository: bitnami/keycloak - tag: 23.0.7-debian-12-r4 +keycloak: + values: + image: + registry: docker.io + repository: bitnami/keycloak + tag: 23.0.7-debian-12-r4 ``` Pour mémoire, les values utilisables sont disponibles ici : @@ -938,9 +922,9 @@ Si toutefois vous souhaitez la modifier, les tags d'images utilisables sont disp Pour déployer une autre version, il suffira d'éditer la `dsc`, de préférence avec le fichier YAML que vous avez initialement utilisé pendant l'installation, puis modifier la section suivante en y indiquant la version d'image désirée au niveau du paramètre **imageTag**. Exemple : ```yaml - nexus: - storageSize: 25Gi - imageTag: 3.68.1 +nexus: + storageSize: 25Gi + imageTag: 3.68.1 ``` #### SonarQube Community Edition @@ -958,14 +942,14 @@ Il faudra juste leur ajouter le suffixe "-community" qui correspond à l'éditio Pour spécifier un tel tag, il nous suffira d'éditer la ressource `dsc` de configuration (par défaut ce sera la `dsc` nommée `conf-dso`) et de surcharger les "values" correspondantes du chart Helm, en ajoutant celles dont nous avons besoin. Exemple : ```yaml - sonarqube: - postgresPvcSize: 25Gi - values: - image: - registry: docker.io - repository: sonarqube - edition: community - tag: 10.4.1-{{ .Values.edition }} +sonarqube: + postgresPvcSize: 25Gi + values: + image: + registry: docker.io + repository: sonarqube + edition: community + tag: 10.4.1-{{ .Values.edition }} ``` #### Vault @@ -985,22 +969,22 @@ Les différents tags d'images utilisables sont disponibles ici : Pour spécifier nos tags, il nous suffira d'éditer la ressource `dsc` de configuration (par défaut ce sera la `dsc` nommée `conf-dso`) et de surcharger les "values" correspondantes du chart Helm, en ajoutant celles dont nous avons besoin. Exemple : ```yaml - vault: - values: - injector: - image: - repository: "docker.io/hashicorp/vault-k8s" - tag: "1.2.1" - pullPolicy: IfNotPresent - agentImage: - repository: "docker.io/hashicorp/vault" - tag: "1.14.0" - server: - image: - repository: "docker.io/hashicorp/vault" - tag: "1.14.0" - pullPolicy: IfNotPresent - updateStrategyType: "RollingUpdate" +vault: + values: + injector: + image: + repository: docker.io/hashicorp/vault-k8s + tag: 1.2.1 + pullPolicy: IfNotPresent + agentImage: + repository: docker.io/hashicorp/vault + tag: 1.14.0 + server: + image: + repository: docker.io/hashicorp/vault + tag: 1.14.0 + pullPolicy: IfNotPresent + updateStrategyType: RollingUpdate ``` **Remarque importante** : En cas de tentative de mise à jour des versions d'images, dans la section `server` de vos values, le paramètre `updateStrategyType` doit impérativement être présent et positionné sur "RollingUpdate" pour que l'image du serveur Vault puisse éventuellement se mettre à jour avec le tag que vous avez indiqué. @@ -1021,12 +1005,89 @@ Pour les backups de namespaces avec Velero : kubectl explain dsc.spec.global.backup.velero ``` -Pour les backups S3 des BDD PostgreSQL déployées via CNPG : +Pour les backups S3 des BDD PostgreSQL déployées via CNPG : ``` kubectl explain dsc.spec.global.backup.cnpg ``` +## Offline / air gap + +En mode air gap ou déconnecté d'internet, certaines valeurs de la `dsc` devront être adaptées. +- `dsc.sonarqube:` + - `pluginDownloadUrl` et `PrometheusJavaagentVersion` +- `dsc.gitlabCatalog.catalogRepoUrl` +- `dsc.argocd.privateGitlabDomain` +- `dsc.grafanaOperator.ociChartUrl` +- `helmRepoUrl` pour chaque service à savoir : + - `argocd`, `certmanager`, `cloudnativepg`, `console`, `gitlabCiPipelinesExporter`, `gitlabOperator`, `gitlabRunner`, `harbor`, `keycloak`, `kyverno`, `sonarqube` et `vault` + +## Platform + +Par défaut, le déploiement du socle DSO se fait sur un cluster de la famille Openshift, mais il est possible de déployer sur les autres types de distribution Kubernetes (Vanilla, K3s, RKE2, EKS, GKE...) en spécifiant comme suit dans la dsc. +``` +platform: kubernetes +``` + +## Profile CIS + +Pour un déploiement sur un cluster qui n'est pas de la famille d'Openshift, par exemple sur un Kubernetes Vanilla, il est possible d'activer le profil de sécurité CIS pour enforcer la partie securityContext, en spécifiant comme suit dans la dsc. +``` +profile: cis +``` + +## Utilisation de credentials Docker Hub pour le pull des images + +Si vous disposez d'un compte Docker Hub, il est possible de l'utiliser pour le pull d'images des outils de la plateforme elle-même. + +Ceci peut se révéler utile si vous effectuez de nombreux tests d'installation, et que vous vous retrouvez confronté à la problématique des [pull rate limits](https://www.docker.com/increase-rate-limits) de Docker Hub. + +Pour cela, générez tout d'abord un secret de type `kubernetes.io/dockerconfigjson` en mode dry run et qui contiendra vos identifiants Docker Hub. + +Vous en récupérerez le contenu encodé en base64, en une seule fois, via la commande suivante (à adapter avec vos identifiants) : + +```bash +k create secret docker-registry docker-hub-creds \ + --docker-server="https://index.docker.io/v1" \ + --docker-username="email@example.com" \ + --docker-password="mot_de_passe_ici" \ + --docker-email="email@example.com" \ + --dry-run=client \ + -o yaml \ + | yq '.data[.dockerconfigjson]' +``` + +Notez que du fait de l'utilisation de l'option `dry-run`, le secret n'est pas véritablement créé. La partie qui nous intéresse, encodée en base64, est simplement affichée sur la sortie standard. + +Copiez cette sortie, et collez-là dans la section `spec.global.imagePullSecretsData` de votre resource dsc (par défaut conf-dso), exemple : + +```yaml +global: + imagePullSecretsData: valeur_récupérée_ici +``` + +Une fois le changement appliqué à la dsc, relancez l'installation de l'outil souhaité ou de la chaîne DSO complète. Le processus d'installation va maintenant s'appuyer sur le secret `dso-config-pull-secret` créé dans le namespace `default`, utilisant vos identifiants Docker Hub, et répliqué dans le namespace de chaque outil. + +Si vous constatez que la réplication du secret n'a pas lieu ou qu'elle prend trop de temps, supprimez préalablement la ClusterPolicy Kyverno `replace-kubed` : + +```bash +kubectl delete cpol replace-kubed +``` + +Puis relancez l'installation de Kyverno, qui va simplement recréer puis appliquer immédiatement la policy : + +```bash +ansible-playbook install.yaml -t kyverno +``` + +Vérifiez la présence du secret `dso-config-pull-secret` dans le(s) namespace(s) souhaité(s) : + +```bash +kubectl get secrets -A | egrep 'NAME|dso-config-pull-secret' +``` + +Puis relancez l'installation de l'outil voulu ou de la chaîne complète. + ## Contributions ### Les commandes de l'application diff --git a/admin-tools/get-versions.yaml b/admin-tools/get-versions.yaml index 02326b4f..2cd21e84 100644 --- a/admin-tools/get-versions.yaml +++ b/admin-tools/get-versions.yaml @@ -50,6 +50,8 @@ - name: Check socle_config_custom and exit if empty when: (dsc_cr is defined) and (socle_config_custom.resources | length == 0) + tags: + - always block: - name: Warning message ansible.builtin.debug: @@ -71,8 +73,6 @@ - name: Exit playbook ansible.builtin.meta: end_play - tags: - - always - name: Set socle_config fact when dsc_cr defined and not empty ansible.builtin.set_fact: @@ -93,18 +93,21 @@ tags: - always - - ansible.builtin.set_fact: + - name: Set facts + ansible.builtin.set_fact: dsc_default_config: "{{ lookup('ansible.builtin.file', '../roles/socle-config/files/config.yaml') | from_yaml }}" dsc_default_releases: "{{ lookup('ansible.builtin.file', '../roles/socle-config/files/releases.yaml') | from_yaml }}" tags: - always - - ansible.builtin.set_fact: + - name: Set dsc fact + ansible.builtin.set_fact: dsc: "{{ dsc_default_releases | combine(dsc_default_config, recursive=True) | combine(dsc, recursive=True) }}" tags: - always - - ansible.builtin.set_fact: + - name: Adjust dsc fact + ansible.builtin.set_fact: dsc: "{{ dsc.spec }}" tags: - always @@ -133,8 +136,20 @@ namespace: cert-manager register: cert_manager_infos + - name: Warning message + when: > + cm_ns.resources | length > 0 and + cert_manager_infos.status is not defined + ansible.builtin.debug: + msg: + - "Cert-manager n'est pas installé en tant que chart Helm dans le namespace {{ dsc.kyverno.namespace }}." + - "Cela signifie notamment qu'il n'a pas été installé via les roles du Socle." + - "Nous ne pouvons en déterminer la version de manière fiable." + - name: Display cert-manager version - when: cm_ns.resources | length > 0 + when: > + cm_ns.resources | length > 0 and + cert_manager_infos.status is defined ansible.builtin.debug: msg: - "Version de cert-manager : {{ cert_manager_infos.status.app_version }}" @@ -161,11 +176,23 @@ when: kyverno_ns.resources | length > 0 kubernetes.core.helm_info: name: kyverno - namespace: "{{ dsc.kyverno.namespace }}" + namespace: "{{ dsc.kyverno.namespace }}" register: kyverno_infos + - name: Warning message + when: > + kyverno_ns.resources | length > 0 and + kyverno_infos.status is not defined + ansible.builtin.debug: + msg: + - "Kyverno n'est pas installé en tant que chart Helm dans le namespace {{ dsc.kyverno.namespace }}." + - "Cela signifie notamment qu'il n'a pas été installé via les roles du Socle." + - "Nous ne pouvons en déterminer la version de manière fiable." + - name: Display Kyverno version - when: kyverno_ns.resources | length > 0 + when: > + kyverno_ns.resources | length > 0 and + kyverno_infos.status is defined ansible.builtin.debug: msg: - "Version de Kyverno : {{ kyverno_infos.status.app_version }}" @@ -193,11 +220,23 @@ when: cnpg_ns.resources | length > 0 kubernetes.core.helm_info: name: cloudnative-pg - namespace: "{{ dsc.cloudnativepg.namespace }}" + namespace: "{{ dsc.cloudnativepg.namespace }}" register: cnpg_infos + - name: Warning message + when: > + cnpg_ns.resources | length > 0 and + cnpg_infos.status is not defined + ansible.builtin.debug: + msg: + - "L'opérateur CNPG n'est pas installé en tant que chart Helm dans le namespace {{ dsc.kyverno.namespace }}." + - "Cela signifie notamment qu'il n'a pas été installé via les roles du Socle." + - "Nous ne pouvons en déterminer la version de manière fiable." + - name: Display CNPG Operator version - when: cnpg_ns.resources | length > 0 + when: > + cnpg_ns.resources | length > 0 and + cnpg_infos.status is defined ansible.builtin.debug: msg: - "Version de l'opérateur CNPG : {{ cnpg_infos.status.app_version }}" @@ -210,7 +249,7 @@ - name: Retrieve Keycloak infos kubernetes.core.helm_info: name: keycloak - namespace: "{{ dsc.keycloak.namespace }}" + namespace: "{{ dsc.keycloak.namespace }}" register: keycloak_infos - name: Display Keycloak version @@ -248,7 +287,7 @@ - name: Retrieve SonarQube infos kubernetes.core.helm_info: name: sonarqube - namespace: "{{ dsc.sonarqube.namespace }}" + namespace: "{{ dsc.sonarqube.namespace }}" register: sonarqube_infos - name: Display SonarQube version @@ -307,14 +346,14 @@ - name: Retrieve gitlab-ci-pipelines-exporter infos kubernetes.core.helm_info: name: gitlab-ci-pipelines-exporter - namespace: "{{ dsc.gitlab.namespace }}" + namespace: "{{ dsc.gitlab.namespace }}" register: gcipe_infos - name: Warning message when: gcipe_infos.status is not defined ansible.builtin.debug: msg: "Gitlab-ci-pipelines-exporter n'est pas installé." - + - name: Display gitlab-ci-pipelines-exporter version when: gcipe_infos.status is defined ansible.builtin.debug: @@ -330,7 +369,7 @@ - name: Retrieve gitlab-operator infos kubernetes.core.helm_info: name: gitlab-operator - namespace: "{{ dsc.gitlabOperator.namespace }}" + namespace: "{{ dsc.gitlabOperator.namespace }}" register: gop_infos - name: Display gitlab-operator version @@ -347,7 +386,7 @@ - name: Retrieve gitlab-runner infos kubernetes.core.helm_info: name: gitlab-runner - namespace: "{{ dsc.gitlab.namespace }}" + namespace: "{{ dsc.gitlab.namespace }}" register: grunner_infos - name: Display gitlab-runner version @@ -363,7 +402,7 @@ - name: Retrieve Vault infos kubernetes.core.helm_info: name: "{{ dsc_name }}-vault" - namespace: "{{ dsc.vault.namespace }}" + namespace: "{{ dsc.vault.namespace }}" register: vault_infos - name: Display Vault version @@ -379,8 +418,8 @@ block: - name: Retrieve Argo CD infos kubernetes.core.helm_info: - name: "argo" - namespace: "{{ dsc.argocd.namespace }}" + name: "{{ dsc_name }}" + namespace: "{{ dsc.argocd.namespace }}" register: argocd_infos - name: Display Argo CD version @@ -396,7 +435,7 @@ - name: Retrieve Harbor infos kubernetes.core.helm_info: name: "harbor" - namespace: "{{ dsc.harbor.namespace }}" + namespace: "{{ dsc.harbor.namespace }}" register: harbor_infos - name: Display Harbor version @@ -496,11 +535,23 @@ when: gop_ns.resources | length > 0 kubernetes.core.helm_info: name: grafana-operator - namespace: "{{ dsc.grafanaOperator.namespace }}" + namespace: "{{ dsc.grafanaOperator.namespace }}" register: gop_infos + - name: Warning message + when: > + gop_ns.resources | length > 0 and + gop_infos.status is not defined + ansible.builtin.debug: + msg: + - "L'opérateur Grafana n'est pas installé en tant que chart Helm dans le namespace {{ dsc.kyverno.namespace }}." + - "Cela signifie notamment qu'il n'a pas été installé via les roles du Socle." + - "Nous ne pouvons en déterminer la version de manière fiable." + - name: Display Grafana Operator version - when: gop_ns.resources | length > 0 + when: > + gop_ns.resources | length > 0 and + gop_infos.status is defined ansible.builtin.debug: msg: - "Version de l'opérateur Grafana : {{ gop_infos.status.app_version }}" diff --git a/admin-tools/install-requirements.yaml b/admin-tools/install-requirements.yaml index 9a33a4be..ad9abf4e 100644 --- a/admin-tools/install-requirements.yaml +++ b/admin-tools/install-requirements.yaml @@ -13,6 +13,7 @@ - pyyaml - kubernetes - python-gitlab + - jmespath apps: - kubectl - helm @@ -76,7 +77,7 @@ when: (user_profile.stat.exists) and (homebrew_shellenv.stdout | length > 0) ansible.builtin.blockinfile: path: "{{ user_profile.stat.path }}" - block: | + block: | {{ homebrew_shellenv.stdout }} - name: "Install final requirements with Homebrew" diff --git a/commitlint.config.cjs b/commitlint.config.cjs index e4a28e09..7250c5bc 100644 --- a/commitlint.config.cjs +++ b/commitlint.config.cjs @@ -1,5 +1,5 @@ module.exports = { extends: [ - '@commitlint/config-conventional' - ] + "@commitlint/config-conventional", + ], } diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 00000000..73bef693 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,15 @@ +// eslint.config.mjs +import antfu from "@antfu/eslint-config" + +export default antfu({ + stylistic: { + indent: 2, + quotes: "double", + }, + yaml: { + overrides: { + "yml/plain-scalar": "off", + }, + }, + ignores: ["./operator"], +}) diff --git a/install.yaml b/install.yaml index 34030d10..80428821 100644 --- a/install.yaml +++ b/install.yaml @@ -21,16 +21,16 @@ tags: - always + - name: kyverno + tags: + - kyverno + - name: cert-manager tags: - cert-manager - cm - always - - name: kyverno - tags: - - kyverno - - name: cloudnativepg tags: - cloudnativepg diff --git a/package.json b/package.json index 13f8f6a1..b6033a5f 100644 --- a/package.json +++ b/package.json @@ -3,16 +3,15 @@ "version": "2.7.0", "private": true, "scripts": { - "format": "eslint ./ --ext .js,.yaml,.yml --fix", - "lint": "eslint ./ --ext .js,.yaml,.yml" + "format": "eslint . --fix", + "lint": "eslint ." }, "devDependencies": { - "@commitlint/cli": "^18.2.0", - "@commitlint/config-conventional": "^18.1.0", - "husky": "^8.0.3", - "lint-staged": "^15.0.2", - "eslint": "^8.53.0", - "eslint-plugin-yml": "^1.10.0", - "yaml-eslint-parser": "^1.2.2" + "@antfu/eslint-config": "^2.24.1", + "@commitlint/cli": "^19.3.0", + "@commitlint/config-conventional": "^19.2.2", + "eslint": "^9.8.0", + "husky": "^9.1.4", + "lint-staged": "^15.2.8" } -} \ No newline at end of file +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 796740ad..58ff5426 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,27 +8,24 @@ importers: .: devDependencies: + '@antfu/eslint-config': + specifier: ^2.24.1 + version: 2.24.1(@vue/compiler-sfc@3.4.35)(eslint@9.8.0)(typescript@5.2.2) '@commitlint/cli': - specifier: ^18.2.0 - version: 18.2.0(typescript@5.2.2) + specifier: ^19.3.0 + version: 19.3.0(@types/node@18.18.8)(typescript@5.2.2) '@commitlint/config-conventional': - specifier: ^18.1.0 - version: 18.1.0 + specifier: ^19.2.2 + version: 19.2.2 eslint: - specifier: ^8.53.0 - version: 8.53.0 - eslint-plugin-yml: - specifier: ^1.10.0 - version: 1.10.0(eslint@8.53.0) + specifier: ^9.8.0 + version: 9.8.0 husky: - specifier: ^8.0.3 - version: 8.0.3 + specifier: ^9.1.4 + version: 9.1.4 lint-staged: - specifier: ^15.0.2 - version: 15.0.2 - yaml-eslint-parser: - specifier: ^1.2.2 - version: 1.2.2 + specifier: ^15.2.8 + version: 15.2.8 packages: @@ -36,115 +33,212 @@ packages: resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==} engines: {node: '>=0.10.0'} + '@antfu/eslint-config@2.24.1': + resolution: {integrity: sha512-vk2zqPO3HFHxhlIZbMxjo185qvMmCUUc6H58TrXHjMxnCCkw9SqBDWemV6uKUmPSphaOipjzoXYYSyeFYhGa1w==} + hasBin: true + peerDependencies: + '@eslint-react/eslint-plugin': ^1.5.8 + '@prettier/plugin-xml': ^3.4.1 + '@unocss/eslint-plugin': '>=0.50.0' + astro-eslint-parser: ^1.0.2 + eslint: '>=8.40.0' + eslint-plugin-astro: ^1.2.0 + eslint-plugin-format: '>=0.1.0' + eslint-plugin-react-hooks: ^4.6.0 + eslint-plugin-react-refresh: ^0.4.4 + eslint-plugin-solid: ^0.13.2 + eslint-plugin-svelte: '>=2.35.1' + prettier-plugin-astro: ^0.13.0 + prettier-plugin-slidev: ^1.0.5 + svelte-eslint-parser: '>=0.37.0' + peerDependenciesMeta: + '@eslint-react/eslint-plugin': + optional: true + '@prettier/plugin-xml': + optional: true + '@unocss/eslint-plugin': + optional: true + astro-eslint-parser: + optional: true + eslint-plugin-astro: + optional: true + eslint-plugin-format: + optional: true + eslint-plugin-react-hooks: + optional: true + eslint-plugin-react-refresh: + optional: true + eslint-plugin-solid: + optional: true + eslint-plugin-svelte: + optional: true + prettier-plugin-astro: + optional: true + prettier-plugin-slidev: + optional: true + svelte-eslint-parser: + optional: true + + '@antfu/install-pkg@0.3.3': + resolution: {integrity: sha512-nHHsk3NXQ6xkCfiRRC8Nfrg8pU5kkr3P3Y9s9dKqiuRmBD0Yap7fymNDjGFKeWhZQHqqbCS5CfeMy9wtExM24w==} + + '@antfu/utils@0.7.10': + resolution: {integrity: sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==} + '@babel/code-frame@7.22.13': resolution: {integrity: sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==} engines: {node: '>=6.9.0'} + '@babel/helper-string-parser@7.24.8': + resolution: {integrity: sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==} + engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@7.22.20': resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@7.24.7': + resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==} + engines: {node: '>=6.9.0'} + '@babel/highlight@7.22.20': resolution: {integrity: sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==} engines: {node: '>=6.9.0'} - '@commitlint/cli@18.2.0': - resolution: {integrity: sha512-F/DCG791kMFmWg5eIdogakuGeg4OiI2kD430ed1a1Hh3epvrJdeIAgcGADAMIOmF+m0S1+VlIYUKG2dvQQ1Izw==} + '@babel/parser@7.25.3': + resolution: {integrity: sha512-iLTJKDbJ4hMvFPgQwwsVoxtHyWpKKPBrxkANrSYewDPaPpT5py5yeVkgPIJ7XYXhndxJpaA3PyALSXQ7u8e/Dw==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/types@7.25.2': + resolution: {integrity: sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q==} + engines: {node: '>=6.9.0'} + + '@clack/core@0.3.4': + resolution: {integrity: sha512-H4hxZDXgHtWTwV3RAVenqcC4VbJZNegbBjlPvzOzCouXtS2y3sDvlO3IsbrPNWuLWPPlYVYPghQdSF64683Ldw==} + + '@clack/prompts@0.7.0': + resolution: {integrity: sha512-0MhX9/B4iL6Re04jPrttDm+BsP8y6mS7byuv0BvXgdXhbV5PdlsHt55dvNsuBCPZ7xq1oTAOOuotR9NFbQyMSA==} + bundledDependencies: + - is-unicode-supported + + '@commitlint/cli@19.3.0': + resolution: {integrity: sha512-LgYWOwuDR7BSTQ9OLZ12m7F/qhNY+NpAyPBgo4YNMkACE7lGuUnuQq1yi9hz1KA4+3VqpOYl8H1rY/LYK43v7g==} engines: {node: '>=v18'} hasBin: true - '@commitlint/config-conventional@18.1.0': - resolution: {integrity: sha512-8vvvtV3GOLEMHeKc8PjRL1lfP1Y4B6BG0WroFd9PJeRiOc3nFX1J0wlJenLURzl9Qus6YXVGWf+a/ZlbCKT3AA==} + '@commitlint/config-conventional@19.2.2': + resolution: {integrity: sha512-mLXjsxUVLYEGgzbxbxicGPggDuyWNkf25Ht23owXIH+zV2pv1eJuzLK3t1gDY5Gp6pxdE60jZnWUY5cvgL3ufw==} engines: {node: '>=v18'} - '@commitlint/config-validator@18.1.0': - resolution: {integrity: sha512-kbHkIuItXn93o2NmTdwi5Mk1ujyuSIysRE/XHtrcps/27GuUKEIqBJp6TdJ4Sq+ze59RlzYSHMKuDKZbfg9+uQ==} + '@commitlint/config-validator@19.0.3': + resolution: {integrity: sha512-2D3r4PKjoo59zBc2auodrSCaUnCSALCx54yveOFwwP/i2kfEAQrygwOleFWswLqK0UL/F9r07MFi5ev2ohyM4Q==} engines: {node: '>=v18'} - '@commitlint/ensure@18.1.0': - resolution: {integrity: sha512-CkPzJ9UBumIo54VDcpmBlaVX81J++wzEhN3DJH9+6PaLeiIG+gkSx8t7C2gfwG7PaiW4HzQtdQlBN5ab+c4vFQ==} + '@commitlint/ensure@19.0.3': + resolution: {integrity: sha512-SZEpa/VvBLoT+EFZVb91YWbmaZ/9rPH3ESrINOl0HD2kMYsjvl0tF7nMHh0EpTcv4+gTtZBAe1y/SS6/OhfZzQ==} engines: {node: '>=v18'} - '@commitlint/execute-rule@18.1.0': - resolution: {integrity: sha512-w3Vt4K+O7+nSr9/gFSEfZ1exKUOPSlJaRpnk7Y+XowEhvwT7AIk1HNANH+gETf0zGZ020+hfiMW/Ome+SNCUsg==} + '@commitlint/execute-rule@19.0.0': + resolution: {integrity: sha512-mtsdpY1qyWgAO/iOK0L6gSGeR7GFcdW7tIjcNFxcWkfLDF5qVbPHKuGATFqRMsxcO8OUKNj0+3WOHB7EHm4Jdw==} engines: {node: '>=v18'} - '@commitlint/format@18.1.0': - resolution: {integrity: sha512-So/w217tGWMZZb1yXcUFNF2qFLyYtSVqbnGoMbX8a+JKcG4oB11Gc1adS0ssUOMivtiNpaLtkSHFynyiwtJtiQ==} + '@commitlint/format@19.3.0': + resolution: {integrity: sha512-luguk5/aF68HiF4H23ACAfk8qS8AHxl4LLN5oxPc24H+2+JRPsNr1OS3Gaea0CrH7PKhArBMKBz5RX9sA5NtTg==} engines: {node: '>=v18'} - '@commitlint/is-ignored@18.1.0': - resolution: {integrity: sha512-fa1fY93J/Nx2GH6r6WOLdBOiL7x9Uc1N7wcpmaJ1C5Qs6P+rPSUTkofe2IOhSJIJoboHfAH6W0ru4xtK689t0Q==} + '@commitlint/is-ignored@19.2.2': + resolution: {integrity: sha512-eNX54oXMVxncORywF4ZPFtJoBm3Tvp111tg1xf4zWXGfhBPKpfKG6R+G3G4v5CPlRROXpAOpQ3HMhA9n1Tck1g==} engines: {node: '>=v18'} - '@commitlint/lint@18.1.0': - resolution: {integrity: sha512-LGB3eI5UYu5LLayibNrRM4bSbowr1z9uyqvp0c7+0KaSJi+xHxy/QEhb6fy4bMAtbXEvygY0sUu9HxSWg41rVQ==} + '@commitlint/lint@19.2.2': + resolution: {integrity: sha512-xrzMmz4JqwGyKQKTpFzlN0dx0TAiT7Ran1fqEBgEmEj+PU98crOFtysJgY+QdeSagx6EDRigQIXJVnfrI0ratA==} engines: {node: '>=v18'} - '@commitlint/load@18.2.0': - resolution: {integrity: sha512-xjX3d3CRlOALwImhOsmLYZh14/+gW/KxsY7+bPKrzmGuFailf9K7ckhB071oYZVJdACnpY4hDYiosFyOC+MpAA==} + '@commitlint/load@19.2.0': + resolution: {integrity: sha512-XvxxLJTKqZojCxaBQ7u92qQLFMMZc4+p9qrIq/9kJDy8DOrEa7P1yx7Tjdc2u2JxIalqT4KOGraVgCE7eCYJyQ==} engines: {node: '>=v18'} - '@commitlint/message@18.1.0': - resolution: {integrity: sha512-8dT/jJg73wf3o2Mut/fqEDTpBYSIEVtX5PWyuY/0uviEYeheZAczFo/VMIkeGzhJJn1IrcvAwWsvJ1lVGY2I/w==} + '@commitlint/message@19.0.0': + resolution: {integrity: sha512-c9czf6lU+9oF9gVVa2lmKaOARJvt4soRsVmbR7Njwp9FpbBgste5i7l/2l5o8MmbwGh4yE1snfnsy2qyA2r/Fw==} engines: {node: '>=v18'} - '@commitlint/parse@18.1.0': - resolution: {integrity: sha512-23yv8uBweXWYn8bXk4PjHIsmVA+RkbqPh2h7irupBo2LthVlzMRc4LM6UStasScJ4OlXYYaWOmuP7jcExUF50Q==} + '@commitlint/parse@19.0.3': + resolution: {integrity: sha512-Il+tNyOb8VDxN3P6XoBBwWJtKKGzHlitEuXA5BP6ir/3loWlsSqDr5aecl6hZcC/spjq4pHqNh0qPlfeWu38QA==} engines: {node: '>=v18'} - '@commitlint/read@18.1.0': - resolution: {integrity: sha512-rzfzoKUwxmvYO81tI5o1371Nwt3vhcQR36oTNfupPdU1jgSL3nzBIS3B93LcZh3IYKbCIMyMPN5WZ10BXdeoUg==} + '@commitlint/read@19.2.1': + resolution: {integrity: sha512-qETc4+PL0EUv7Q36lJbPG+NJiBOGg7SSC7B5BsPWOmei+Dyif80ErfWQ0qXoW9oCh7GTpTNRoaVhiI8RbhuaNw==} engines: {node: '>=v18'} - '@commitlint/resolve-extends@18.1.0': - resolution: {integrity: sha512-3mZpzOEJkELt7BbaZp6+bofJyxViyObebagFn0A7IHaLARhPkWTivXdjvZHS12nAORftv88Yhbh8eCPKfSvB7g==} + '@commitlint/resolve-extends@19.1.0': + resolution: {integrity: sha512-z2riI+8G3CET5CPgXJPlzftH+RiWYLMYv4C9tSLdLXdr6pBNimSKukYP9MS27ejmscqCTVA4almdLh0ODD2KYg==} engines: {node: '>=v18'} - '@commitlint/rules@18.1.0': - resolution: {integrity: sha512-VJNQ674CRv4znI0DbsjZLVnn647J+BTxHGcrDIsYv7c99gW7TUGeIe5kL80G7l8+5+N0se8v9yn+Prr8xEy6Yw==} + '@commitlint/rules@19.0.3': + resolution: {integrity: sha512-TspKb9VB6svklxNCKKwxhELn7qhtY1rFF8ls58DcFd0F97XoG07xugPjjbVnLqmMkRjZDbDIwBKt9bddOfLaPw==} engines: {node: '>=v18'} - '@commitlint/to-lines@18.1.0': - resolution: {integrity: sha512-aHIoSDjG0ckxPLYDpODUeSLbEKmF6Jrs1B5JIssbbE9eemBtXtjm9yzdiAx9ZXcwoHlhbTp2fbndDb3YjlvJag==} + '@commitlint/to-lines@19.0.0': + resolution: {integrity: sha512-vkxWo+VQU5wFhiP9Ub9Sre0FYe019JxFikrALVoD5UGa8/t3yOJEpEhxC5xKiENKKhUkTpEItMTRAjHw2SCpZw==} engines: {node: '>=v18'} - '@commitlint/top-level@18.1.0': - resolution: {integrity: sha512-1/USHlolIxJlsfLKecSXH+6PDojIvnzaJGPYwF7MtnTuuXCNQ4izkeqDsRuNMe9nU2VIKpK9OT8Q412kGNmgGw==} + '@commitlint/top-level@19.0.0': + resolution: {integrity: sha512-KKjShd6u1aMGNkCkaX4aG1jOGdn7f8ZI8TR1VEuNqUOjWTOdcDSsmglinglJ18JTjuBX5I1PtjrhQCRcixRVFQ==} engines: {node: '>=v18'} - '@commitlint/types@18.1.0': - resolution: {integrity: sha512-65vGxZmbs+2OVwEItxhp3Ul7X2m2LyLfifYI/NdPwRqblmuES2w2aIRhIjb7cwUIBHHSTT8WXj4ixVHQibmvLQ==} + '@commitlint/types@19.0.3': + resolution: {integrity: sha512-tpyc+7i6bPG9mvaBbtKUeghfyZSDgWquIDfMgqYtTbmZ9Y9VzEm2je9EYcQ0aoz5o7NvGS+rcDec93yO08MHYA==} engines: {node: '>=v18'} + '@es-joy/jsdoccomment@0.43.1': + resolution: {integrity: sha512-I238eDtOolvCuvtxrnqtlBaw0BwdQuYqK7eA6XIonicMdOOOb75mqdIzkGDUbS04+1Di007rgm9snFRNeVrOog==} + engines: {node: '>=16'} + + '@es-joy/jsdoccomment@0.46.0': + resolution: {integrity: sha512-C3Axuq1xd/9VqFZpW4YAzOx5O9q/LP46uIQy/iNDpHG3fmPa6TBtvfglMCs3RBiBxAIi0Go97r8+jvTt55XMyQ==} + engines: {node: '>=16'} + '@eslint-community/eslint-utils@4.4.0': resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - '@eslint-community/regexpp@4.8.1': - resolution: {integrity: sha512-PWiOzLIUAjN/w5K17PoF4n6sKBw0gqLHPhywmYHP4t1VFQQVYeb1yWsJwnMVEMl3tUHME7X/SJPZLmtG7XBDxQ==} + '@eslint-community/regexpp@4.11.0': + resolution: {integrity: sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - '@eslint/eslintrc@2.1.3': - resolution: {integrity: sha512-yZzuIG+jnVu6hNSzFEN07e8BxF3uAzYtQb6uDkaYZLo6oYZDCq454c5kB8zxnzfCYyP4MIuyBn10L0DqwujTmA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@eslint/config-array@0.17.1': + resolution: {integrity: sha512-BlYOpej8AQ8Ev9xVqroV7a02JK3SkBAaN9GfMMH9W6Ch8FlQlkjGw4Ir7+FgYwfirivAf4t+GtzuAxqfukmISA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/js@8.53.0': - resolution: {integrity: sha512-Kn7K8dx/5U6+cT1yEhpX1w4PCSg0M+XyRILPgvwcEBjerFWCwQj5sbr3/VmxqV0JGHCBCzyd6LxypEuehypY1w==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@eslint/eslintrc@3.1.0': + resolution: {integrity: sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@humanwhocodes/config-array@0.11.13': - resolution: {integrity: sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==} - engines: {node: '>=10.10.0'} + '@eslint/js@9.8.0': + resolution: {integrity: sha512-MfluB7EUfxXtv3i/++oh89uzAr4PDI4nn201hsp+qaXqsjAWzinlZEHEfPgAX4doIlKvPG/i0A9dpKxOLII8yA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/object-schema@2.1.4': + resolution: {integrity: sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@humanwhocodes/module-importer@1.0.1': resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} engines: {node: '>=12.22'} - '@humanwhocodes/object-schema@2.0.1': - resolution: {integrity: sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==} + '@humanwhocodes/retry@0.3.0': + resolution: {integrity: sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==} + engines: {node: '>=18.18'} + + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + + '@jsdevtools/ez-spawn@3.0.4': + resolution: {integrity: sha512-f5DRIOZf7wxogefH03RjMPMdBF7ADTWUMoOs9kaJo06EfwF+aFhMZMDZxHg/Xe12hptN9xoZjGso2fdjapBRIA==} + engines: {node: '>=10'} '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} @@ -158,17 +252,164 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@types/minimist@1.2.2': - resolution: {integrity: sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==} + '@pkgr/core@0.1.1': + resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + + '@stylistic/eslint-plugin-js@2.6.1': + resolution: {integrity: sha512-iLOiVzcvqzDGD9U0EuVOX680v+XOPiPAjkxWj+Q6iV2GLOM5NB27tKVOpJY7AzBhidwpRbaLTgg3T4UzYx09jw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: '>=8.40.0' + + '@stylistic/eslint-plugin-jsx@2.6.1': + resolution: {integrity: sha512-5qHLXqxfY6jubAQfDqrifv41fx7gaqA9svDaChxMI6JiHpEBfh+PXxmm3g+B8gJCYVBTC62Rjl0Ny5QabK58bw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: '>=8.40.0' + + '@stylistic/eslint-plugin-plus@2.6.1': + resolution: {integrity: sha512-z/IYu/q8ipApzNam5utSU+BrXg4pK/Gv9xNbr4eWv/bZppvTWJU62xCO4nw/6r2dHNPnqc7uCHEC7GMlBnPY0A==} + peerDependencies: + eslint: '*' + + '@stylistic/eslint-plugin-ts@2.6.1': + resolution: {integrity: sha512-Mxl1VMorEG1Hc6oBYPD0+KIJOWkjEF1R0liL7wWgKfwpqOkgmnh5lVdZBrYyfRKOE4RlGcwEFTNai1IW6orgVg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: '>=8.40.0' + + '@stylistic/eslint-plugin@2.6.1': + resolution: {integrity: sha512-UT0f4t+3sQ/GKW7875NiIIjZJ1Bh4gd7JNfoIkwIQyWqO7wGd0Pqzu0Ho30Ka8MNF5lm++SkVeqAk26vGxoUpg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: '>=8.40.0' + + '@types/conventional-commits-parser@5.0.0': + resolution: {integrity: sha512-loB369iXNmAZglwWATL+WRe+CRMmmBPtpolYzIebFaX4YA3x+BEfLqhUAV9WanycKI3TG1IMr5bMJDajDKLlUQ==} + + '@types/eslint@8.56.11': + resolution: {integrity: sha512-sVBpJMf7UPo/wGecYOpk2aQya2VUGeHhe38WG7/mN5FufNSubf5VT9Uh9Uyp8/eLJpu1/tuhJ/qTo4mhSB4V4Q==} + + '@types/eslint@9.6.0': + resolution: {integrity: sha512-gi6WQJ7cHRgZxtkQEoyHMppPjq9Kxo5Tjn2prSKDSmZrCz8TZ3jSRCeTJm+WoM+oB0WG37bRqLzaaU3q7JypGg==} + + '@types/estree@1.0.5': + resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/mdast@3.0.15': + resolution: {integrity: sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==} '@types/node@18.18.8': resolution: {integrity: sha512-OLGBaaK5V3VRBS1bAkMVP2/W9B+H8meUfl866OrMNQqt7wDgdpWPp5o6gmIc9pB+lIQHSq4ZL8ypeH1vPxcPaQ==} - '@types/normalize-package-data@2.4.1': - resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} + '@types/normalize-package-data@2.4.4': + resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} + + '@types/unist@2.0.10': + resolution: {integrity: sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==} + + '@typescript-eslint/eslint-plugin@8.0.0': + resolution: {integrity: sha512-STIZdwEQRXAHvNUS6ILDf5z3u95Gc8jzywunxSNqX00OooIemaaNIA0vEgynJlycL5AjabYLLrIyHd4iazyvtg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 + eslint: ^8.57.0 || ^9.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/parser@8.0.0': + resolution: {integrity: sha512-pS1hdZ+vnrpDIxuFXYQpLTILglTjSYJ9MbetZctrUawogUsPdz31DIIRZ9+rab0LhYNTsk88w4fIzVheiTbWOQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/scope-manager@7.18.0': + resolution: {integrity: sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==} + engines: {node: ^18.18.0 || >=20.0.0} + + '@typescript-eslint/scope-manager@8.0.0': + resolution: {integrity: sha512-V0aa9Csx/ZWWv2IPgTfY7T4agYwJyILESu/PVqFtTFz9RIS823mAze+NbnBI8xiwdX3iqeQbcTYlvB04G9wyQw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/type-utils@8.0.0': + resolution: {integrity: sha512-mJAFP2mZLTBwAn5WI4PMakpywfWFH5nQZezUQdSKV23Pqo6o9iShQg1hP2+0hJJXP2LnZkWPphdIq4juYYwCeg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/types@7.18.0': + resolution: {integrity: sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==} + engines: {node: ^18.18.0 || >=20.0.0} + + '@typescript-eslint/types@8.0.0': + resolution: {integrity: sha512-wgdSGs9BTMWQ7ooeHtu5quddKKs5Z5dS+fHLbrQI+ID0XWJLODGMHRfhwImiHoeO2S5Wir2yXuadJN6/l4JRxw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@7.18.0': + resolution: {integrity: sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/typescript-estree@8.0.0': + resolution: {integrity: sha512-5b97WpKMX+Y43YKi4zVcCVLtK5F98dFls3Oxui8LbnmRsseKenbbDinmvxrWegKDMmlkIq/XHuyy0UGLtpCDKg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/utils@7.18.0': + resolution: {integrity: sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + eslint: ^8.56.0 + + '@typescript-eslint/utils@8.0.0': + resolution: {integrity: sha512-k/oS/A/3QeGLRvOWCg6/9rATJL5rec7/5s1YmdS0ZU6LHveJyGFwBvLhSRBv6i9xaj7etmosp+l+ViN1I9Aj/Q==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + + '@typescript-eslint/visitor-keys@7.18.0': + resolution: {integrity: sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==} + engines: {node: ^18.18.0 || >=20.0.0} + + '@typescript-eslint/visitor-keys@8.0.0': + resolution: {integrity: sha512-oN0K4nkHuOyF3PVMyETbpP5zp6wfyOvm7tWhTMfoqxSSsPmJIh6JNASuZDlODE8eE+0EB9uar+6+vxr9DBTYOA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@vue/compiler-core@3.4.35': + resolution: {integrity: sha512-gKp0zGoLnMYtw4uS/SJRRO7rsVggLjvot3mcctlMXunYNsX+aRJDqqw/lV5/gHK91nvaAAlWFgdVl020AW1Prg==} + + '@vue/compiler-dom@3.4.35': + resolution: {integrity: sha512-pWIZRL76/oE/VMhdv/ovZfmuooEni6JPG1BFe7oLk5DZRo/ImydXijoZl/4kh2406boRQ7lxTYzbZEEXEhj9NQ==} + + '@vue/compiler-sfc@3.4.35': + resolution: {integrity: sha512-xacnRS/h/FCsjsMfxBkzjoNxyxEyKyZfBch/P4vkLRvYJwe5ChXmZZrj8Dsed/752H2Q3JE8kYu9Uyha9J6PgA==} + + '@vue/compiler-ssr@3.4.35': + resolution: {integrity: sha512-7iynB+0KB1AAJKk/biENTV5cRGHRdbdaD7Mx3nWcm1W8bVD6QmnH3B4AHhQQ1qZHhqFwzEzMwiytXm3PX1e60A==} - '@ungap/structured-clone@1.2.0': - resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + '@vue/shared@3.4.35': + resolution: {integrity: sha512-hvuhBYYDe+b1G8KHxsQ0diDqDMA8D9laxWZhNAjE83VZb5UDaXl9Xnz7cGdDSyiHM90qqI/CyGMcpBpiDy6VVQ==} JSONStream@1.3.5: resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} @@ -179,8 +420,8 @@ packages: peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - acorn@8.10.0: - resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==} + acorn@8.12.1: + resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==} engines: {node: '>=0.4.0'} hasBin: true @@ -190,9 +431,9 @@ packages: ajv@8.12.0: resolution: {integrity: sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==} - ansi-escapes@5.0.0: - resolution: {integrity: sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA==} - engines: {node: '>=12'} + ansi-escapes@7.0.0: + resolution: {integrity: sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==} + engines: {node: '>=18'} ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} @@ -214,38 +455,55 @@ packages: resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} engines: {node: '>=12'} + are-docs-informative@0.0.2: + resolution: {integrity: sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==} + engines: {node: '>=14'} + argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} array-ify@1.0.0: resolution: {integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==} - arrify@1.0.1: - resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==} - engines: {node: '>=0.10.0'} + array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} - braces@3.0.2: - resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} - callsites@3.1.0: - resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + browserslist@4.23.3: + resolution: {integrity: sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + builtin-modules@3.3.0: + resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} engines: {node: '>=6'} - camelcase-keys@6.2.2: - resolution: {integrity: sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==} - engines: {node: '>=8'} + call-me-maybe@1.0.2: + resolution: {integrity: sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==} - camelcase@5.3.1: - resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} + caniuse-lite@1.0.30001647: + resolution: {integrity: sha512-n83xdNiyeNcHpzWY+1aFbqCK7LuLfBricc4+alSQL2Xb6OR3XpnQAmlDG+pQcdTfiHRuLcQ96VOfrPSGiNJYSg==} + chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} engines: {node: '>=4'} @@ -258,13 +516,30 @@ packages: resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - cli-cursor@4.0.0: - resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + character-entities-legacy@1.1.4: + resolution: {integrity: sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==} - cli-truncate@3.1.0: - resolution: {integrity: sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + character-entities@1.2.4: + resolution: {integrity: sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==} + + character-reference-invalid@1.1.4: + resolution: {integrity: sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==} + + ci-info@4.0.0: + resolution: {integrity: sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg==} + engines: {node: '>=8'} + + clean-regexp@1.0.0: + resolution: {integrity: sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==} + engines: {node: '>=4'} + + cli-cursor@5.0.0: + resolution: {integrity: sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==} + engines: {node: '>=18'} + + cli-truncate@4.0.0: + resolution: {integrity: sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==} + engines: {node: '>=18'} cliui@8.0.1: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} @@ -286,9 +561,13 @@ packages: colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} - commander@11.1.0: - resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} - engines: {node: '>=16'} + commander@12.1.0: + resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} + engines: {node: '>=18'} + + comment-parser@1.4.1: + resolution: {integrity: sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==} + engines: {node: '>= 12.0.0'} compare-func@2.0.0: resolution: {integrity: sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==} @@ -296,9 +575,12 @@ packages: concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - conventional-changelog-angular@6.0.0: - resolution: {integrity: sha512-6qLgrBF4gueoC7AFVHu51nHL9pF9FRjXrH+ceVf7WmAfH3gs+gEYOkvxhjMPjZu57I4AGUGoNTY8V7Hrgf1uqg==} - engines: {node: '>=14'} + confbox@0.1.7: + resolution: {integrity: sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==} + + conventional-changelog-angular@7.0.0: + resolution: {integrity: sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==} + engines: {node: '>=16'} conventional-changelog-conventionalcommits@7.0.2: resolution: {integrity: sha512-NKXYmMR/Hr1DevQegFB4MwfM5Vv0m4UIxKZTTYuD98lpTknaZlSRrDOG4X7wIXpGkfsYxZTghUN+Qq+T0YQI7w==} @@ -309,6 +591,9 @@ packages: engines: {node: '>=16'} hasBin: true + core-js-compat@3.38.0: + resolution: {integrity: sha512-75LAicdLa4OJVwFxFbQR3NdnZjNgX6ILpVcVzcC4T2smerB5lELMrJQQQoWV6TiuC/vlaFqgU2tKQx9w5s0e0A==} + cosmiconfig-typescript-loader@5.0.0: resolution: {integrity: sha512-+8cK7jRAReYkMwMiG+bxhcNKiHJDM6bR9FD/nGBXOWdMLuYawjF5cGrtLilJ+LGd3ZjCXnJjR5DkfWPoIVlqJA==} engines: {node: '>=v16'} @@ -317,8 +602,8 @@ packages: cosmiconfig: '>=8.2' typescript: '>=4' - cosmiconfig@8.3.6: - resolution: {integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==} + cosmiconfig@9.0.0: + resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==} engines: {node: '>=14'} peerDependencies: typescript: '>=4.9.5' @@ -330,9 +615,22 @@ packages: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} - dargs@7.0.0: - resolution: {integrity: sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==} - engines: {node: '>=8'} + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + + dargs@8.1.0: + resolution: {integrity: sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw==} + engines: {node: '>=12'} + + debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true debug@4.3.4: resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} @@ -343,17 +641,22 @@ packages: supports-color: optional: true - decamelize-keys@1.1.1: - resolution: {integrity: sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==} - engines: {node: '>=0.10.0'} - - decamelize@1.2.0: - resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} - engines: {node: '>=0.10.0'} + debug@4.3.6: + resolution: {integrity: sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + doctrine@3.0.0: resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} engines: {node: '>=6.0.0'} @@ -362,22 +665,45 @@ packages: resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} engines: {node: '>=8'} - eastasianwidth@0.2.0: - resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + electron-to-chromium@1.5.4: + resolution: {integrity: sha512-orzA81VqLyIGUEA77YkVA1D+N+nNfl2isJVjjmOyrlxuooZ19ynb+dOlaDTqd/idKRS9lDCSBmtzM+kyCsMnkA==} + + emoji-regex@10.3.0: + resolution: {integrity: sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==} emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - emoji-regex@9.2.2: - resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + enhanced-resolve@5.17.1: + resolution: {integrity: sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==} + engines: {node: '>=10.13.0'} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + env-paths@2.2.1: + resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} + engines: {node: '>=6'} + + environment@1.1.0: + resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==} + engines: {node: '>=18'} error-ex@1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + es-module-lexer@1.5.4: + resolution: {integrity: sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==} + escalade@3.1.1: resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} engines: {node: '>=6'} + escalade@3.1.2: + resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} + engines: {node: '>=6'} + escape-string-regexp@1.0.5: resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} engines: {node: '>=0.8.0'} @@ -386,31 +712,189 @@ packages: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} - eslint-compat-utils@0.1.2: - resolution: {integrity: sha512-Jia4JDldWnFNIru1Ehx1H5s9/yxiRHY/TimCuUc0jNexew3cF1gI6CYZil1ociakfWO3rRqFjl1mskBblB3RYg==} + eslint-compat-utils@0.5.1: + resolution: {integrity: sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==} engines: {node: '>=12'} peerDependencies: eslint: '>=6.0.0' - eslint-plugin-yml@1.10.0: - resolution: {integrity: sha512-53SUwuNDna97lVk38hL/5++WXDuugPM9SUQ1T645R0EHMRCdBIIxGye/oOX2qO3FQ7aImxaUZJU/ju+NMUBrLQ==} + eslint-config-flat-gitignore@0.1.8: + resolution: {integrity: sha512-OEUbS2wzzYtUfshjOqzFo4Bl4lHykXUdM08TCnYNl7ki+niW4Q1R0j0FDFDr0vjVsI5ZFOz5LvluxOP+Ew+dYw==} + + eslint-flat-config-utils@0.3.0: + resolution: {integrity: sha512-FaFQLUunAl6YK7aU/pT23DXYVWg/cEHbSfxwAxpCGT6Su8H9RfkmzKLh1G2bba46p6dTlQeA4VTiV5//0SeToQ==} + + eslint-import-resolver-node@0.3.9: + resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} + + eslint-merge-processors@0.1.0: + resolution: {integrity: sha512-IvRXXtEajLeyssvW4wJcZ2etxkR9mUf4zpNwgI+m/Uac9RfXHskuJefkHUcawVzePnd6xp24enp5jfgdHzjRdQ==} + peerDependencies: + eslint: '*' + + eslint-plugin-antfu@2.3.4: + resolution: {integrity: sha512-5RIjJpBK1tuNHuLyFyZ90/iW9s439dP1u2cxA4dH70djx9sKq1CqI+O6Q95aVjgFNTDtQzSC9uYdAD5uEEKciQ==} + peerDependencies: + eslint: '*' + + eslint-plugin-command@0.2.3: + resolution: {integrity: sha512-1bBYNfjZg60N2ZpLV5ATYSYyueIJ+zl5yKrTs0UFDdnyu07dNSZ7Xplnc+Wb6SXTdc1sIaoIrnuyhvztcltX6A==} + peerDependencies: + eslint: '*' + + eslint-plugin-es-x@7.8.0: + resolution: {integrity: sha512-7Ds8+wAAoV3T+LAKeu39Y5BzXCrGKrcISfgKEqTS4BDN8SFEDQd0S43jiQ8vIa3wUKD07qitZdfzlenSi8/0qQ==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + eslint: '>=8' + + eslint-plugin-eslint-comments@3.2.0: + resolution: {integrity: sha512-0jkOl0hfojIHHmEHgmNdqv4fmh7300NdpA9FFpF7zaoLvB/QeXOGNLIo86oAveJFrfB1p05kC8hpEMHM8DwWVQ==} + engines: {node: '>=6.5.0'} + peerDependencies: + eslint: '>=4.19.1' + + eslint-plugin-import-x@3.1.0: + resolution: {integrity: sha512-/UbPA+bYY7nIxcjL3kpcDY3UNdoLHFhyBFzHox2M0ypcUoueTn6woZUUmzzi5et/dXChksasYYFeKE2wshOrhg==} + engines: {node: '>=16'} + peerDependencies: + eslint: ^8.56.0 || ^9.0.0-0 + + eslint-plugin-jsdoc@48.11.0: + resolution: {integrity: sha512-d12JHJDPNo7IFwTOAItCeJY1hcqoIxE0lHA8infQByLilQ9xkqrRa6laWCnsuCrf+8rUnvxXY1XuTbibRBNylA==} + engines: {node: '>=18'} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 + + eslint-plugin-jsonc@2.16.0: + resolution: {integrity: sha512-Af/ZL5mgfb8FFNleH6KlO4/VdmDuTqmM+SPnWcdoWywTetv7kq+vQe99UyQb9XO3b0OWLVuTH7H0d/PXYCMdSg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '>=6.0.0' + + eslint-plugin-markdown@5.1.0: + resolution: {integrity: sha512-SJeyKko1K6GwI0AN6xeCDToXDkfKZfXcexA6B+O2Wr2btUS9GrC+YgwSyVli5DJnctUHjFXcQ2cqTaAmVoLi2A==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: '>=8' + + eslint-plugin-n@17.10.1: + resolution: {integrity: sha512-hm/q37W6efDptJXdwirsm6A257iY6ZNtpoSG0wEzFzjJ3AhL7OhEIhdSR2e4OdYfHO5EDeqlCfFrjf9q208IPw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: '>=8.23.0' + + eslint-plugin-no-only-tests@3.1.0: + resolution: {integrity: sha512-Lf4YW/bL6Un1R6A76pRZyE1dl1vr31G/ev8UzIc/geCgFWyrKil8hVjYqWVKGB/UIGmb6Slzs9T0wNezdSVegw==} + engines: {node: '>=5.0.0'} + + eslint-plugin-perfectionist@3.1.1: + resolution: {integrity: sha512-joaAPd2gVNV+Gm+xU6tqOxy9WlBcb/6TSCUaHLNSdhot/KcsyiKSzeTVToasrCPIxgqgGwcOy+AJaGaBhBwblw==} + engines: {node: ^18.0.0 || >=20.0.0} + peerDependencies: + astro-eslint-parser: ^1.0.2 + eslint: '>=8.0.0' + svelte: '>=3.0.0' + svelte-eslint-parser: ^0.40.0 + vue-eslint-parser: '>=9.0.0' + peerDependenciesMeta: + astro-eslint-parser: + optional: true + svelte: + optional: true + svelte-eslint-parser: + optional: true + vue-eslint-parser: + optional: true + + eslint-plugin-regexp@2.6.0: + resolution: {integrity: sha512-FCL851+kislsTEQEMioAlpDuK5+E5vs0hi1bF8cFlPlHcEjeRhuAzEsGikXRreE+0j4WhW2uO54MqTjXtYOi3A==} + engines: {node: ^18 || >=20} + peerDependencies: + eslint: '>=8.44.0' + + eslint-plugin-toml@0.11.1: + resolution: {integrity: sha512-Y1WuMSzfZpeMIrmlP1nUh3kT8p96mThIq4NnHrYUhg10IKQgGfBZjAWnrg9fBqguiX4iFps/x/3Hb5TxBisfdw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '>=6.0.0' + + eslint-plugin-unicorn@55.0.0: + resolution: {integrity: sha512-n3AKiVpY2/uDcGrS3+QsYDkjPfaOrNrsfQxU9nt5nitd9KuvVXrfAvgCO9DYPSfap+Gqjw9EOrXIsBp5tlHZjA==} + engines: {node: '>=18.18'} + peerDependencies: + eslint: '>=8.56.0' + + eslint-plugin-unused-imports@4.0.1: + resolution: {integrity: sha512-rax76s05z64uQgG9YXsWFmXrgjkaK79AvfeAWiSxhPP6RVGxeRaj4+2u+wxxu/mDy2pmJoOy1QTOEALMia2xGQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/eslint-plugin': ^8.0.0-0 + eslint: ^9.0.0 + peerDependenciesMeta: + '@typescript-eslint/eslint-plugin': + optional: true + + eslint-plugin-vitest@0.5.4: + resolution: {integrity: sha512-um+odCkccAHU53WdKAw39MY61+1x990uXjSPguUCq3VcEHdqJrOb8OTMrbYlY6f9jAKx7x98kLVlIe3RJeJqoQ==} + engines: {node: ^18.0.0 || >= 20.0.0} + peerDependencies: + '@typescript-eslint/eslint-plugin': '*' + eslint: ^8.57.0 || ^9.0.0 + vitest: '*' + peerDependenciesMeta: + '@typescript-eslint/eslint-plugin': + optional: true + vitest: + optional: true + + eslint-plugin-vue@9.27.0: + resolution: {integrity: sha512-5Dw3yxEyuBSXTzT5/Ge1X5kIkRTQ3nvBn/VwPwInNiZBSJOO/timWMUaflONnFBzU6NhB68lxnCda7ULV5N7LA==} + engines: {node: ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.2.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 + + eslint-plugin-yml@1.14.0: + resolution: {integrity: sha512-ESUpgYPOcAYQO9czugcX5OqRvn/ydDVwGCPXY4YjPqc09rHaUVUA6IE6HLQys4rXk/S+qx3EwTd1wHCwam/OWQ==} engines: {node: ^14.17.0 || >=16.0.0} peerDependencies: eslint: '>=6.0.0' + eslint-processor-vue-blocks@0.1.2: + resolution: {integrity: sha512-PfpJ4uKHnqeL/fXUnzYkOax3aIenlwewXRX8jFinA1a2yCFnLgMuiH3xvCgvHHUlV2xJWQHbCTdiJWGwb3NqpQ==} + peerDependencies: + '@vue/compiler-sfc': ^3.3.0 + eslint: ^8.50.0 || ^9.0.0 + + eslint-rule-composer@0.3.0: + resolution: {integrity: sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg==} + engines: {node: '>=4.0.0'} + eslint-scope@7.2.2: resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + eslint-scope@8.0.2: + resolution: {integrity: sha512-6E4xmrTw5wtxnLA5wYL3WDfhZ/1bUBGOXV0zQvVRDOtrR8D0p6W7fs3JweNYhwRYeGvd/1CKX2se0/2s7Q/nJA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + eslint-visitor-keys@3.4.3: resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - eslint@8.53.0: - resolution: {integrity: sha512-N4VuiPjXDUa4xVeV/GC/RV3hQW9Nw+Y463lkWaKKXKYMvmRiRDAtfpuPFLN+E1/6ZhyR8J2ig+eVREnYgUsiag==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + eslint-visitor-keys@4.0.0: + resolution: {integrity: sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint@9.8.0: + resolution: {integrity: sha512-K8qnZ/QJzT2dLKdZJVX6W4XOwBzutMYmt0lqUS+JdXgd+HTYFlonFgkJ8s44d/zMPPCnOOk0kMWCApCPhiOy9A==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true + espree@10.1.0: + resolution: {integrity: sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + espree@9.6.1: resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -419,6 +903,10 @@ packages: resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} engines: {node: '>=0.10'} + esquery@1.6.0: + resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} + engines: {node: '>=0.10'} + esrecurse@4.3.0: resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} engines: {node: '>=4.0'} @@ -427,6 +915,9 @@ packages: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} engines: {node: '>=4.0'} + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + esutils@2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} @@ -434,10 +925,6 @@ packages: eventemitter3@5.0.1: resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} - execa@5.1.1: - resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} - engines: {node: '>=10'} - execa@8.0.1: resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} engines: {node: '>=16.17'} @@ -445,6 +932,10 @@ packages: fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + fast-glob@3.3.2: + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} + engines: {node: '>=8.6.0'} + fast-json-stable-stringify@2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} @@ -454,14 +945,18 @@ packages: fastq@1.15.0: resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} - file-entry-cache@6.0.1: - resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} - engines: {node: ^10.12.0 || >=12.0.0} + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} - fill-range@7.0.1: - resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} + find-up-simple@1.0.0: + resolution: {integrity: sha512-q7Us7kcjj2VMePAa02hDAF6d+MzsdsAWEwYyOpwUtlerRBkOEPBCRZrAV4XfcSN8fHAgaD0hP7miwoay6DCprw==} + engines: {node: '>=18'} + find-up@4.1.0: resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} engines: {node: '>=8'} @@ -470,65 +965,74 @@ packages: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} - flat-cache@3.1.0: - resolution: {integrity: sha512-OHx4Qwrrt0E4jEIcI5/Xb+f+QmJYNj2rrK8wiIdQOIrB9WrrJL8cjZvXdXuBTkkEwEqLycb5BeZDV1o2i9bTew==} - engines: {node: '>=12.0.0'} + find-up@7.0.0: + resolution: {integrity: sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==} + engines: {node: '>=18'} + + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} flatted@3.2.9: resolution: {integrity: sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==} - fs-extra@11.1.1: - resolution: {integrity: sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==} - engines: {node: '>=14.14'} - - fs.realpath@1.0.0: - resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} - - function-bind@1.1.1: - resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} get-caller-file@2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} - get-stream@6.0.1: - resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} - engines: {node: '>=10'} + get-east-asian-width@1.2.0: + resolution: {integrity: sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==} + engines: {node: '>=18'} get-stream@8.0.1: resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} engines: {node: '>=16'} - git-raw-commits@2.0.11: - resolution: {integrity: sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==} - engines: {node: '>=10'} + get-tsconfig@4.7.6: + resolution: {integrity: sha512-ZAqrLlu18NbDdRaHq+AKXzAmqIUPswPWKUchfytdAjiRFnCe5ojG2bstg6mRiZabkKfCoL/e98pbBELIV/YCeA==} + + git-raw-commits@4.0.0: + resolution: {integrity: sha512-ICsMM1Wk8xSGMowkOmPrzo2Fgmfo4bMHLNX6ytHjajRJUqvHOw/TFapQ+QG75c3X/tTDDhOSRPGC52dDbNM8FQ==} + engines: {node: '>=16'} hasBin: true + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + glob-parent@6.0.2: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} - glob@7.2.3: - resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - - global-dirs@0.1.1: - resolution: {integrity: sha512-NknMLn7F2J7aflwFOlGdNIuCDpN3VGoSoB+aap3KABFWbHVn1TCgFC+np23J8W2BiZbjfEw3BFBycSMv1AFblg==} - engines: {node: '>=4'} + global-directory@4.0.1: + resolution: {integrity: sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==} + engines: {node: '>=18'} - globals@13.21.0: - resolution: {integrity: sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==} + globals@13.24.0: + resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} engines: {node: '>=8'} + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + + globals@15.9.0: + resolution: {integrity: sha512-SmSKyLLKFbSr6rptvP8izbyxJL4ILwqO9Jg23UA0sDlGlu58V59D1//I3vlc0KJphVdUR7vMjHIplYnzBxorQA==} + engines: {node: '>=18'} + + globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - hard-rejection@2.1.0: - resolution: {integrity: sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==} - engines: {node: '>=6'} - has-flag@3.0.0: resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} engines: {node: '>=4'} @@ -537,38 +1041,37 @@ packages: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} - has@1.0.3: - resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} - engines: {node: '>= 0.4.0'} + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} hosted-git-info@2.8.9: resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} - hosted-git-info@4.1.0: - resolution: {integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==} - engines: {node: '>=10'} - - human-signals@2.1.0: - resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} - engines: {node: '>=10.17.0'} - human-signals@5.0.0: resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} engines: {node: '>=16.17.0'} - husky@8.0.3: - resolution: {integrity: sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==} - engines: {node: '>=14'} + husky@9.1.4: + resolution: {integrity: sha512-bho94YyReb4JV7LYWRWxZ/xr6TtOTt8cMfmQ39MQYJ7f/YE268s3GdghGwi+y4zAeqewE5zYLvuhV0M0ijsDEA==} + engines: {node: '>=18'} hasBin: true ignore@5.2.4: resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} engines: {node: '>= 4'} + ignore@5.3.1: + resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} + engines: {node: '>= 4'} + import-fresh@3.3.0: resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} engines: {node: '>=6'} + import-meta-resolve@4.1.0: + resolution: {integrity: sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==} + imurmurhash@0.1.4: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} @@ -577,23 +1080,32 @@ packages: resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} engines: {node: '>=8'} - inflight@1.0.6: - resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + ini@4.1.1: + resolution: {integrity: sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + is-alphabetical@1.0.4: + resolution: {integrity: sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==} - ini@1.3.8: - resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + is-alphanumerical@1.0.4: + resolution: {integrity: sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==} is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - is-core-module@2.13.0: - resolution: {integrity: sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==} + is-builtin-module@3.2.1: + resolution: {integrity: sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==} + engines: {node: '>=6'} - is-extglob@2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + is-core-module@2.15.0: + resolution: {integrity: sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==} + engines: {node: '>= 0.4'} + + is-decimal@1.0.4: + resolution: {integrity: sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} is-fullwidth-code-point@3.0.0: @@ -604,10 +1116,17 @@ packages: resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} engines: {node: '>=12'} + is-fullwidth-code-point@5.0.0: + resolution: {integrity: sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==} + engines: {node: '>=18'} + is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} + is-hexadecimal@1.0.4: + resolution: {integrity: sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==} + is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} @@ -620,14 +1139,6 @@ packages: resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} engines: {node: '>=8'} - is-plain-obj@1.1.0: - resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==} - engines: {node: '>=0.10.0'} - - is-stream@2.0.1: - resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} - engines: {node: '>=8'} - is-stream@3.0.0: resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -650,6 +1161,19 @@ packages: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true + jsdoc-type-pratt-parser@4.0.0: + resolution: {integrity: sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ==} + engines: {node: '>=12.0.0'} + + jsesc@0.5.0: + resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} + hasBin: true + + jsesc@3.0.2: + resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} + engines: {node: '>=6'} + hasBin: true + json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} @@ -665,39 +1189,40 @@ packages: json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - jsonfile@6.1.0: - resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + jsonc-eslint-parser@2.4.0: + resolution: {integrity: sha512-WYDyuc/uFcGp6YtM2H0uKmUwieOuzeE/5YocFJLnLfclZ4inf3mRn8ZVy1s7Hxji7Jxm6Ss8gqpexD/GlKoGgg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} jsonparse@1.3.1: resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} engines: {'0': node >= 0.2.0} - keyv@4.5.3: - resolution: {integrity: sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==} - - kind-of@6.0.3: - resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} - engines: {node: '>=0.10.0'} + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} - lilconfig@2.1.0: - resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} - engines: {node: '>=10'} + lilconfig@3.1.2: + resolution: {integrity: sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==} + engines: {node: '>=14'} lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - lint-staged@15.0.2: - resolution: {integrity: sha512-vnEy7pFTHyVuDmCAIFKR5QDO8XLVlPFQQyujQ/STOxe40ICWqJ6knS2wSJ/ffX/Lw0rz83luRDh+ET7toN+rOw==} + lint-staged@15.2.8: + resolution: {integrity: sha512-PUWFf2zQzsd9EFU+kM1d7UP+AZDbKFKuj+9JNVTBkhUFhbg4MAt6WfyMMwBfM4lYqd4D2Jwac5iuTu9rVj4zCQ==} engines: {node: '>=18.12.0'} hasBin: true - listr2@7.0.2: - resolution: {integrity: sha512-rJysbR9GKIalhTbVL2tYbF2hVyDnrf7pFUZBwjPaMIdadYHmeT+EVi/Bu3qd7ETQPahTotg2WRCatXwRBW554g==} - engines: {node: '>=16.0.0'} + listr2@8.2.4: + resolution: {integrity: sha512-opevsywziHd3zHCVQGAj8zu+Z3yHNkkoYhWIGnq54RrCVwLz0MozotJEDnKsIBLvkfLGN6BLOyAeRrYI0pKA4g==} + engines: {node: '>=18.0.0'} + + local-pkg@0.5.0: + resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==} + engines: {node: '>=14'} locate-path@5.0.0: resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} @@ -707,12 +1232,13 @@ packages: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} + locate-path@7.2.0: + resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + lodash.camelcase@4.3.0: resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} - lodash.isfunction@3.0.9: - resolution: {integrity: sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==} - lodash.isplainobject@4.0.6: resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} @@ -740,91 +1266,105 @@ packages: lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - log-update@5.0.1: - resolution: {integrity: sha512-5UtUDQ/6edw4ofyljDNcOVJQ4c7OjDro4h3y8e1GQL5iYElYclVHJ3zeWchylvMaKnDbDilC8irOVyexnA/Slw==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + log-update@6.1.0: + resolution: {integrity: sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==} + engines: {node: '>=18'} lru-cache@6.0.0: resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} engines: {node: '>=10'} - map-obj@1.0.1: - resolution: {integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==} - engines: {node: '>=0.10.0'} + magic-string@0.30.11: + resolution: {integrity: sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==} - map-obj@4.3.0: - resolution: {integrity: sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==} - engines: {node: '>=8'} + mdast-util-from-markdown@0.8.5: + resolution: {integrity: sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==} + + mdast-util-to-string@2.0.0: + resolution: {integrity: sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==} meow@12.1.1: resolution: {integrity: sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==} engines: {node: '>=16.10'} - meow@8.1.2: - resolution: {integrity: sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==} - engines: {node: '>=10'} - merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} - micromatch@4.0.5: - resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} - engines: {node: '>=8.6'} + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} - mimic-fn@2.1.0: - resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} - engines: {node: '>=6'} + micromark@2.11.4: + resolution: {integrity: sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==} + + micromatch@4.0.7: + resolution: {integrity: sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==} + engines: {node: '>=8.6'} mimic-fn@4.0.0: resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} engines: {node: '>=12'} + mimic-function@5.0.1: + resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==} + engines: {node: '>=18'} + min-indent@1.0.1: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} engines: {node: '>=4'} + minimatch@10.0.1: + resolution: {integrity: sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==} + engines: {node: 20 || >=22} + minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - minimist-options@4.1.0: - resolution: {integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==} - engines: {node: '>= 6'} + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + mlly@1.7.1: + resolution: {integrity: sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==} + ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + natural-compare-lite@1.4.0: + resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} + natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + node-releases@2.0.18: + resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} + normalize-package-data@2.5.0: resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} - normalize-package-data@3.0.3: - resolution: {integrity: sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==} - engines: {node: '>=10'} - - npm-run-path@4.0.1: - resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} - engines: {node: '>=8'} - npm-run-path@5.1.0: resolution: {integrity: sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - - onetime@5.1.2: - resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} - engines: {node: '>=6'} + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} onetime@6.0.0: resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} engines: {node: '>=12'} + onetime@7.0.0: + resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==} + engines: {node: '>=18'} + optionator@0.9.3: resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} engines: {node: '>= 0.8.0'} @@ -837,6 +1377,10 @@ packages: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} + p-limit@4.0.0: + resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + p-locate@4.1.0: resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} engines: {node: '>=8'} @@ -845,6 +1389,10 @@ packages: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} + p-locate@6.0.0: + resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + p-try@2.2.0: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} @@ -853,6 +1401,17 @@ packages: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} + parse-entities@2.0.0: + resolution: {integrity: sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==} + + parse-gitignore@2.0.0: + resolution: {integrity: sha512-RmVuCHWsfu0QPNW+mraxh/xjQVw/lhUCUru8Zni3Ctq3AoMhpDTq0OVdKS6iesd6Kqb7viCV3isAL43dciOSog==} + engines: {node: '>=14'} + + parse-imports@2.1.1: + resolution: {integrity: sha512-TDT4HqzUiTMO1wJRwg/t/hYk8Wdp3iF/ToMIlAoVQfL1Xs/sTxq1dKWSMjMbQmIarfWKymOyly40+zmPHXMqCA==} + engines: {node: '>= 18'} + parse-json@5.2.0: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} @@ -861,9 +1420,9 @@ packages: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} - path-is-absolute@1.0.1: - resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} - engines: {node: '>=0.10.0'} + path-exists@5.0.0: + resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} @@ -880,15 +1439,40 @@ packages: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} + pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + + picocolors@1.0.1: + resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} + picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} + picomatch@4.0.2: + resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} + engines: {node: '>=12'} + pidtree@0.6.0: resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==} engines: {node: '>=0.10'} hasBin: true + pkg-types@1.1.3: + resolution: {integrity: sha512-+JrgthZG6m3ckicaOB74TwQ+tBWsFl3qVQg7mN8ulwSOElJ7gBhKzj2VkCPnZ4NlF6kEquYU+RIYNVAvzd54UA==} + + pluralize@8.0.0: + resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} + engines: {node: '>=4'} + + postcss-selector-parser@6.1.1: + resolution: {integrity: sha512-b4dlw/9V8A71rLIDsSwVmak9z2DuBUB7CA1/wSdelNEzqsjoSPeADTWNO09lpH49Diy3/JIZ2bSPB1dI3LJCHg==} + engines: {node: '>=4'} + + postcss@8.4.40: + resolution: {integrity: sha512-YF2kKIUzAofPMpfH6hOi2cGnv/HrUlfucspc7pDyvv7kGdqXrfj8SCl/t8owkEgKEuu8ZcRjSOxFxVLqwChZ2Q==} + engines: {node: ^10 || ^12 || >=14} + prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} @@ -900,10 +1484,6 @@ packages: queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - quick-lru@4.0.1: - resolution: {integrity: sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==} - engines: {node: '>=8'} - read-pkg-up@7.0.1: resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} engines: {node: '>=8'} @@ -912,13 +1492,21 @@ packages: resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==} engines: {node: '>=8'} - readable-stream@3.6.2: - resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} - engines: {node: '>= 6'} + refa@0.12.1: + resolution: {integrity: sha512-J8rn6v4DBb2nnFqkqwy6/NnTYMcgLA+sLr0iIO41qpv0n+ngb7ksag2tMRl0inb1bbO/esUwzW1vbJi7K0sI0g==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - redent@3.0.0: - resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} - engines: {node: '>=8'} + regexp-ast-analysis@0.7.1: + resolution: {integrity: sha512-sZuz1dYW/ZsfG17WSAG7eS85r5a0dDsvg+7BiiYR5o6lKCAtUrEwdmRmaGF6rwVj3LcmAeYkOWKEPlbPzN3Y3A==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + regexp-tree@0.1.27: + resolution: {integrity: sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==} + hasBin: true + + regjsparser@0.10.0: + resolution: {integrity: sha512-qx+xQGZVsy55CH0a1hiVwHmqjLryfh7wQyF5HO07XJ9f7dQMY/gPQHhlyDkIzJKC+x2fUCpCcUODUUUFrm7SHA==} + hasBin: true require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} @@ -936,34 +1524,30 @@ packages: resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} engines: {node: '>=8'} - resolve-global@1.0.0: - resolution: {integrity: sha512-zFa12V4OLtT5XUX/Q4VLvTfBf+Ok0SPc1FNGM/z9ctUdiU618qwKpWnd0CHs3+RqROfyEg/DhuHbMWYqcgljEw==} - engines: {node: '>=8'} + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} - resolve@1.22.6: - resolution: {integrity: sha512-njhxM7mV12JfufShqGy3Rz8j11RPdLy4xi15UurGJeoHLfJpVXKdh3ueuOqbYUcDZnffr6X739JBo5LzyahEsw==} + resolve@1.22.8: + resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} hasBin: true - restore-cursor@4.0.0: - resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + restore-cursor@5.1.0: + resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==} + engines: {node: '>=18'} reusify@1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - rfdc@1.3.0: - resolution: {integrity: sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==} - - rimraf@3.0.2: - resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} - hasBin: true + rfdc@1.4.1: + resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - safe-buffer@5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + scslre@0.3.0: + resolution: {integrity: sha512-3A6sD0WYP7+QrjbfNA2FN3FsOaGGFoekCVgTyypy53gPxhbkCIjtO6YWgdrfM+n/8sI8JeXZOIxsHjMTNxQ4nQ==} + engines: {node: ^14.0.0 || >=16.0.0} semver@5.7.2: resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} @@ -974,6 +1558,11 @@ packages: engines: {node: '>=10'} hasBin: true + semver@7.6.3: + resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} + engines: {node: '>=10'} + hasBin: true + shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -982,36 +1571,54 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} - signal-exit@3.0.7: - resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} - signal-exit@4.1.0: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} + sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + slashes@3.0.12: + resolution: {integrity: sha512-Q9VME8WyGkc7pJf6QEkj3wE+2CnvZMI+XJhwdTPR8Z/kWQRXi7boAWLDibRPyHRTUTPx5FaU7MsyrjI3yLB4HA==} + slice-ansi@5.0.0: resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} engines: {node: '>=12'} + slice-ansi@7.1.0: + resolution: {integrity: sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==} + engines: {node: '>=18'} + + source-map-js@1.2.0: + resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} + engines: {node: '>=0.10.0'} + spdx-correct@3.2.0: resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} - spdx-exceptions@2.3.0: - resolution: {integrity: sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==} + spdx-exceptions@2.5.0: + resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==} spdx-expression-parse@3.0.1: resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} - spdx-license-ids@3.0.14: - resolution: {integrity: sha512-U0eS5wcpu/O2/QZk6PcAMOA8H3ZuvRe4mFHA3Q+LNl1SRDmfQ+mD3RoD6tItqnvqubJ32m/zV2Z/ikSmxccD1Q==} + spdx-expression-parse@4.0.0: + resolution: {integrity: sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==} - split2@3.2.2: - resolution: {integrity: sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==} + spdx-license-ids@3.0.18: + resolution: {integrity: sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==} split2@4.2.0: resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} engines: {node: '>= 10.x'} + stable-hash@0.0.4: + resolution: {integrity: sha512-LjdcbuBeLcdETCrPn9i8AYAZ1eCtu4ECAWtP7UleOiZ9LzVxRzzUZEoZ8zB24nhkQnDWyET0I+3sWokSDS3E7g==} + string-argv@0.3.2: resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} engines: {node: '>=0.6.19'} @@ -1020,12 +1627,9 @@ packages: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} - string-width@5.1.2: - resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} - engines: {node: '>=12'} - - string_decoder@1.3.0: - resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + string-width@7.2.0: + resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} + engines: {node: '>=18'} strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} @@ -1035,10 +1639,6 @@ packages: resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} engines: {node: '>=12'} - strip-final-newline@2.0.0: - resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} - engines: {node: '>=6'} - strip-final-newline@3.0.0: resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} engines: {node: '>=12'} @@ -1063,6 +1663,18 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} + synckit@0.6.2: + resolution: {integrity: sha512-Vhf+bUa//YSTYKseDiiEuQmhGCoIF3CVBhunm3r/DQnYiGT4JssmnKQc44BIyOZRK2pKjXXAgbhfmbeoC9CJpA==} + engines: {node: '>=12.20'} + + synckit@0.9.1: + resolution: {integrity: sha512-7gr8p9TQP6RAHusBOSLs46F4564ZrjV8xFmw5zCmgmhGUcw2hxsShhJ6CEiHQMgPDwAQ1fWHPM0ypc4RMAig4A==} + engines: {node: ^14.18.0 || >=16.0.0} + + tapable@2.2.1: + resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} + engines: {node: '>=6'} + text-extensions@2.4.0: resolution: {integrity: sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==} engines: {node: '>=8'} @@ -1070,27 +1682,37 @@ packages: text-table@0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} - through2@4.0.2: - resolution: {integrity: sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==} - through@2.3.8: resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} - trim-newlines@3.0.1: - resolution: {integrity: sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==} - engines: {node: '>=8'} + toml-eslint-parser@0.10.0: + resolution: {integrity: sha512-khrZo4buq4qVmsGzS5yQjKe/WsFvV8fGfOjDQN0q4iy9FjRfPWRgTFrU8u1R2iu/SfWLhY9WnCi4Jhdrcbtg+g==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + ts-api-utils@1.3.0: + resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==} + engines: {node: '>=16'} + peerDependencies: + typescript: '>=4.2.0' + + tslib@2.6.3: + resolution: {integrity: sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==} type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} - type-fest@0.18.1: - resolution: {integrity: sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==} - engines: {node: '>=10'} + type-detect@4.1.0: + resolution: {integrity: sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==} + engines: {node: '>=4'} type-fest@0.20.2: resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} @@ -1104,21 +1726,29 @@ packages: resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} engines: {node: '>=8'} - type-fest@1.4.0: - resolution: {integrity: sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==} - engines: {node: '>=10'} - typescript@5.2.2: resolution: {integrity: sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==} engines: {node: '>=14.17'} hasBin: true + ufo@1.5.4: + resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} + undici-types@5.26.5: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} - universalify@2.0.0: - resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==} - engines: {node: '>= 10.0.0'} + unicorn-magic@0.1.0: + resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==} + engines: {node: '>=18'} + + unist-util-stringify-position@2.0.3: + resolution: {integrity: sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==} + + update-browserslist-db@1.1.0: + resolution: {integrity: sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} @@ -1129,6 +1759,12 @@ packages: validate-npm-package-license@3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + vue-eslint-parser@9.4.3: + resolution: {integrity: sha512-2rYRLWlIpaiN8xbPiDyXZXRgLGOtWxERV7ND5fFAv5qo1D2N9Fu9MNajBNc6o13lZ+24DAWCkQCvj4klgmcITg==} + engines: {node: ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '>=6.0.0' + which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} @@ -1138,12 +1774,13 @@ packages: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} - wrap-ansi@8.1.0: - resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} - engines: {node: '>=12'} + wrap-ansi@9.0.0: + resolution: {integrity: sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==} + engines: {node: '>=18'} - wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + xml-name-validator@4.0.0: + resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} + engines: {node: '>=12'} y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} @@ -1152,21 +1789,18 @@ packages: yallist@4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} - yaml-eslint-parser@1.2.2: - resolution: {integrity: sha512-pEwzfsKbTrB8G3xc/sN7aw1v6A6c/pKxLAkjclnAyo5g5qOh6eL9WGu0o3cSDQZKrTNk4KL4lQSwZW+nBkANEg==} + yaml-eslint-parser@1.2.3: + resolution: {integrity: sha512-4wZWvE398hCP7O8n3nXKu/vdq1HcH01ixYlCREaJL5NUMwQ0g3MaGFUBNSlmBtKmhbtVG/Cm6lyYmSVTEVil8A==} engines: {node: ^14.17.0 || >=16.0.0} - yaml@2.3.2: - resolution: {integrity: sha512-N/lyzTPaJasoDmfV7YTrYCI0G/3ivm/9wdG0aHuheKowWQwGTsK0Eoiw6utmzAnI6pkJa0DUVygvp3spqqEKXg==} - engines: {node: '>= 14'} - yaml@2.3.3: resolution: {integrity: sha512-zw0VAJxgeZ6+++/su5AFoqBbZbrEakwu+X0M5HmcwUiBL7AzcuPKjj5we4xfQLp78LkEMpD0cOnUhmgOVy3KdQ==} engines: {node: '>= 14'} - yargs-parser@20.2.9: - resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} - engines: {node: '>=10'} + yaml@2.5.0: + resolution: {integrity: sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw==} + engines: {node: '>= 14'} + hasBin: true yargs-parser@21.1.1: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} @@ -1180,148 +1814,250 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} + yocto-queue@1.1.1: + resolution: {integrity: sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==} + engines: {node: '>=12.20'} + snapshots: '@aashutoshrathi/word-wrap@1.2.6': {} + '@antfu/eslint-config@2.24.1(@vue/compiler-sfc@3.4.35)(eslint@9.8.0)(typescript@5.2.2)': + dependencies: + '@antfu/install-pkg': 0.3.3 + '@clack/prompts': 0.7.0 + '@stylistic/eslint-plugin': 2.6.1(eslint@9.8.0)(typescript@5.2.2) + '@typescript-eslint/eslint-plugin': 8.0.0(@typescript-eslint/parser@8.0.0(eslint@9.8.0)(typescript@5.2.2))(eslint@9.8.0)(typescript@5.2.2) + '@typescript-eslint/parser': 8.0.0(eslint@9.8.0)(typescript@5.2.2) + eslint: 9.8.0 + eslint-config-flat-gitignore: 0.1.8 + eslint-flat-config-utils: 0.3.0 + eslint-merge-processors: 0.1.0(eslint@9.8.0) + eslint-plugin-antfu: 2.3.4(eslint@9.8.0) + eslint-plugin-command: 0.2.3(eslint@9.8.0) + eslint-plugin-eslint-comments: 3.2.0(eslint@9.8.0) + eslint-plugin-import-x: 3.1.0(eslint@9.8.0)(typescript@5.2.2) + eslint-plugin-jsdoc: 48.11.0(eslint@9.8.0) + eslint-plugin-jsonc: 2.16.0(eslint@9.8.0) + eslint-plugin-markdown: 5.1.0(eslint@9.8.0) + eslint-plugin-n: 17.10.1(eslint@9.8.0) + eslint-plugin-no-only-tests: 3.1.0 + eslint-plugin-perfectionist: 3.1.1(eslint@9.8.0)(typescript@5.2.2)(vue-eslint-parser@9.4.3(eslint@9.8.0)) + eslint-plugin-regexp: 2.6.0(eslint@9.8.0) + eslint-plugin-toml: 0.11.1(eslint@9.8.0) + eslint-plugin-unicorn: 55.0.0(eslint@9.8.0) + eslint-plugin-unused-imports: 4.0.1(@typescript-eslint/eslint-plugin@8.0.0(@typescript-eslint/parser@8.0.0(eslint@9.8.0)(typescript@5.2.2))(eslint@9.8.0)(typescript@5.2.2))(eslint@9.8.0) + eslint-plugin-vitest: 0.5.4(@typescript-eslint/eslint-plugin@8.0.0(@typescript-eslint/parser@8.0.0(eslint@9.8.0)(typescript@5.2.2))(eslint@9.8.0)(typescript@5.2.2))(eslint@9.8.0)(typescript@5.2.2) + eslint-plugin-vue: 9.27.0(eslint@9.8.0) + eslint-plugin-yml: 1.14.0(eslint@9.8.0) + eslint-processor-vue-blocks: 0.1.2(@vue/compiler-sfc@3.4.35)(eslint@9.8.0) + globals: 15.9.0 + jsonc-eslint-parser: 2.4.0 + local-pkg: 0.5.0 + parse-gitignore: 2.0.0 + picocolors: 1.0.1 + toml-eslint-parser: 0.10.0 + vue-eslint-parser: 9.4.3(eslint@9.8.0) + yaml-eslint-parser: 1.2.3 + yargs: 17.7.2 + transitivePeerDependencies: + - '@vue/compiler-sfc' + - supports-color + - svelte + - typescript + - vitest + + '@antfu/install-pkg@0.3.3': + dependencies: + '@jsdevtools/ez-spawn': 3.0.4 + + '@antfu/utils@0.7.10': {} + '@babel/code-frame@7.22.13': dependencies: '@babel/highlight': 7.22.20 chalk: 2.4.2 + '@babel/helper-string-parser@7.24.8': {} + '@babel/helper-validator-identifier@7.22.20': {} + '@babel/helper-validator-identifier@7.24.7': {} + '@babel/highlight@7.22.20': dependencies: '@babel/helper-validator-identifier': 7.22.20 chalk: 2.4.2 js-tokens: 4.0.0 - '@commitlint/cli@18.2.0(typescript@5.2.2)': + '@babel/parser@7.25.3': dependencies: - '@commitlint/format': 18.1.0 - '@commitlint/lint': 18.1.0 - '@commitlint/load': 18.2.0(typescript@5.2.2) - '@commitlint/read': 18.1.0 - '@commitlint/types': 18.1.0 - execa: 5.1.1 - lodash.isfunction: 3.0.9 - resolve-from: 5.0.0 - resolve-global: 1.0.0 + '@babel/types': 7.25.2 + + '@babel/types@7.25.2': + dependencies: + '@babel/helper-string-parser': 7.24.8 + '@babel/helper-validator-identifier': 7.24.7 + to-fast-properties: 2.0.0 + + '@clack/core@0.3.4': + dependencies: + picocolors: 1.0.1 + sisteransi: 1.0.5 + + '@clack/prompts@0.7.0': + dependencies: + '@clack/core': 0.3.4 + picocolors: 1.0.1 + sisteransi: 1.0.5 + + '@commitlint/cli@19.3.0(@types/node@18.18.8)(typescript@5.2.2)': + dependencies: + '@commitlint/format': 19.3.0 + '@commitlint/lint': 19.2.2 + '@commitlint/load': 19.2.0(@types/node@18.18.8)(typescript@5.2.2) + '@commitlint/read': 19.2.1 + '@commitlint/types': 19.0.3 + execa: 8.0.1 yargs: 17.7.2 transitivePeerDependencies: + - '@types/node' - typescript - '@commitlint/config-conventional@18.1.0': + '@commitlint/config-conventional@19.2.2': dependencies: + '@commitlint/types': 19.0.3 conventional-changelog-conventionalcommits: 7.0.2 - '@commitlint/config-validator@18.1.0': + '@commitlint/config-validator@19.0.3': dependencies: - '@commitlint/types': 18.1.0 + '@commitlint/types': 19.0.3 ajv: 8.12.0 - '@commitlint/ensure@18.1.0': + '@commitlint/ensure@19.0.3': dependencies: - '@commitlint/types': 18.1.0 + '@commitlint/types': 19.0.3 lodash.camelcase: 4.3.0 lodash.kebabcase: 4.1.1 lodash.snakecase: 4.1.1 lodash.startcase: 4.4.0 lodash.upperfirst: 4.3.1 - '@commitlint/execute-rule@18.1.0': {} + '@commitlint/execute-rule@19.0.0': {} - '@commitlint/format@18.1.0': + '@commitlint/format@19.3.0': dependencies: - '@commitlint/types': 18.1.0 - chalk: 4.1.2 + '@commitlint/types': 19.0.3 + chalk: 5.3.0 - '@commitlint/is-ignored@18.1.0': + '@commitlint/is-ignored@19.2.2': dependencies: - '@commitlint/types': 18.1.0 - semver: 7.5.4 + '@commitlint/types': 19.0.3 + semver: 7.6.3 - '@commitlint/lint@18.1.0': + '@commitlint/lint@19.2.2': dependencies: - '@commitlint/is-ignored': 18.1.0 - '@commitlint/parse': 18.1.0 - '@commitlint/rules': 18.1.0 - '@commitlint/types': 18.1.0 + '@commitlint/is-ignored': 19.2.2 + '@commitlint/parse': 19.0.3 + '@commitlint/rules': 19.0.3 + '@commitlint/types': 19.0.3 - '@commitlint/load@18.2.0(typescript@5.2.2)': + '@commitlint/load@19.2.0(@types/node@18.18.8)(typescript@5.2.2)': dependencies: - '@commitlint/config-validator': 18.1.0 - '@commitlint/execute-rule': 18.1.0 - '@commitlint/resolve-extends': 18.1.0 - '@commitlint/types': 18.1.0 - '@types/node': 18.18.8 - chalk: 4.1.2 - cosmiconfig: 8.3.6(typescript@5.2.2) - cosmiconfig-typescript-loader: 5.0.0(@types/node@18.18.8)(cosmiconfig@8.3.6)(typescript@5.2.2) + '@commitlint/config-validator': 19.0.3 + '@commitlint/execute-rule': 19.0.0 + '@commitlint/resolve-extends': 19.1.0 + '@commitlint/types': 19.0.3 + chalk: 5.3.0 + cosmiconfig: 9.0.0(typescript@5.2.2) + cosmiconfig-typescript-loader: 5.0.0(@types/node@18.18.8)(cosmiconfig@9.0.0(typescript@5.2.2))(typescript@5.2.2) lodash.isplainobject: 4.0.6 lodash.merge: 4.6.2 lodash.uniq: 4.5.0 - resolve-from: 5.0.0 transitivePeerDependencies: + - '@types/node' - typescript - '@commitlint/message@18.1.0': {} + '@commitlint/message@19.0.0': {} - '@commitlint/parse@18.1.0': + '@commitlint/parse@19.0.3': dependencies: - '@commitlint/types': 18.1.0 - conventional-changelog-angular: 6.0.0 + '@commitlint/types': 19.0.3 + conventional-changelog-angular: 7.0.0 conventional-commits-parser: 5.0.0 - '@commitlint/read@18.1.0': + '@commitlint/read@19.2.1': dependencies: - '@commitlint/top-level': 18.1.0 - '@commitlint/types': 18.1.0 - fs-extra: 11.1.1 - git-raw-commits: 2.0.11 + '@commitlint/top-level': 19.0.0 + '@commitlint/types': 19.0.3 + execa: 8.0.1 + git-raw-commits: 4.0.0 minimist: 1.2.8 - '@commitlint/resolve-extends@18.1.0': + '@commitlint/resolve-extends@19.1.0': dependencies: - '@commitlint/config-validator': 18.1.0 - '@commitlint/types': 18.1.0 - import-fresh: 3.3.0 + '@commitlint/config-validator': 19.0.3 + '@commitlint/types': 19.0.3 + global-directory: 4.0.1 + import-meta-resolve: 4.1.0 lodash.mergewith: 4.6.2 resolve-from: 5.0.0 - resolve-global: 1.0.0 - '@commitlint/rules@18.1.0': + '@commitlint/rules@19.0.3': dependencies: - '@commitlint/ensure': 18.1.0 - '@commitlint/message': 18.1.0 - '@commitlint/to-lines': 18.1.0 - '@commitlint/types': 18.1.0 - execa: 5.1.1 + '@commitlint/ensure': 19.0.3 + '@commitlint/message': 19.0.0 + '@commitlint/to-lines': 19.0.0 + '@commitlint/types': 19.0.3 + execa: 8.0.1 - '@commitlint/to-lines@18.1.0': {} + '@commitlint/to-lines@19.0.0': {} - '@commitlint/top-level@18.1.0': + '@commitlint/top-level@19.0.0': dependencies: - find-up: 5.0.0 + find-up: 7.0.0 - '@commitlint/types@18.1.0': + '@commitlint/types@19.0.3': dependencies: - chalk: 4.1.2 + '@types/conventional-commits-parser': 5.0.0 + chalk: 5.3.0 - '@eslint-community/eslint-utils@4.4.0(eslint@8.53.0)': + '@es-joy/jsdoccomment@0.43.1': dependencies: - eslint: 8.53.0 + '@types/eslint': 8.56.11 + '@types/estree': 1.0.5 + '@typescript-eslint/types': 7.18.0 + comment-parser: 1.4.1 + esquery: 1.5.0 + jsdoc-type-pratt-parser: 4.0.0 + + '@es-joy/jsdoccomment@0.46.0': + dependencies: + comment-parser: 1.4.1 + esquery: 1.6.0 + jsdoc-type-pratt-parser: 4.0.0 + + '@eslint-community/eslint-utils@4.4.0(eslint@9.8.0)': + dependencies: + eslint: 9.8.0 eslint-visitor-keys: 3.4.3 - '@eslint-community/regexpp@4.8.1': {} + '@eslint-community/regexpp@4.11.0': {} - '@eslint/eslintrc@2.1.3': + '@eslint/config-array@0.17.1': + dependencies: + '@eslint/object-schema': 2.1.4 + debug: 4.3.4 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@eslint/eslintrc@3.1.0': dependencies: ajv: 6.12.6 debug: 4.3.4 - espree: 9.6.1 - globals: 13.21.0 + espree: 10.1.0 + globals: 14.0.0 ignore: 5.2.4 import-fresh: 3.3.0 js-yaml: 4.1.0 @@ -1330,19 +2066,22 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/js@8.53.0': {} + '@eslint/js@9.8.0': {} - '@humanwhocodes/config-array@0.11.13': - dependencies: - '@humanwhocodes/object-schema': 2.0.1 - debug: 4.3.4 - minimatch: 3.1.2 - transitivePeerDependencies: - - supports-color + '@eslint/object-schema@2.1.4': {} '@humanwhocodes/module-importer@1.0.1': {} - '@humanwhocodes/object-schema@2.0.1': {} + '@humanwhocodes/retry@0.3.0': {} + + '@jridgewell/sourcemap-codec@1.5.0': {} + + '@jsdevtools/ez-spawn@3.0.4': + dependencies: + call-me-maybe: 1.0.2 + cross-spawn: 7.0.3 + string-argv: 0.3.2 + type-detect: 4.1.0 '@nodelib/fs.scandir@2.1.5': dependencies: @@ -1356,26 +2095,246 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.15.0 - '@types/minimist@1.2.2': {} + '@pkgr/core@0.1.1': {} + + '@stylistic/eslint-plugin-js@2.6.1(eslint@9.8.0)': + dependencies: + '@types/eslint': 9.6.0 + acorn: 8.12.1 + eslint: 9.8.0 + eslint-visitor-keys: 4.0.0 + espree: 10.1.0 + + '@stylistic/eslint-plugin-jsx@2.6.1(eslint@9.8.0)': + dependencies: + '@stylistic/eslint-plugin-js': 2.6.1(eslint@9.8.0) + '@types/eslint': 9.6.0 + eslint: 9.8.0 + estraverse: 5.3.0 + picomatch: 4.0.2 + + '@stylistic/eslint-plugin-plus@2.6.1(eslint@9.8.0)(typescript@5.2.2)': + dependencies: + '@types/eslint': 9.6.0 + '@typescript-eslint/utils': 8.0.0(eslint@9.8.0)(typescript@5.2.2) + eslint: 9.8.0 + transitivePeerDependencies: + - supports-color + - typescript + + '@stylistic/eslint-plugin-ts@2.6.1(eslint@9.8.0)(typescript@5.2.2)': + dependencies: + '@stylistic/eslint-plugin-js': 2.6.1(eslint@9.8.0) + '@types/eslint': 9.6.0 + '@typescript-eslint/utils': 8.0.0(eslint@9.8.0)(typescript@5.2.2) + eslint: 9.8.0 + transitivePeerDependencies: + - supports-color + - typescript + + '@stylistic/eslint-plugin@2.6.1(eslint@9.8.0)(typescript@5.2.2)': + dependencies: + '@stylistic/eslint-plugin-js': 2.6.1(eslint@9.8.0) + '@stylistic/eslint-plugin-jsx': 2.6.1(eslint@9.8.0) + '@stylistic/eslint-plugin-plus': 2.6.1(eslint@9.8.0)(typescript@5.2.2) + '@stylistic/eslint-plugin-ts': 2.6.1(eslint@9.8.0)(typescript@5.2.2) + '@types/eslint': 9.6.0 + eslint: 9.8.0 + transitivePeerDependencies: + - supports-color + - typescript + + '@types/conventional-commits-parser@5.0.0': + dependencies: + '@types/node': 18.18.8 + + '@types/eslint@8.56.11': + dependencies: + '@types/estree': 1.0.5 + '@types/json-schema': 7.0.15 + + '@types/eslint@9.6.0': + dependencies: + '@types/estree': 1.0.5 + '@types/json-schema': 7.0.15 + + '@types/estree@1.0.5': {} + + '@types/json-schema@7.0.15': {} + + '@types/mdast@3.0.15': + dependencies: + '@types/unist': 2.0.10 '@types/node@18.18.8': dependencies: undici-types: 5.26.5 - '@types/normalize-package-data@2.4.1': {} + '@types/normalize-package-data@2.4.4': {} - '@ungap/structured-clone@1.2.0': {} + '@types/unist@2.0.10': {} + + '@typescript-eslint/eslint-plugin@8.0.0(@typescript-eslint/parser@8.0.0(eslint@9.8.0)(typescript@5.2.2))(eslint@9.8.0)(typescript@5.2.2)': + dependencies: + '@eslint-community/regexpp': 4.11.0 + '@typescript-eslint/parser': 8.0.0(eslint@9.8.0)(typescript@5.2.2) + '@typescript-eslint/scope-manager': 8.0.0 + '@typescript-eslint/type-utils': 8.0.0(eslint@9.8.0)(typescript@5.2.2) + '@typescript-eslint/utils': 8.0.0(eslint@9.8.0)(typescript@5.2.2) + '@typescript-eslint/visitor-keys': 8.0.0 + eslint: 9.8.0 + graphemer: 1.4.0 + ignore: 5.3.1 + natural-compare: 1.4.0 + ts-api-utils: 1.3.0(typescript@5.2.2) + optionalDependencies: + typescript: 5.2.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.0.0(eslint@9.8.0)(typescript@5.2.2)': + dependencies: + '@typescript-eslint/scope-manager': 8.0.0 + '@typescript-eslint/types': 8.0.0 + '@typescript-eslint/typescript-estree': 8.0.0(typescript@5.2.2) + '@typescript-eslint/visitor-keys': 8.0.0 + debug: 4.3.6 + eslint: 9.8.0 + optionalDependencies: + typescript: 5.2.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@7.18.0': + dependencies: + '@typescript-eslint/types': 7.18.0 + '@typescript-eslint/visitor-keys': 7.18.0 + + '@typescript-eslint/scope-manager@8.0.0': + dependencies: + '@typescript-eslint/types': 8.0.0 + '@typescript-eslint/visitor-keys': 8.0.0 + + '@typescript-eslint/type-utils@8.0.0(eslint@9.8.0)(typescript@5.2.2)': + dependencies: + '@typescript-eslint/typescript-estree': 8.0.0(typescript@5.2.2) + '@typescript-eslint/utils': 8.0.0(eslint@9.8.0)(typescript@5.2.2) + debug: 4.3.6 + ts-api-utils: 1.3.0(typescript@5.2.2) + optionalDependencies: + typescript: 5.2.2 + transitivePeerDependencies: + - eslint + - supports-color + + '@typescript-eslint/types@7.18.0': {} + + '@typescript-eslint/types@8.0.0': {} + + '@typescript-eslint/typescript-estree@7.18.0(typescript@5.2.2)': + dependencies: + '@typescript-eslint/types': 7.18.0 + '@typescript-eslint/visitor-keys': 7.18.0 + debug: 4.3.6 + globby: 11.1.0 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.6.3 + ts-api-utils: 1.3.0(typescript@5.2.2) + optionalDependencies: + typescript: 5.2.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/typescript-estree@8.0.0(typescript@5.2.2)': + dependencies: + '@typescript-eslint/types': 8.0.0 + '@typescript-eslint/visitor-keys': 8.0.0 + debug: 4.3.6 + globby: 11.1.0 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.6.3 + ts-api-utils: 1.3.0(typescript@5.2.2) + optionalDependencies: + typescript: 5.2.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@7.18.0(eslint@9.8.0)(typescript@5.2.2)': + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@9.8.0) + '@typescript-eslint/scope-manager': 7.18.0 + '@typescript-eslint/types': 7.18.0 + '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.2.2) + eslint: 9.8.0 + transitivePeerDependencies: + - supports-color + - typescript + + '@typescript-eslint/utils@8.0.0(eslint@9.8.0)(typescript@5.2.2)': + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@9.8.0) + '@typescript-eslint/scope-manager': 8.0.0 + '@typescript-eslint/types': 8.0.0 + '@typescript-eslint/typescript-estree': 8.0.0(typescript@5.2.2) + eslint: 9.8.0 + transitivePeerDependencies: + - supports-color + - typescript + + '@typescript-eslint/visitor-keys@7.18.0': + dependencies: + '@typescript-eslint/types': 7.18.0 + eslint-visitor-keys: 3.4.3 + + '@typescript-eslint/visitor-keys@8.0.0': + dependencies: + '@typescript-eslint/types': 8.0.0 + eslint-visitor-keys: 3.4.3 + + '@vue/compiler-core@3.4.35': + dependencies: + '@babel/parser': 7.25.3 + '@vue/shared': 3.4.35 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.2.0 + + '@vue/compiler-dom@3.4.35': + dependencies: + '@vue/compiler-core': 3.4.35 + '@vue/shared': 3.4.35 + + '@vue/compiler-sfc@3.4.35': + dependencies: + '@babel/parser': 7.25.3 + '@vue/compiler-core': 3.4.35 + '@vue/compiler-dom': 3.4.35 + '@vue/compiler-ssr': 3.4.35 + '@vue/shared': 3.4.35 + estree-walker: 2.0.2 + magic-string: 0.30.11 + postcss: 8.4.40 + source-map-js: 1.2.0 + + '@vue/compiler-ssr@3.4.35': + dependencies: + '@vue/compiler-dom': 3.4.35 + '@vue/shared': 3.4.35 + + '@vue/shared@3.4.35': {} JSONStream@1.3.5: dependencies: jsonparse: 1.3.1 through: 2.3.8 - acorn-jsx@5.3.2(acorn@8.10.0): + acorn-jsx@5.3.2(acorn@8.12.1): dependencies: - acorn: 8.10.0 + acorn: 8.12.1 - acorn@8.10.0: {} + acorn@8.12.1: {} ajv@6.12.6: dependencies: @@ -1391,9 +2350,9 @@ snapshots: require-from-string: 2.0.2 uri-js: 4.4.1 - ansi-escapes@5.0.0: + ansi-escapes@7.0.0: dependencies: - type-fest: 1.4.0 + environment: 1.1.0 ansi-regex@5.0.1: {} @@ -1409,32 +2368,45 @@ snapshots: ansi-styles@6.2.1: {} + are-docs-informative@0.0.2: {} + argparse@2.0.1: {} array-ify@1.0.0: {} - arrify@1.0.1: {} + array-union@2.1.0: {} balanced-match@1.0.2: {} + boolbase@1.0.0: {} + brace-expansion@1.1.11: dependencies: balanced-match: 1.0.2 concat-map: 0.0.1 - braces@3.0.2: + brace-expansion@2.0.1: dependencies: - fill-range: 7.0.1 + balanced-match: 1.0.2 - callsites@3.1.0: {} + braces@3.0.3: + dependencies: + fill-range: 7.1.1 - camelcase-keys@6.2.2: + browserslist@4.23.3: dependencies: - camelcase: 5.3.1 - map-obj: 4.3.0 - quick-lru: 4.0.1 + caniuse-lite: 1.0.30001647 + electron-to-chromium: 1.5.4 + node-releases: 2.0.18 + update-browserslist-db: 1.1.0(browserslist@4.23.3) + + builtin-modules@3.3.0: {} - camelcase@5.3.1: {} + call-me-maybe@1.0.2: {} + + callsites@3.1.0: {} + + caniuse-lite@1.0.30001647: {} chalk@2.4.2: dependencies: @@ -1449,14 +2421,26 @@ snapshots: chalk@5.3.0: {} - cli-cursor@4.0.0: + character-entities-legacy@1.1.4: {} + + character-entities@1.2.4: {} + + character-reference-invalid@1.1.4: {} + + ci-info@4.0.0: {} + + clean-regexp@1.0.0: + dependencies: + escape-string-regexp: 1.0.5 + + cli-cursor@5.0.0: dependencies: - restore-cursor: 4.0.0 + restore-cursor: 5.1.0 - cli-truncate@3.1.0: + cli-truncate@4.0.0: dependencies: slice-ansi: 5.0.0 - string-width: 5.1.2 + string-width: 7.2.0 cliui@8.0.1: dependencies: @@ -1478,7 +2462,9 @@ snapshots: colorette@2.0.20: {} - commander@11.1.0: {} + commander@12.1.0: {} + + comment-parser@1.4.1: {} compare-func@2.0.0: dependencies: @@ -1487,7 +2473,9 @@ snapshots: concat-map@0.0.1: {} - conventional-changelog-angular@6.0.0: + confbox@0.1.7: {} + + conventional-changelog-angular@7.0.0: dependencies: compare-func: 2.0.0 @@ -1502,120 +2490,354 @@ snapshots: meow: 12.1.1 split2: 4.2.0 - cosmiconfig-typescript-loader@5.0.0(@types/node@18.18.8)(cosmiconfig@8.3.6)(typescript@5.2.2): + core-js-compat@3.38.0: + dependencies: + browserslist: 4.23.3 + + cosmiconfig-typescript-loader@5.0.0(@types/node@18.18.8)(cosmiconfig@9.0.0(typescript@5.2.2))(typescript@5.2.2): dependencies: '@types/node': 18.18.8 - cosmiconfig: 8.3.6(typescript@5.2.2) + cosmiconfig: 9.0.0(typescript@5.2.2) jiti: 1.21.0 typescript: 5.2.2 - cosmiconfig@8.3.6(typescript@5.2.2): + cosmiconfig@9.0.0(typescript@5.2.2): dependencies: + env-paths: 2.2.1 import-fresh: 3.3.0 js-yaml: 4.1.0 parse-json: 5.2.0 - path-type: 4.0.0 + optionalDependencies: typescript: 5.2.2 - cross-spawn@7.0.3: + cross-spawn@7.0.3: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + cssesc@3.0.0: {} + + dargs@8.1.0: {} + + debug@3.2.7: + dependencies: + ms: 2.1.2 + + debug@4.3.4: + dependencies: + ms: 2.1.2 + + debug@4.3.6: + dependencies: + ms: 2.1.2 + + deep-is@0.1.4: {} + + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + + doctrine@3.0.0: + dependencies: + esutils: 2.0.3 + + dot-prop@5.3.0: + dependencies: + is-obj: 2.0.0 + + electron-to-chromium@1.5.4: {} + + emoji-regex@10.3.0: {} + + emoji-regex@8.0.0: {} + + enhanced-resolve@5.17.1: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.2.1 + + entities@4.5.0: {} + + env-paths@2.2.1: {} + + environment@1.1.0: {} + + error-ex@1.3.2: + dependencies: + is-arrayish: 0.2.1 + + es-module-lexer@1.5.4: {} + + escalade@3.1.1: {} + + escalade@3.1.2: {} + + escape-string-regexp@1.0.5: {} + + escape-string-regexp@4.0.0: {} + + eslint-compat-utils@0.5.1(eslint@9.8.0): + dependencies: + eslint: 9.8.0 + semver: 7.5.4 + + eslint-config-flat-gitignore@0.1.8: + dependencies: + find-up-simple: 1.0.0 + parse-gitignore: 2.0.0 + + eslint-flat-config-utils@0.3.0: + dependencies: + '@types/eslint': 9.6.0 + pathe: 1.1.2 + + eslint-import-resolver-node@0.3.9: + dependencies: + debug: 3.2.7 + is-core-module: 2.15.0 + resolve: 1.22.8 + transitivePeerDependencies: + - supports-color + + eslint-merge-processors@0.1.0(eslint@9.8.0): + dependencies: + eslint: 9.8.0 + + eslint-plugin-antfu@2.3.4(eslint@9.8.0): dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 + '@antfu/utils': 0.7.10 + eslint: 9.8.0 - dargs@7.0.0: {} + eslint-plugin-command@0.2.3(eslint@9.8.0): + dependencies: + '@es-joy/jsdoccomment': 0.43.1 + eslint: 9.8.0 - debug@4.3.4: + eslint-plugin-es-x@7.8.0(eslint@9.8.0): dependencies: - ms: 2.1.2 + '@eslint-community/eslint-utils': 4.4.0(eslint@9.8.0) + '@eslint-community/regexpp': 4.11.0 + eslint: 9.8.0 + eslint-compat-utils: 0.5.1(eslint@9.8.0) - decamelize-keys@1.1.1: + eslint-plugin-eslint-comments@3.2.0(eslint@9.8.0): dependencies: - decamelize: 1.2.0 - map-obj: 1.0.1 + escape-string-regexp: 1.0.5 + eslint: 9.8.0 + ignore: 5.2.4 - decamelize@1.2.0: {} + eslint-plugin-import-x@3.1.0(eslint@9.8.0)(typescript@5.2.2): + dependencies: + '@typescript-eslint/utils': 7.18.0(eslint@9.8.0)(typescript@5.2.2) + debug: 4.3.6 + doctrine: 3.0.0 + eslint: 9.8.0 + eslint-import-resolver-node: 0.3.9 + get-tsconfig: 4.7.6 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.6.3 + stable-hash: 0.0.4 + tslib: 2.6.3 + transitivePeerDependencies: + - supports-color + - typescript - deep-is@0.1.4: {} + eslint-plugin-jsdoc@48.11.0(eslint@9.8.0): + dependencies: + '@es-joy/jsdoccomment': 0.46.0 + are-docs-informative: 0.0.2 + comment-parser: 1.4.1 + debug: 4.3.6 + escape-string-regexp: 4.0.0 + eslint: 9.8.0 + espree: 10.1.0 + esquery: 1.6.0 + parse-imports: 2.1.1 + semver: 7.6.3 + spdx-expression-parse: 4.0.0 + synckit: 0.9.1 + transitivePeerDependencies: + - supports-color - doctrine@3.0.0: + eslint-plugin-jsonc@2.16.0(eslint@9.8.0): dependencies: - esutils: 2.0.3 + '@eslint-community/eslint-utils': 4.4.0(eslint@9.8.0) + eslint: 9.8.0 + eslint-compat-utils: 0.5.1(eslint@9.8.0) + espree: 9.6.1 + graphemer: 1.4.0 + jsonc-eslint-parser: 2.4.0 + natural-compare: 1.4.0 + synckit: 0.6.2 - dot-prop@5.3.0: + eslint-plugin-markdown@5.1.0(eslint@9.8.0): dependencies: - is-obj: 2.0.0 + eslint: 9.8.0 + mdast-util-from-markdown: 0.8.5 + transitivePeerDependencies: + - supports-color - eastasianwidth@0.2.0: {} + eslint-plugin-n@17.10.1(eslint@9.8.0): + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@9.8.0) + enhanced-resolve: 5.17.1 + eslint: 9.8.0 + eslint-plugin-es-x: 7.8.0(eslint@9.8.0) + get-tsconfig: 4.7.6 + globals: 15.9.0 + ignore: 5.2.4 + minimatch: 9.0.5 + semver: 7.6.3 - emoji-regex@8.0.0: {} + eslint-plugin-no-only-tests@3.1.0: {} - emoji-regex@9.2.2: {} + eslint-plugin-perfectionist@3.1.1(eslint@9.8.0)(typescript@5.2.2)(vue-eslint-parser@9.4.3(eslint@9.8.0)): + dependencies: + '@typescript-eslint/types': 8.0.0 + '@typescript-eslint/utils': 8.0.0(eslint@9.8.0)(typescript@5.2.2) + eslint: 9.8.0 + minimatch: 10.0.1 + natural-compare-lite: 1.4.0 + optionalDependencies: + vue-eslint-parser: 9.4.3(eslint@9.8.0) + transitivePeerDependencies: + - supports-color + - typescript - error-ex@1.3.2: + eslint-plugin-regexp@2.6.0(eslint@9.8.0): dependencies: - is-arrayish: 0.2.1 + '@eslint-community/eslint-utils': 4.4.0(eslint@9.8.0) + '@eslint-community/regexpp': 4.11.0 + comment-parser: 1.4.1 + eslint: 9.8.0 + jsdoc-type-pratt-parser: 4.0.0 + refa: 0.12.1 + regexp-ast-analysis: 0.7.1 + scslre: 0.3.0 - escalade@3.1.1: {} + eslint-plugin-toml@0.11.1(eslint@9.8.0): + dependencies: + debug: 4.3.6 + eslint: 9.8.0 + eslint-compat-utils: 0.5.1(eslint@9.8.0) + lodash: 4.17.21 + toml-eslint-parser: 0.10.0 + transitivePeerDependencies: + - supports-color - escape-string-regexp@1.0.5: {} + eslint-plugin-unicorn@55.0.0(eslint@9.8.0): + dependencies: + '@babel/helper-validator-identifier': 7.24.7 + '@eslint-community/eslint-utils': 4.4.0(eslint@9.8.0) + ci-info: 4.0.0 + clean-regexp: 1.0.0 + core-js-compat: 3.38.0 + eslint: 9.8.0 + esquery: 1.5.0 + globals: 15.9.0 + indent-string: 4.0.0 + is-builtin-module: 3.2.1 + jsesc: 3.0.2 + pluralize: 8.0.0 + read-pkg-up: 7.0.1 + regexp-tree: 0.1.27 + regjsparser: 0.10.0 + semver: 7.6.3 + strip-indent: 3.0.0 - escape-string-regexp@4.0.0: {} + eslint-plugin-unused-imports@4.0.1(@typescript-eslint/eslint-plugin@8.0.0(@typescript-eslint/parser@8.0.0(eslint@9.8.0)(typescript@5.2.2))(eslint@9.8.0)(typescript@5.2.2))(eslint@9.8.0): + dependencies: + eslint: 9.8.0 + eslint-rule-composer: 0.3.0 + optionalDependencies: + '@typescript-eslint/eslint-plugin': 8.0.0(@typescript-eslint/parser@8.0.0(eslint@9.8.0)(typescript@5.2.2))(eslint@9.8.0)(typescript@5.2.2) + + eslint-plugin-vitest@0.5.4(@typescript-eslint/eslint-plugin@8.0.0(@typescript-eslint/parser@8.0.0(eslint@9.8.0)(typescript@5.2.2))(eslint@9.8.0)(typescript@5.2.2))(eslint@9.8.0)(typescript@5.2.2): + dependencies: + '@typescript-eslint/utils': 7.18.0(eslint@9.8.0)(typescript@5.2.2) + eslint: 9.8.0 + optionalDependencies: + '@typescript-eslint/eslint-plugin': 8.0.0(@typescript-eslint/parser@8.0.0(eslint@9.8.0)(typescript@5.2.2))(eslint@9.8.0)(typescript@5.2.2) + transitivePeerDependencies: + - supports-color + - typescript - eslint-compat-utils@0.1.2(eslint@8.53.0): + eslint-plugin-vue@9.27.0(eslint@9.8.0): dependencies: - eslint: 8.53.0 + '@eslint-community/eslint-utils': 4.4.0(eslint@9.8.0) + eslint: 9.8.0 + globals: 13.24.0 + natural-compare: 1.4.0 + nth-check: 2.1.1 + postcss-selector-parser: 6.1.1 + semver: 7.6.3 + vue-eslint-parser: 9.4.3(eslint@9.8.0) + xml-name-validator: 4.0.0 + transitivePeerDependencies: + - supports-color - eslint-plugin-yml@1.10.0(eslint@8.53.0): + eslint-plugin-yml@1.14.0(eslint@9.8.0): dependencies: debug: 4.3.4 - eslint: 8.53.0 - eslint-compat-utils: 0.1.2(eslint@8.53.0) + eslint: 9.8.0 + eslint-compat-utils: 0.5.1(eslint@9.8.0) lodash: 4.17.21 natural-compare: 1.4.0 - yaml-eslint-parser: 1.2.2 + yaml-eslint-parser: 1.2.3 transitivePeerDependencies: - supports-color + eslint-processor-vue-blocks@0.1.2(@vue/compiler-sfc@3.4.35)(eslint@9.8.0): + dependencies: + '@vue/compiler-sfc': 3.4.35 + eslint: 9.8.0 + + eslint-rule-composer@0.3.0: {} + eslint-scope@7.2.2: dependencies: esrecurse: 4.3.0 estraverse: 5.3.0 + eslint-scope@8.0.2: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + eslint-visitor-keys@3.4.3: {} - eslint@8.53.0: + eslint-visitor-keys@4.0.0: {} + + eslint@9.8.0: dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.53.0) - '@eslint-community/regexpp': 4.8.1 - '@eslint/eslintrc': 2.1.3 - '@eslint/js': 8.53.0 - '@humanwhocodes/config-array': 0.11.13 + '@eslint-community/eslint-utils': 4.4.0(eslint@9.8.0) + '@eslint-community/regexpp': 4.11.0 + '@eslint/config-array': 0.17.1 + '@eslint/eslintrc': 3.1.0 + '@eslint/js': 9.8.0 '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.3.0 '@nodelib/fs.walk': 1.2.8 - '@ungap/structured-clone': 1.2.0 ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.3 debug: 4.3.4 - doctrine: 3.0.0 escape-string-regexp: 4.0.0 - eslint-scope: 7.2.2 - eslint-visitor-keys: 3.4.3 - espree: 9.6.1 + eslint-scope: 8.0.2 + eslint-visitor-keys: 4.0.0 + espree: 10.1.0 esquery: 1.5.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 - file-entry-cache: 6.0.1 + file-entry-cache: 8.0.0 find-up: 5.0.0 glob-parent: 6.0.2 - globals: 13.21.0 - graphemer: 1.4.0 ignore: 5.2.4 imurmurhash: 0.1.4 is-glob: 4.0.3 is-path-inside: 3.0.3 - js-yaml: 4.1.0 json-stable-stringify-without-jsonify: 1.0.1 levn: 0.4.1 lodash.merge: 4.6.2 @@ -1627,38 +2849,38 @@ snapshots: transitivePeerDependencies: - supports-color + espree@10.1.0: + dependencies: + acorn: 8.12.1 + acorn-jsx: 5.3.2(acorn@8.12.1) + eslint-visitor-keys: 4.0.0 + espree@9.6.1: dependencies: - acorn: 8.10.0 - acorn-jsx: 5.3.2(acorn@8.10.0) + acorn: 8.12.1 + acorn-jsx: 5.3.2(acorn@8.12.1) eslint-visitor-keys: 3.4.3 esquery@1.5.0: dependencies: estraverse: 5.3.0 + esquery@1.6.0: + dependencies: + estraverse: 5.3.0 + esrecurse@4.3.0: dependencies: estraverse: 5.3.0 estraverse@5.3.0: {} + estree-walker@2.0.2: {} + esutils@2.0.3: {} eventemitter3@5.0.1: {} - execa@5.1.1: - dependencies: - cross-spawn: 7.0.3 - get-stream: 6.0.1 - human-signals: 2.1.0 - is-stream: 2.0.1 - merge-stream: 2.0.0 - npm-run-path: 4.0.1 - onetime: 5.1.2 - signal-exit: 3.0.7 - strip-final-newline: 2.0.0 - execa@8.0.1: dependencies: cross-spawn: 7.0.3 @@ -1673,6 +2895,14 @@ snapshots: fast-deep-equal@3.1.3: {} + fast-glob@3.3.2: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.7 + fast-json-stable-stringify@2.1.0: {} fast-levenshtein@2.0.6: {} @@ -1681,14 +2911,16 @@ snapshots: dependencies: reusify: 1.0.4 - file-entry-cache@6.0.1: + file-entry-cache@8.0.0: dependencies: - flat-cache: 3.1.0 + flat-cache: 4.0.1 - fill-range@7.0.1: + fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 + find-up-simple@1.0.0: {} + find-up@4.1.0: dependencies: locate-path: 5.0.0 @@ -1699,110 +2931,119 @@ snapshots: locate-path: 6.0.0 path-exists: 4.0.0 - flat-cache@3.1.0: + find-up@7.0.0: dependencies: - flatted: 3.2.9 - keyv: 4.5.3 - rimraf: 3.0.2 + locate-path: 7.2.0 + path-exists: 5.0.0 + unicorn-magic: 0.1.0 - flatted@3.2.9: {} - - fs-extra@11.1.1: + flat-cache@4.0.1: dependencies: - graceful-fs: 4.2.11 - jsonfile: 6.1.0 - universalify: 2.0.0 + flatted: 3.2.9 + keyv: 4.5.4 - fs.realpath@1.0.0: {} + flatted@3.2.9: {} - function-bind@1.1.1: {} + function-bind@1.1.2: {} get-caller-file@2.0.5: {} - get-stream@6.0.1: {} + get-east-asian-width@1.2.0: {} get-stream@8.0.1: {} - git-raw-commits@2.0.11: + get-tsconfig@4.7.6: dependencies: - dargs: 7.0.0 - lodash: 4.17.21 - meow: 8.1.2 - split2: 3.2.2 - through2: 4.0.2 + resolve-pkg-maps: 1.0.0 - glob-parent@6.0.2: + git-raw-commits@4.0.0: + dependencies: + dargs: 8.1.0 + meow: 12.1.1 + split2: 4.2.0 + + glob-parent@5.1.2: dependencies: is-glob: 4.0.3 - glob@7.2.3: + glob-parent@6.0.2: dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 3.1.2 - once: 1.4.0 - path-is-absolute: 1.0.1 + is-glob: 4.0.3 - global-dirs@0.1.1: + global-directory@4.0.1: dependencies: - ini: 1.3.8 + ini: 4.1.1 - globals@13.21.0: + globals@13.24.0: dependencies: type-fest: 0.20.2 + globals@14.0.0: {} + + globals@15.9.0: {} + + globby@11.1.0: + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.2 + ignore: 5.2.4 + merge2: 1.4.1 + slash: 3.0.0 + graceful-fs@4.2.11: {} graphemer@1.4.0: {} - hard-rejection@2.1.0: {} - has-flag@3.0.0: {} has-flag@4.0.0: {} - has@1.0.3: + hasown@2.0.2: dependencies: - function-bind: 1.1.1 + function-bind: 1.1.2 hosted-git-info@2.8.9: {} - hosted-git-info@4.1.0: - dependencies: - lru-cache: 6.0.0 - - human-signals@2.1.0: {} - human-signals@5.0.0: {} - husky@8.0.3: {} + husky@9.1.4: {} ignore@5.2.4: {} + ignore@5.3.1: {} + import-fresh@3.3.0: dependencies: parent-module: 1.0.1 resolve-from: 4.0.0 + import-meta-resolve@4.1.0: {} + imurmurhash@0.1.4: {} indent-string@4.0.0: {} - inflight@1.0.6: - dependencies: - once: 1.4.0 - wrappy: 1.0.2 + ini@4.1.1: {} - inherits@2.0.4: {} + is-alphabetical@1.0.4: {} - ini@1.3.8: {} + is-alphanumerical@1.0.4: + dependencies: + is-alphabetical: 1.0.4 + is-decimal: 1.0.4 is-arrayish@0.2.1: {} - is-core-module@2.13.0: + is-builtin-module@3.2.1: dependencies: - has: 1.0.3 + builtin-modules: 3.3.0 + + is-core-module@2.15.0: + dependencies: + hasown: 2.0.2 + + is-decimal@1.0.4: {} is-extglob@2.1.1: {} @@ -1810,20 +3051,22 @@ snapshots: is-fullwidth-code-point@4.0.0: {} + is-fullwidth-code-point@5.0.0: + dependencies: + get-east-asian-width: 1.2.0 + is-glob@4.0.3: dependencies: is-extglob: 2.1.1 + is-hexadecimal@1.0.4: {} + is-number@7.0.0: {} is-obj@2.0.0: {} is-path-inside@3.0.3: {} - is-plain-obj@1.1.0: {} - - is-stream@2.0.1: {} - is-stream@3.0.0: {} is-text-path@2.0.0: @@ -1840,6 +3083,12 @@ snapshots: dependencies: argparse: 2.0.1 + jsdoc-type-pratt-parser@4.0.0: {} + + jsesc@0.5.0: {} + + jsesc@3.0.2: {} + json-buffer@3.0.1: {} json-parse-even-better-errors@2.3.1: {} @@ -1850,52 +3099,56 @@ snapshots: json-stable-stringify-without-jsonify@1.0.1: {} - jsonfile@6.1.0: + jsonc-eslint-parser@2.4.0: dependencies: - universalify: 2.0.0 - optionalDependencies: - graceful-fs: 4.2.11 + acorn: 8.12.1 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + semver: 7.6.3 jsonparse@1.3.1: {} - keyv@4.5.3: + keyv@4.5.4: dependencies: json-buffer: 3.0.1 - kind-of@6.0.3: {} - levn@0.4.1: dependencies: prelude-ls: 1.2.1 type-check: 0.4.0 - lilconfig@2.1.0: {} + lilconfig@3.1.2: {} lines-and-columns@1.2.4: {} - lint-staged@15.0.2: + lint-staged@15.2.8: dependencies: chalk: 5.3.0 - commander: 11.1.0 - debug: 4.3.4 + commander: 12.1.0 + debug: 4.3.6 execa: 8.0.1 - lilconfig: 2.1.0 - listr2: 7.0.2 - micromatch: 4.0.5 + lilconfig: 3.1.2 + listr2: 8.2.4 + micromatch: 4.0.7 pidtree: 0.6.0 string-argv: 0.3.2 - yaml: 2.3.3 + yaml: 2.5.0 transitivePeerDependencies: - supports-color - listr2@7.0.2: + listr2@8.2.4: dependencies: - cli-truncate: 3.1.0 + cli-truncate: 4.0.0 colorette: 2.0.20 eventemitter3: 5.0.1 - log-update: 5.0.1 - rfdc: 1.3.0 - wrap-ansi: 8.1.0 + log-update: 6.1.0 + rfdc: 1.4.1 + wrap-ansi: 9.0.0 + + local-pkg@0.5.0: + dependencies: + mlly: 1.7.1 + pkg-types: 1.1.3 locate-path@5.0.0: dependencies: @@ -1905,9 +3158,11 @@ snapshots: dependencies: p-locate: 5.0.0 - lodash.camelcase@4.3.0: {} + locate-path@7.2.0: + dependencies: + p-locate: 6.0.0 - lodash.isfunction@3.0.9: {} + lodash.camelcase@4.3.0: {} lodash.isplainobject@4.0.6: {} @@ -1927,101 +3182,112 @@ snapshots: lodash@4.17.21: {} - log-update@5.0.1: + log-update@6.1.0: dependencies: - ansi-escapes: 5.0.0 - cli-cursor: 4.0.0 - slice-ansi: 5.0.0 + ansi-escapes: 7.0.0 + cli-cursor: 5.0.0 + slice-ansi: 7.1.0 strip-ansi: 7.1.0 - wrap-ansi: 8.1.0 + wrap-ansi: 9.0.0 lru-cache@6.0.0: dependencies: yallist: 4.0.0 - map-obj@1.0.1: {} + magic-string@0.30.11: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + + mdast-util-from-markdown@0.8.5: + dependencies: + '@types/mdast': 3.0.15 + mdast-util-to-string: 2.0.0 + micromark: 2.11.4 + parse-entities: 2.0.0 + unist-util-stringify-position: 2.0.3 + transitivePeerDependencies: + - supports-color - map-obj@4.3.0: {} + mdast-util-to-string@2.0.0: {} meow@12.1.1: {} - meow@8.1.2: - dependencies: - '@types/minimist': 1.2.2 - camelcase-keys: 6.2.2 - decamelize-keys: 1.1.1 - hard-rejection: 2.1.0 - minimist-options: 4.1.0 - normalize-package-data: 3.0.3 - read-pkg-up: 7.0.1 - redent: 3.0.0 - trim-newlines: 3.0.1 - type-fest: 0.18.1 - yargs-parser: 20.2.9 - merge-stream@2.0.0: {} - micromatch@4.0.5: + merge2@1.4.1: {} + + micromark@2.11.4: dependencies: - braces: 3.0.2 - picomatch: 2.3.1 + debug: 4.3.6 + parse-entities: 2.0.0 + transitivePeerDependencies: + - supports-color - mimic-fn@2.1.0: {} + micromatch@4.0.7: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 mimic-fn@4.0.0: {} + mimic-function@5.0.1: {} + min-indent@1.0.1: {} + minimatch@10.0.1: + dependencies: + brace-expansion: 2.0.1 + minimatch@3.1.2: dependencies: brace-expansion: 1.1.11 - minimist-options@4.1.0: + minimatch@9.0.5: dependencies: - arrify: 1.0.1 - is-plain-obj: 1.1.0 - kind-of: 6.0.3 + brace-expansion: 2.0.1 minimist@1.2.8: {} + mlly@1.7.1: + dependencies: + acorn: 8.12.1 + pathe: 1.1.2 + pkg-types: 1.1.3 + ufo: 1.5.4 + ms@2.1.2: {} + nanoid@3.3.7: {} + + natural-compare-lite@1.4.0: {} + natural-compare@1.4.0: {} + node-releases@2.0.18: {} + normalize-package-data@2.5.0: dependencies: hosted-git-info: 2.8.9 - resolve: 1.22.6 + resolve: 1.22.8 semver: 5.7.2 validate-npm-package-license: 3.0.4 - normalize-package-data@3.0.3: - dependencies: - hosted-git-info: 4.1.0 - is-core-module: 2.13.0 - semver: 7.5.4 - validate-npm-package-license: 3.0.4 - - npm-run-path@4.0.1: - dependencies: - path-key: 3.1.1 - npm-run-path@5.1.0: dependencies: path-key: 4.0.0 - once@1.4.0: - dependencies: - wrappy: 1.0.2 - - onetime@5.1.2: + nth-check@2.1.1: dependencies: - mimic-fn: 2.1.0 + boolbase: 1.0.0 onetime@6.0.0: dependencies: mimic-fn: 4.0.0 + onetime@7.0.0: + dependencies: + mimic-function: 5.0.1 + optionator@0.9.3: dependencies: '@aashutoshrathi/word-wrap': 1.2.6 @@ -2039,6 +3305,10 @@ snapshots: dependencies: yocto-queue: 0.1.0 + p-limit@4.0.0: + dependencies: + yocto-queue: 1.1.1 + p-locate@4.1.0: dependencies: p-limit: 2.3.0 @@ -2047,12 +3317,32 @@ snapshots: dependencies: p-limit: 3.1.0 + p-locate@6.0.0: + dependencies: + p-limit: 4.0.0 + p-try@2.2.0: {} parent-module@1.0.1: dependencies: callsites: 3.1.0 + parse-entities@2.0.0: + dependencies: + character-entities: 1.2.4 + character-entities-legacy: 1.1.4 + character-reference-invalid: 1.1.4 + is-alphanumerical: 1.0.4 + is-decimal: 1.0.4 + is-hexadecimal: 1.0.4 + + parse-gitignore@2.0.0: {} + + parse-imports@2.1.1: + dependencies: + es-module-lexer: 1.5.4 + slashes: 3.0.12 + parse-json@5.2.0: dependencies: '@babel/code-frame': 7.22.13 @@ -2062,7 +3352,7 @@ snapshots: path-exists@4.0.0: {} - path-is-absolute@1.0.1: {} + path-exists@5.0.0: {} path-key@3.1.1: {} @@ -2072,18 +3362,41 @@ snapshots: path-type@4.0.0: {} + pathe@1.1.2: {} + + picocolors@1.0.1: {} + picomatch@2.3.1: {} + picomatch@4.0.2: {} + pidtree@0.6.0: {} + pkg-types@1.1.3: + dependencies: + confbox: 0.1.7 + mlly: 1.7.1 + pathe: 1.1.2 + + pluralize@8.0.0: {} + + postcss-selector-parser@6.1.1: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss@8.4.40: + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.1 + source-map-js: 1.2.0 + prelude-ls@1.2.1: {} punycode@2.3.0: {} queue-microtask@1.2.3: {} - quick-lru@4.0.1: {} - read-pkg-up@7.0.1: dependencies: find-up: 4.1.0 @@ -2092,21 +3405,25 @@ snapshots: read-pkg@5.2.0: dependencies: - '@types/normalize-package-data': 2.4.1 + '@types/normalize-package-data': 2.4.4 normalize-package-data: 2.5.0 parse-json: 5.2.0 type-fest: 0.6.0 - readable-stream@3.6.2: + refa@0.12.1: dependencies: - inherits: 2.0.4 - string_decoder: 1.3.0 - util-deprecate: 1.0.2 + '@eslint-community/regexpp': 4.11.0 - redent@3.0.0: + regexp-ast-analysis@0.7.1: dependencies: - indent-string: 4.0.0 - strip-indent: 3.0.0 + '@eslint-community/regexpp': 4.11.0 + refa: 0.12.1 + + regexp-tree@0.1.27: {} + + regjsparser@0.10.0: + dependencies: + jsesc: 0.5.0 require-directory@2.1.1: {} @@ -2116,34 +3433,32 @@ snapshots: resolve-from@5.0.0: {} - resolve-global@1.0.0: - dependencies: - global-dirs: 0.1.1 + resolve-pkg-maps@1.0.0: {} - resolve@1.22.6: + resolve@1.22.8: dependencies: - is-core-module: 2.13.0 + is-core-module: 2.15.0 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 - restore-cursor@4.0.0: + restore-cursor@5.1.0: dependencies: - onetime: 5.1.2 - signal-exit: 3.0.7 + onetime: 7.0.0 + signal-exit: 4.1.0 reusify@1.0.4: {} - rfdc@1.3.0: {} - - rimraf@3.0.2: - dependencies: - glob: 7.2.3 + rfdc@1.4.1: {} run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 - safe-buffer@5.2.1: {} + scslre@0.3.0: + dependencies: + '@eslint-community/regexpp': 4.11.0 + refa: 0.12.1 + regexp-ast-analysis: 0.7.1 semver@5.7.2: {} @@ -2151,41 +3466,57 @@ snapshots: dependencies: lru-cache: 6.0.0 + semver@7.6.3: {} + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 shebang-regex@3.0.0: {} - signal-exit@3.0.7: {} - signal-exit@4.1.0: {} + sisteransi@1.0.5: {} + + slash@3.0.0: {} + + slashes@3.0.12: {} + slice-ansi@5.0.0: dependencies: ansi-styles: 6.2.1 is-fullwidth-code-point: 4.0.0 + slice-ansi@7.1.0: + dependencies: + ansi-styles: 6.2.1 + is-fullwidth-code-point: 5.0.0 + + source-map-js@1.2.0: {} + spdx-correct@3.2.0: dependencies: spdx-expression-parse: 3.0.1 - spdx-license-ids: 3.0.14 + spdx-license-ids: 3.0.18 - spdx-exceptions@2.3.0: {} + spdx-exceptions@2.5.0: {} spdx-expression-parse@3.0.1: dependencies: - spdx-exceptions: 2.3.0 - spdx-license-ids: 3.0.14 + spdx-exceptions: 2.5.0 + spdx-license-ids: 3.0.18 - spdx-license-ids@3.0.14: {} - - split2@3.2.2: + spdx-expression-parse@4.0.0: dependencies: - readable-stream: 3.6.2 + spdx-exceptions: 2.5.0 + spdx-license-ids: 3.0.18 + + spdx-license-ids@3.0.18: {} split2@4.2.0: {} + stable-hash@0.0.4: {} + string-argv@0.3.2: {} string-width@4.2.3: @@ -2194,16 +3525,12 @@ snapshots: is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 - string-width@5.1.2: + string-width@7.2.0: dependencies: - eastasianwidth: 0.2.0 - emoji-regex: 9.2.2 + emoji-regex: 10.3.0 + get-east-asian-width: 1.2.0 strip-ansi: 7.1.0 - string_decoder@1.3.0: - dependencies: - safe-buffer: 5.2.1 - strip-ansi@6.0.1: dependencies: ansi-regex: 5.0.1 @@ -2212,8 +3539,6 @@ snapshots: dependencies: ansi-regex: 6.0.1 - strip-final-newline@2.0.0: {} - strip-final-newline@3.0.0: {} strip-indent@3.0.0: @@ -2232,27 +3557,44 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} + synckit@0.6.2: + dependencies: + tslib: 2.6.3 + + synckit@0.9.1: + dependencies: + '@pkgr/core': 0.1.1 + tslib: 2.6.3 + + tapable@2.2.1: {} + text-extensions@2.4.0: {} text-table@0.2.0: {} - through2@4.0.2: - dependencies: - readable-stream: 3.6.2 - through@2.3.8: {} + to-fast-properties@2.0.0: {} + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 - trim-newlines@3.0.1: {} + toml-eslint-parser@0.10.0: + dependencies: + eslint-visitor-keys: 3.4.3 + + ts-api-utils@1.3.0(typescript@5.2.2): + dependencies: + typescript: 5.2.2 + + tslib@2.6.3: {} type-check@0.4.0: dependencies: prelude-ls: 1.2.1 - type-fest@0.18.1: {} + type-detect@4.1.0: {} type-fest@0.20.2: {} @@ -2260,13 +3602,23 @@ snapshots: type-fest@0.8.1: {} - type-fest@1.4.0: {} - typescript@5.2.2: {} + ufo@1.5.4: {} + undici-types@5.26.5: {} - universalify@2.0.0: {} + unicorn-magic@0.1.0: {} + + unist-util-stringify-position@2.0.3: + dependencies: + '@types/unist': 2.0.10 + + update-browserslist-db@1.1.0(browserslist@4.23.3): + dependencies: + browserslist: 4.23.3 + escalade: 3.1.2 + picocolors: 1.0.1 uri-js@4.4.1: dependencies: @@ -2279,6 +3631,19 @@ snapshots: spdx-correct: 3.2.0 spdx-expression-parse: 3.0.1 + vue-eslint-parser@9.4.3(eslint@9.8.0): + dependencies: + debug: 4.3.6 + eslint: 9.8.0 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esquery: 1.5.0 + lodash: 4.17.21 + semver: 7.6.3 + transitivePeerDependencies: + - supports-color + which@2.0.2: dependencies: isexe: 2.0.0 @@ -2289,29 +3654,27 @@ snapshots: string-width: 4.2.3 strip-ansi: 6.0.1 - wrap-ansi@8.1.0: + wrap-ansi@9.0.0: dependencies: ansi-styles: 6.2.1 - string-width: 5.1.2 + string-width: 7.2.0 strip-ansi: 7.1.0 - wrappy@1.0.2: {} + xml-name-validator@4.0.0: {} y18n@5.0.8: {} yallist@4.0.0: {} - yaml-eslint-parser@1.2.2: + yaml-eslint-parser@1.2.3: dependencies: eslint-visitor-keys: 3.4.3 lodash: 4.17.21 - yaml: 2.3.2 - - yaml@2.3.2: {} + yaml: 2.3.3 yaml@2.3.3: {} - yargs-parser@20.2.9: {} + yaml@2.5.0: {} yargs-parser@21.1.1: {} @@ -2326,3 +3689,5 @@ snapshots: yargs-parser: 21.1.1 yocto-queue@0.1.0: {} + + yocto-queue@1.1.1: {} diff --git a/release-please-config.json b/release-please-config.json index e3bc589a..7ea870b2 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -1,8 +1,10 @@ { + "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json", "packages": { ".": { + "release-type": "node", "package-name": "socle", "include-component-in-tag": false } } -} \ No newline at end of file +} diff --git a/roles/argocd/tasks/main.yaml b/roles/argocd/tasks/main.yaml index ed605517..efdd38c3 100644 --- a/roles/argocd/tasks/main.yaml +++ b/roles/argocd/tasks/main.yaml @@ -7,14 +7,14 @@ register: argocd_secret failed_when: argocd_secret.resources | length == 0 -- name: Argo crb +- name: Argo CD OpenShift scc crb kubernetes.core.k8s: definition: apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: creationTimestamp: - name: system:openshift:scc:privileged + name: "{{ dsc_name }}-argocd-system:openshift:scc:privileged" roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole @@ -22,24 +22,25 @@ subjects: - kind: ServiceAccount namespace: "{{ dsc.argocd.namespace }}" - name: argo-argo-cd-argocd-repo-server + name: "{{ dsc_name }}-argocd-repo-server" - kind: ServiceAccount namespace: "{{ dsc.argocd.namespace }}" - name: argo-argo-cd-argocd-server + name: argocd-server - kind: ServiceAccount namespace: "{{ dsc.argocd.namespace }}" - name: argo-redis + name: "{{ dsc_name }}-redis" - kind: ServiceAccount namespace: "{{ dsc.argocd.namespace }}" - name: argo-redis-master + name: "{{ dsc_name }}-redis-ha" - kind: ServiceAccount namespace: "{{ dsc.argocd.namespace }}" - name: argo-redis-replica + name: "{{ dsc_name }}-redis-ha-haproxy" - name: Add helm repo kubernetes.core.helm_repository: - name: bitnami - repo_url: https://charts.bitnami.com/bitnami + name: argo + repo_url: "{{ dsc.argocd.helmRepoUrl }}" + force_update: true - name: Set path fact ansible.builtin.set_fact: @@ -55,8 +56,8 @@ - name: Deploy helm kubernetes.core.helm: - name: argo - chart_ref: bitnami/argo-cd + name: "{{ dsc_name }}" + chart_ref: argo/argo-cd chart_version: "{{ dsc.argocd.chartVersion }}" release_namespace: "{{ dsc.argocd.namespace }}" create_namespace: true @@ -89,3 +90,8 @@ template: "{{ item }}" with_items: - ingress.yaml.j2 + +- name: Set alerting rules + when: dsc.global.alerting.enabled + kubernetes.core.k8s: + template: prometheusrule.yml.j2 diff --git a/roles/argocd/templates/ingress.yaml.j2 b/roles/argocd/templates/ingress.yaml.j2 index e726b280..63caa4b7 100644 --- a/roles/argocd/templates/ingress.yaml.j2 +++ b/roles/argocd/templates/ingress.yaml.j2 @@ -30,6 +30,43 @@ spec: pathType: Prefix backend: service: - name: argo-argo-cd-server + name: {{ dsc_name }}-argocd-server port: - number: 80 \ No newline at end of file + number: 80 + +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: argo-appset-ingress + namespace: {{ dsc.argocd.namespace }} + annotations: +{% for key, val in dsc.ingress.annotations.items() %} + {{ key }}: {{ val }} +{% endfor %} + labels: +{% for key, val in dsc.ingress.labels.items() %} + {{ key }}: {{ val }} +{% endfor %} +spec: +{% if not dsc.ingress.tls.type == 'none' %} + tls: + - hosts: + - appset.{{ argocd_domain }} +{% if dsc.ingress.tls.type == 'tlsSecret' %} + secretName: {{ dsc.ingress.tls.tlsSecret.name }} +{% else %} + secretName: argocd-appset-tls-secret +{% endif %} +{% endif %} + rules: + - host: appset.{{ argocd_domain }} + http: + paths: + - path: /api/webhook + pathType: Prefix + backend: + service: + name: {{ dsc_name }}-argocd-applicationset-controller + port: + number: 7000 diff --git a/roles/argocd/templates/prometheusrule.yml.j2 b/roles/argocd/templates/prometheusrule.yml.j2 new file mode 100644 index 00000000..84e79871 --- /dev/null +++ b/roles/argocd/templates/prometheusrule.yml.j2 @@ -0,0 +1,94 @@ +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + labels: + app.kubernetes.io/name: gitlab + name: argocd + namespace: {{ dsc.argocd.namespace }} +spec: + groups: + - name: ArgoCD + rules: + - alert: Argo CD Redis HA not available + annotations: + message: Argo CD Redis HA in namespace {{ dsc.argocd.namespace }} has not been available for the last 5 minutes. + summary: Argo CD Redis HA down (no ready pod)" + expr: | + sum(kube_pod_status_ready{ + pod=~"argo-redis-ha-server-.*", + namespace="{{ dsc.argocd.namespace }}", + condition="true"}) == 0 + for: 5m + labels: + severity: critical + - alert: Argo CD Redis HA Haproxy not available + annotations: + message: Argo CD Redis HA Haproxy in namespace {{ dsc.argocd.namespace }} has not been available for the last 5 minutes. + summary: Argo CD Redis HA Haproxy down (no ready pod)" + expr: | + sum(kube_pod_status_ready{ + pod=~"argo-redis-ha-haproxy-.*", + namespace="{{ dsc.argocd.namespace }}", + condition="true"}) == 0 + for: 5m + labels: + severity: critical + - alert: Argo CD Server not available + annotations: + message: Argo CD Server in namespace {{ dsc.argocd.namespace }} has not been available for the last 5 minutes. + summary: Argo CD Server down (no ready pod)" + expr: | + sum(kube_pod_status_ready{ + pod=~"argo-argocd-server-.*", + namespace="{{ dsc.argocd.namespace }}", + condition="true"}) == 0 + for: 5m + labels: + severity: critical + - alert: Argo CD Repo Server not available + annotations: + message: Argo CD Repo Server in namespace {{ dsc.argocd.namespace }} has not been available for the last 5 minutes. + summary: Argo CD Repo Server down (no ready pod)" + expr: | + sum(kube_pod_status_ready{ + pod=~"argo-argocd-repo-server-.*", + namespace="{{ dsc.argocd.namespace }}", + condition="true"}) == 0 + for: 5m + labels: + severity: critical + - alert: Argo CD Applicationset Controller not available + annotations: + message: Argo CD Applicationset Controller in namespace {{ dsc.argocd.namespace }} has not been available for the last 5 minutes. + summary: Argo CD Applicationset Controller down (no ready pod)" + expr: | + sum(kube_pod_status_ready{ + pod=~"argo-argocd-applicationset-controller-.*", + namespace="{{ dsc.argocd.namespace }}", + condition="true"}) == 0 + for: 5m + labels: + severity: critical + - alert: Argo CD Application Controller not available + annotations: + message: Argo CD Application Controller in namespace {{ dsc.argocd.namespace }} has not been available for the last 5 minutes. + summary: Argo CD Application Controller down (no ready pod)" + expr: | + sum(kube_pod_status_ready{ + pod=~"argo-argocd-application-controller-.*", + namespace="{{ dsc.argocd.namespace }}", + condition="true"}) == 0 + for: 5m + labels: + severity: critical + - alert: Argo CD Pod not healthy + annotations: + message: Argo CD {{"{{"}} $labels.pod {{"}}"}} pod in namespace {{ dsc.argocd.namespace }} has been unavailable for the last 5 minutes. + summary: Argo CD {{"{{"}} $labels.pod {{"}}"}} pod not healthy (container {{"{{"}} $labels.container {{"}}"}} is not ready) + expr: | + kube_pod_container_status_ready{ + pod=~"argo-.*", + container!~"secret-init", namespace="{{ dsc.argocd.namespace }}"} == 0 + for: 5m + labels: + severity: warning diff --git a/roles/argocd/templates/values/00-main.j2 b/roles/argocd/templates/values/00-main.j2 index 3119e004..d3cafc8d 100644 --- a/roles/argocd/templates/values/00-main.j2 +++ b/roles/argocd/templates/values/00-main.j2 @@ -1,8 +1,17 @@ -config: +crds: + install: true + keep: true +{% if dsc.global.platform == "openshift" %} +openshift: + enabled: true +{% endif %} +configs: {% if dsc.argocd.admin.enabled %} secret: argocdServerAdminPassword: "{{ dsc.argocd.admin.password }}" {% endif %} + params: + server.insecure: true rbac: policy.csv: | p, role:admin, *, *, */*, allow @@ -23,20 +32,7 @@ config: scopes: "[groups]" policy.default: role:nada admin.enabled: "false" -redis: - architecture: replication -controller: - replicaCount: 3 -dex: - enabled: false -server: - replicaCount: 3 - ingress: - ingressClassName: {{ dsc.ingress.className | default('') }} - ingressGrpc: - ingressClassName: {{ dsc.ingress.className | default('') }} - insecure: true - config: + cm: clusterResources: "true" url: "https://{{ argocd_domain }}" oidc.config: | @@ -60,13 +56,23 @@ server: kinds: - TaskRun - PipelineRun - extraEnvVars: [] +redis-ha: + enabled: true +controller: + replicas: 3 +dex: + enabled: false +server: + replicas: 3 + ingress: + ingressClassName: {{ dsc.ingress.className | default('') }} + ingressGrpc: + ingressClassName: {{ dsc.ingress.className | default('') }} repoServer: - extraEnvVars: [] - replicaCount: 3 + replicas: 3 applicationSet: enabled: false - replicaCount: 2 + replicas: 2 webhook: ingress: ingressClassName: {{ dsc.ingress.className | default('') }} diff --git a/roles/argocd/templates/values/10-alerting.j2 b/roles/argocd/templates/values/10-alerting.j2 new file mode 100644 index 00000000..19542d60 --- /dev/null +++ b/roles/argocd/templates/values/10-alerting.j2 @@ -0,0 +1,32 @@ +{% if dsc.global.metrics.enabled and dsc.global.alerting.enabled %} +controller: + metrics: + rules: + enabled: true + namespace: "{{ dsc.argocd.namespace }}" + spec: + - alert: Argo CD App Missing + expr: | + absent(argocd_app_info) == 1 + for: 15m + labels: + severity: critical + annotations: + summary: "[Argo CD] No reported applications" + description: | + Argo CD has not reported any applications data for the past 15 minutes which + means that it must be down or not functioning properly. This needs to be + resolved for this cloud to continue to maintain state. + - alert: Argo CD App Not Synced + expr: | + argocd_app_info{sync_status!="Synced"} == 1 + for: 12h + labels: + severity: warning + annotations: + summary: Application not synchronized + description: | + Argo CD instance in namespace {{"{{"}} $labels.namespace {{"}}"}} : The application {{"{{"}} $labels.name {{"}}"}} + in namespace {{"{{"}} $labels.dest_namespace {{"}}"}} has not been synchronized for over 12 hours, + which means that the state of this cloud has drifted away from the state inside Git. +{% endif %} diff --git a/roles/argocd/templates/values/10-exposed-ca.j2 b/roles/argocd/templates/values/10-exposed-ca.j2 index 3bcb3b08..290dcb2d 100644 --- a/roles/argocd/templates/values/10-exposed-ca.j2 +++ b/roles/argocd/templates/values/10-exposed-ca.j2 @@ -1,6 +1,7 @@ {% if dsc.exposedCA.type != 'none' %} -config: - tlsCerts: - {{ gitlab_domain }}: | - {{ exposed_ca_pem | indent(width=6, first=False) }} +configs: + tls: + certificates: + {{ gitlab_domain }}: | + {{ exposed_ca_pem | indent(width=8, first=False) }} {% endif %} diff --git a/roles/argocd/templates/values/10-metrics.j2 b/roles/argocd/templates/values/10-metrics.j2 index f7df84c9..4dc262a2 100644 --- a/roles/argocd/templates/values/10-metrics.j2 +++ b/roles/argocd/templates/values/10-metrics.j2 @@ -1,10 +1,21 @@ {% if dsc.global.metrics.enabled %} -redis: - metrics: +redis-ha: + exporter: enabled: true serviceMonitor: enabled: true namespace: "{{ dsc.argocd.namespace }}" + haproxy: + metrics: + enabled: true + serviceMonitor: + enabled: true + namespace: "{{ dsc.argocd.namespace }}" +redis: + metrics: + enabled: false + serviceMonitor: + enabled: false controller: metrics: enabled: true diff --git a/roles/argocd/templates/values/10-offline.j2 b/roles/argocd/templates/values/10-offline.j2 index 6c99a3a6..b55d383e 100644 --- a/roles/argocd/templates/values/10-offline.j2 +++ b/roles/argocd/templates/values/10-offline.j2 @@ -1,6 +1,7 @@ {% if dsc.global.offline %} -config: - tlsCerts: - {{ dsc.argocd.privateGitlabDomain }}: | - {{ exposed_ca_pem | indent(width=6, first=False) }} +configs: + tls: + certificates: + {{ dsc.argocd.privateGitlabDomain }}: | + {{ exposed_ca_pem | indent(width=8, first=False) }} {% endif %} diff --git a/roles/argocd/templates/values/10-proxy.j2 b/roles/argocd/templates/values/10-proxy.j2 index 55d49ef3..f3fde573 100644 --- a/roles/argocd/templates/values/10-proxy.j2 +++ b/roles/argocd/templates/values/10-proxy.j2 @@ -1,6 +1,6 @@ {% if dsc.proxy.enabled %} server: - extraEnvVars: &extraEnvVars + env: &extraEnvVars - name: HTTP_PROXY value: "{{ dsc.proxy.http_proxy }}" - name: HTTPS_PROXY @@ -9,5 +9,5 @@ server: value: "{{ dsc.proxy.no_proxy }},argo-argo-cd-repo-server" repoServer: - extraEnvVars: *extraEnvVars + env: *extraEnvVars {% endif %} \ No newline at end of file diff --git a/roles/argocd/templates/values/10-redis-openshift.j2 b/roles/argocd/templates/values/10-redis-openshift.j2 index fa55f612..75adafaa 100644 --- a/roles/argocd/templates/values/10-redis-openshift.j2 +++ b/roles/argocd/templates/values/10-redis-openshift.j2 @@ -1,18 +1,10 @@ {% if dsc.global.platform == "openshift" %} -redis: - metrics: - podSecurityContext: - enabled: false +redis-ha: + containerSecurityContext: + runAsUser: null + runAsGroup: null + haproxy: containerSecurityContext: - enabled: false - master: - podSecurityContext: - enabled: false - containerSecurityContext: - enabled: false - replica: - podSecurityContext: - enabled: false - containerSecurityContext: - enabled: false + runAsUser: null + runAsGroup: null {% endif %} \ No newline at end of file diff --git a/roles/argocd/templates/values/10-registry.j2 b/roles/argocd/templates/values/10-registry.j2 index fe0194d2..93aec52e 100644 --- a/roles/argocd/templates/values/10-registry.j2 +++ b/roles/argocd/templates/values/10-registry.j2 @@ -1,8 +1,14 @@ {% if use_private_registry %} image: - registry: "{{ dsc.global.registry }}" + repository: "{{ dsc.global.registry }}" redis: image: - registry: "{{ dsc.global.registry }}" + repository: "{{ dsc.global.registry }}" {% endif %} + +{% if use_image_pull_secrets %} +global: + imagePullSecrets: + - dso-config-pull-secret +{% endif %} \ No newline at end of file diff --git a/roles/cert-manager/tasks/main.yaml b/roles/cert-manager/tasks/main.yaml index 8a5adaaf..20a8840d 100644 --- a/roles/cert-manager/tasks/main.yaml +++ b/roles/cert-manager/tasks/main.yaml @@ -14,12 +14,16 @@ register: cm_mwhc - name: Install cert-manager - when: (cm_api == 'absent') or (cm_mwhc.resources | length == 0) + when: > + cm_api == 'absent' or + cm_mwhc.resources | length == 0 or + dsc.certmanager.forcedInstall block: - name: Add cert-manager helm repo kubernetes.core.helm_repository: name: jetstack - repo_url: https://charts.jetstack.io + repo_url: "{{ dsc.certmanager.helmRepoUrl }}" + force_update: true # Installation des CRDs indépendamment du chart helm. # Recommandé en production. @@ -66,6 +70,11 @@ retries: 15 delay: 5 + - name: Set alerting rules + when: dsc.global.alerting.enabled + kubernetes.core.k8s: + template: prometheusrule.yml.j2 + - name: Create Let's Encrypt ClusterIssuer kubernetes.core.k8s: state: present diff --git a/roles/cert-manager/templates/prometheusrule.yml.j2 b/roles/cert-manager/templates/prometheusrule.yml.j2 new file mode 100644 index 00000000..77ca8619 --- /dev/null +++ b/roles/cert-manager/templates/prometheusrule.yml.j2 @@ -0,0 +1,22 @@ +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + labels: + app.kubernetes.io/name: gitlab + name: certmanager + namespace: cert-manager +spec: + groups: + - name: Cert-manager + rules: + - alert: Cert-manager Pod not healthy + annotations: + message: Cert-manager {{"{{"}} $labels.pod {{"}}"}} pod in namespace cert-manager has been unavailable for the last 5 minutes. + summary: Cert-manager {{"{{"}} $labels.pod {{"}}"}} pod not healthy (container {{"{{"}} $labels.container {{"}}"}} is not ready) + expr: | + kube_pod_container_status_ready{ + pod=~"cert-manager(-.*)*", + namespace="cert-manager"} == 0 + for: 5m + labels: + severity: critical diff --git a/roles/cloudnativepg/tasks/main.yml b/roles/cloudnativepg/tasks/main.yml index adb8e5c3..ba237723 100644 --- a/roles/cloudnativepg/tasks/main.yml +++ b/roles/cloudnativepg/tasks/main.yml @@ -14,7 +14,10 @@ register: cnpg_mwhc - name: Install CloudNativePG operator - when: (cnpg_api == 'absent') or (cnpg_mwhc.resources | length == 0) + when: > + cnpg_api == 'absent' or + cnpg_mwhc.resources | length == 0 or + dsc.cloudnativepg.forcedInstall block: - name: Create CloudNativePG namespace kubernetes.core.k8s: @@ -26,7 +29,8 @@ - name: Add CloudNativePG helm repo kubernetes.core.helm_repository: name: cnpg - repo_url: https://cloudnative-pg.github.io/charts + repo_url: "{{ dsc.cloudnativepg.helmRepoUrl }}" + force_update: true - name: Set path fact ansible.builtin.set_fact: @@ -56,3 +60,8 @@ until: endpoint.resources[0].subsets[0].addresses[0] is defined retries: 15 delay: 5 + + - name: Set alerting rules + when: dsc.global.alerting.enabled + kubernetes.core.k8s: + template: prometheusrule.yml.j2 diff --git a/roles/cloudnativepg/templates/prometheusrule.yml.j2 b/roles/cloudnativepg/templates/prometheusrule.yml.j2 new file mode 100644 index 00000000..1aa1446c --- /dev/null +++ b/roles/cloudnativepg/templates/prometheusrule.yml.j2 @@ -0,0 +1,22 @@ +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + labels: + app.kubernetes.io/name: gitlab + name: cnpg + namespace: {{ dsc.cloudnativepg.namespace }} +spec: + groups: + - name: CNPG + rules: + - alert: CNPG Operator Pod not healthy + annotations: + message: CNPG Operator {{"{{"}} $labels.pod {{"}}"}} pod in namespace {{ dsc.cloudnativepg.namespace }} has been unavailable for the last 5 minutes. + summary: CNPG Operator {{"{{"}} $labels.pod {{"}}"}} pod not healthy (container {{"{{"}} $labels.container {{"}}"}} is not ready) + expr: | + kube_pod_container_status_ready{ + pod=~"cloudnative-pg(-.*)*", + namespace="{{ dsc.cloudnativepg.namespace }}"} == 0 + for: 5m + labels: + severity: critical diff --git a/roles/cloudnativepg/templates/values/10-registry.j2 b/roles/cloudnativepg/templates/values/10-registry.j2 index 4f14b93c..d47b426d 100644 --- a/roles/cloudnativepg/templates/values/10-registry.j2 +++ b/roles/cloudnativepg/templates/values/10-registry.j2 @@ -2,3 +2,8 @@ image: repository: "{{ dsc.global.registry }}/cloudnative-pg/cloudnative-pg" {% endif %} + +{% if use_image_pull_secrets %} +imagePullSecrets: +- name: dso-config-pull-secret +{% endif %} \ No newline at end of file diff --git a/roles/cluster-offline/tasks/main.yml b/roles/cluster-offline/tasks/main.yml index 3a2dcadc..2cddc9df 100644 --- a/roles/cluster-offline/tasks/main.yml +++ b/roles/cluster-offline/tasks/main.yml @@ -5,11 +5,11 @@ - dsc.sonarqube.pluginDownloadUrl != "" fail_msg: "'dsc.sonarqube.pluginDownloadUrl' must not be empty" -- name: Validate dsc.sonarqube.PrometheusJavaagentVersion is not empty +- name: Validate dsc.sonarqube.prometheusJavaagentVersion is not empty assert: that: - - dsc.sonarqube.PrometheusJavaagentVersion != "" - fail_msg: "'dsc.sonarqube.PrometheusJavaagentVersion' must not be empty" + - dsc.sonarqube.prometheusJavaagentVersion != "" + fail_msg: "'dsc.sonarqube.prometheusJavaagentVersion' must not be empty" - name: Validate dsc.gitlabCatalog.catalogRepoUrl is different than default assert: @@ -17,14 +17,14 @@ - dsc.gitlabCatalog.catalogRepoUrl != "https://github.com/cloud-pi-native/gitlab-ci-catalog.git" fail_msg: "'dsc.gitlabCatalog.catalogRepoUrl' is same as 'https://github.com/cloud-pi-native/gitlab-ci-catalog.git'" -- name: Validate dsc.console.consoleRepoUrl is different than default +- name: Validate dsc.console.helmRepoUrl is different than default assert: that: - - dsc.console.consoleRepoUrl != "https://github.com/cloud-pi-native/console.git" - fail_msg: "'dsc.console.consoleRepoUrl' is same as 'https://github.com/cloud-pi-native/console.git'" + - dsc.console.helmRepoUrl != "https://cloud-pi-native.github.io/helm-charts" + fail_msg: "'dsc.console.helmRepoUrl' is same as 'https://cloud-pi-native.github.io/helm-charts'" - name: Validate dsc.argocd.privateGitlabDomain is not empty assert: that: - dsc.argocd.privateGitlabDomain != "" - fail_msg: "'dsc.argocd.privateGitlabDomain' is empty" + fail_msg: "'dsc.argocd.privateGitlabDomain' is empty" diff --git a/roles/console-dso-config/tasks/main.yml b/roles/console-dso-config/tasks/main.yml index 467b3617..795915b0 100644 --- a/roles/console-dso-config/tasks/main.yml +++ b/roles/console-dso-config/tasks/main.yml @@ -32,3 +32,17 @@ # VAULT_TOKEN: roles/vault/tasks/main.yaml ARGO_NAMESPACE: "{{ dsc.argocd.namespace | b64encode }}" PROJECTS_ROOT_DIR: "{{ dsc.global.projectsRootDir | join('/') | b64encode }}" + +- name: Create imagePullSecret secret + kubernetes.core.k8s: + definition: + kind: Secret + metadata: + name: dso-config-pull-secret + labels: + ns.kyverno.io/all-sync: "" # Share secret for all dso namespaces + namespace: "default" + type: kubernetes.io/dockerconfigjson + data: + .dockerconfigjson: "{{ dsc.global.imagePullSecretsData }}" + when: use_image_pull_secrets diff --git a/roles/console-dso/tasks/main.yaml b/roles/console-dso/tasks/main.yaml index b28755c5..c7336858 100644 --- a/roles/console-dso/tasks/main.yaml +++ b/roles/console-dso/tasks/main.yaml @@ -52,20 +52,20 @@ - name: CNPG s3 CA (secret) when: > - dsc.global.backup.cnpg.enabled and + dsc.global.backup.cnpg.enabled and dsc.global.backup.cnpg.endpointCA.namespace is defined and dsc.global.backup.cnpg.endpointCA.name is defined and dsc.global.backup.cnpg.endpointCA.key is defined block: - name: Get secret kubernetes.core.k8s_info: - name: "{{ dsc.global.backup.cnpg.endpointCA.name }}" - namespace: "{{ dsc.global.backup.cnpg.endpointCA.namespace }}" + name: "{{ dsc.global.backup.endpointCa.name }}" + namespace: "{{ dsc.global.backup.endpointCa.namespace }}" kind: Secret register: cnpg_s3_ca_resource - name: Extract key - ansible.builtin.set_fact: + ansible.builtin.set_fact: cnpg_s3_ca_pem: "{{ cnpg_s3_ca_resource.resources[0].data[dsc.global.backup.cnpg.endpointCA.key] }}" - name: Set cnpg bundle-ca secret @@ -80,14 +80,14 @@ - name: Set cnpg backup secret kubernetes.core.k8s: - name: "{{ dsc.global.backup.cnpg.s3Credentials.name }}" + name: "{{ dsc.global.backup.s3Credentials.name }}" namespace: "{{ dsc.console.namespace }}" kind: Secret api_version: v1 definition: data: - accessKeyId: "{{ dsc.global.backup.cnpg.s3Credentials.accessKeyId.value | b64encode }}" - secretAccessKey: "{{ dsc.global.backup.cnpg.s3Credentials.secretAccessKey.value | b64encode }}" + accessKeyId: "{{ dsc.global.backup.s3Credentials.accessKeyId.value | b64encode }}" + secretAccessKey: "{{ dsc.global.backup.s3Credentials.secretAccessKey.value | b64encode }}" when: dsc.global.backup.cnpg.enabled - name: Remove cnpg scheduled backup @@ -122,7 +122,7 @@ kubernetes.core.k8s: template: app.yaml.j2 -- block: +- block: - name: Set first_console_deployment to "true" ansible.builtin.set_fact: first_console_deployment: true @@ -136,9 +136,9 @@ until: pg_db_secret.resources[0].data.uri is defined retries: 10 delay: 5 - when: pg_db_secret.resources[0].data.uri is undefined + when: pg_db_secret.resources[0].data.uri is undefined -- block: +- block: - name: Compute Console Helm values ansible.builtin.include_role: name: combine @@ -151,3 +151,8 @@ kubernetes.core.k8s: template: app.yaml.j2 when: first_console_deployment is defined + +- name: Set alerting rules + when: dsc.global.alerting.enabled + kubernetes.core.k8s: + template: prometheusrule.yml.j2 diff --git a/roles/console-dso/templates/app.yaml.j2 b/roles/console-dso/templates/app.yaml.j2 index 1f6e9ebb..c7e3142b 100644 --- a/roles/console-dso/templates/app.yaml.j2 +++ b/roles/console-dso/templates/app.yaml.j2 @@ -12,7 +12,7 @@ spec: project: console-pi-native source: chart: cpn-console - repoURL: "{{ dsc.console.consoleRepoUrl }}" + repoURL: "{{ dsc.console.helmRepoUrl }}" targetRevision: {{ dsc.console.release }} helm: releaseName: dso diff --git a/roles/console-dso/templates/project.j2 b/roles/console-dso/templates/project.j2 index 03d88dda..4e870ecb 100644 --- a/roles/console-dso/templates/project.j2 +++ b/roles/console-dso/templates/project.j2 @@ -34,4 +34,4 @@ spec: policies: - p, proj:console-pi-native:admin-RW, applications, *, console-pi-native/*, allow sourceRepos: - - "{{ dsc.console.consoleRepoUrl }}" + - "{{ dsc.console.helmRepoUrl }}" diff --git a/roles/console-dso/templates/prometheusrule.yml.j2 b/roles/console-dso/templates/prometheusrule.yml.j2 new file mode 100644 index 00000000..1faa038c --- /dev/null +++ b/roles/console-dso/templates/prometheusrule.yml.j2 @@ -0,0 +1,97 @@ +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + labels: + app.kubernetes.io/name: gitlab + name: console-dso + namespace: {{ dsc.console.namespace }} +spec: + groups: + - name: Console DSO + rules: + - alert: DSO Console client not available + annotations: + message: DSO Console client in namespace {{ dsc.console.namespace }} has not been available for the last 5 minutes. + summary: DSO Console client down (no ready pod)" + expr: | + sum(kube_pod_status_ready{ + pod=~"dso-cpn-console-client-.*", + namespace="{{ dsc.console.namespace }}", + condition="true"}) == 0 + for: 5m + labels: + severity: critical + - alert: DSO Console server not available + annotations: + message: DSO Console server in namespace {{ dsc.console.namespace }} has not been available for the last 5 minutes. + summary: DSO Console server down (no ready pod)" + expr: | + sum(kube_pod_status_ready{ + pod=~"dso-cpn-console-server-.*", + namespace="{{ dsc.console.namespace }}", + condition="true"}) == 0 + for: 5m + labels: + severity: critical + - alert: DSO Console Pod not healthy + annotations: + message: DSO Console {{"{{"}} $labels.pod {{"}}"}} pod in namespace {{ dsc.console.namespace }} has been unavailable for the last 5 minutes. + summary: DSO Console {{"{{"}} $labels.pod {{"}}"}} pod not healthy (container {{"{{"}} $labels.container {{"}}"}} is not ready) + expr: | + kube_pod_container_status_ready{ + pod=~"dso-cpn-console-.*", + namespace="{{ dsc.console.namespace }}"} == 0 + for: 5m + labels: + severity: warning + - alert: DSO Console DB not available + annotations: + message: All DSO Console CNPG pods in namespace {{ dsc.console.namespace }} have been unavailable for the last 5 minutes. + summary: DSO Console database down (containers not ready) + expr: | + (absent(kube_pod_container_status_ready{ + pod=~"pg-cluster-console-\\d+", + container="postgres", namespace="{{ dsc.console.namespace }}"}) == 1) + or sum(kube_pod_container_status_ready{ + pod=~"pg-cluster-console-\\d+", + container="postgres", namespace="{{ dsc.console.namespace }}"}) == 0 + for: 5m + labels: + severity: critical + - alert: DSO Console DB Pod not healthy + annotations: + message: DSO Console {{"{{"}} $labels.pod {{"}}"}} pod in namespace {{ dsc.console.namespace }} has been unavailable for the last 5 minutes. + summary: DSO Console database pod not healthy (container is not ready) + expr: | + kube_pod_container_status_ready{ + pod=~"pg-cluster-console-\\d+", + container="postgres", namespace="{{ dsc.console.namespace }}"} == 0 + for: 5m + labels: + severity: warning + - alert: DSO Console PVC almost out of disk space + annotations: + message: PVC {{"{{"}} $labels.persistentvolumeclaim {{"}}"}} in namespace {{ dsc.console.namespace }} is almost full (< 10% left). VALUE = {{"{{"}} $value {{"}}"}}% + summary: DSO Console PVC almost out of disk space in namespace {{ dsc.console.namespace }} + expr: | + round( + kubelet_volume_stats_available_bytes{ + persistentvolumeclaim=~"(.*-)*console(-.*)*", + namespace="{{ dsc.console.namespace }}"} + / kubelet_volume_stats_capacity_bytes{ + persistentvolumeclaim=~"(.*-)*console(-.*)*", + namespace="{{ dsc.console.namespace }}"} * 100, 0.01) < 10 > 0 + for: 1m + labels: + severity: warning + - alert: DSO Console PVC out of disk space + annotations: + message: PVC {{"{{"}} $labels.persistentvolumeclaim {{"}}"}} in namespace {{ dsc.console.namespace }} is full (0% left). + summary: DSO Console PVC out of disk space in namespace {{ dsc.console.namespace }} + expr: | + kubelet_volume_stats_available_bytes{ + persistentvolumeclaim=~"(.*-)*console(-.*)*", + namespace="{{ dsc.console.namespace }}"} == 0 + for: 1m + labels: + severity: critical diff --git a/roles/console-dso/templates/values/00-main.j2 b/roles/console-dso/templates/values/00-main.j2 index c241b000..27f106fd 100644 --- a/roles/console-dso/templates/values/00-main.j2 +++ b/roles/console-dso/templates/values/00-main.j2 @@ -30,20 +30,35 @@ server: cnpg: enabled: true nameOverride: pg-cluster-console + username: dso + dbName: dso-console-db + mode: "{{ dsc.console.cnpg.mode }}" +{% if dsc.global.backup.velero.enabled %} + annotations: + pre.hook.backup.velero.io/command: '["/bin/bash", "-c", "(( $(date +%d) %2 == 0 )) && index=0 || index=1; pg_dump -U postgres -Fc -d dso-console-db > /var/lib/postgresql/data/app.dump-${index}"]' + pre.hook.backup.velero.io/container: postgres + pre.hook.backup.velero.io/on-error: Fail + pre.hook.backup.velero.io/timeout: 90s +{% endif %} {% if dsc.global.backup.cnpg.enabled %} backup: enabled: "{{ dsc.global.backup.cnpg.enabled }}" - destinationPath: "s3://{{ dsc.global.backup.cnpg.destinationPath }}console" - endpointURL: "{{ dsc.global.backup.cnpg.endpointURL }}" + destinationPath: "s3://{{ dsc.global.backup.s3.bucketName }}/{{ dsc.global.backup.cnpg.pathPrefix }}" + endpointURL: "{{ dsc.global.backup.s3.endpointUrl }}" +{% if dsc.exposedCA.type != 'none' %} endpointCA: name: "bundle-cnpg-s3" key: "ca.pem" +{% endif %} s3Credentials: - name: "{{ dsc.global.backup.cnpg.s3Credentials.name }}" + create: true + secretName: "{{ dsc.global.backup.s3.credentials.name }}" accessKeyId: - key: "{{ dsc.global.backup.cnpg.s3Credentials.accessKeyId.key }}" + key: "{{ dsc.global.backup.s3.credentials.accessKeyId.key }}" + value: "{{ dsc.global.backup.s3.credentials.accessKeyId.value }}" secretAccessKey: - key: "{{ dsc.global.backup.cnpg.s3Credentials.secretAccessKey.key }}" + key: "{{ dsc.global.backup.s3.credentials.secretAccessKey.key }}" + value: "{{ dsc.global.backup.s3.credentials.secretAccessKey.value }}" cron: "{{ dsc.global.backup.cnpg.cron }}" retentionPolicy: "{{ dsc.global.backup.cnpg.retentionPolicy }}" {% endif %} diff --git a/roles/console-dso/templates/values/10-profile.j2 b/roles/console-dso/templates/values/10-profile.j2 new file mode 100644 index 00000000..88a1f62d --- /dev/null +++ b/roles/console-dso/templates/values/10-profile.j2 @@ -0,0 +1,25 @@ +{% if dsc.global.profile is defined and dsc.global.profile == "cis" %} +client: + container: + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + runAsNonRoot: true + runAsUser: 1001 + seccompProfile: + type: RuntimeDefault + +server: + container: + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + runAsNonRoot: true + runAsUser: 1000 + seccompProfile: + type: RuntimeDefault +{% endif %} diff --git a/roles/console-dso/templates/values/10-proxy.j2 b/roles/console-dso/templates/values/10-proxy.j2 index c5b93dd8..e264c69f 100644 --- a/roles/console-dso/templates/values/10-proxy.j2 +++ b/roles/console-dso/templates/values/10-proxy.j2 @@ -1,4 +1,4 @@ -{% if dsc.proxy.enabled %} +{% if dsc.proxy.enabled and dsc.global.offline != true %} global: env: HTTP_PROXY: {{ dsc.proxy.http_proxy }} diff --git a/roles/console-dso/templates/values/10-registry.j2 b/roles/console-dso/templates/values/10-registry.j2 index 9bae1ed2..3bd1db7b 100644 --- a/roles/console-dso/templates/values/10-registry.j2 +++ b/roles/console-dso/templates/values/10-registry.j2 @@ -11,3 +11,10 @@ postgres: container: image: "{{ dsc.global.registry }}/postgres:15.3" {% endif %} + + +{% if use_image_pull_secrets %} +global: + imagePullSecrets: + - dso-config-pull-secret +{% endif %} \ No newline at end of file diff --git a/roles/gitlab-catalog/tasks/main.yaml b/roles/gitlab-catalog/tasks/main.yaml index 587cc919..fcd29461 100644 --- a/roles/gitlab-catalog/tasks/main.yaml +++ b/roles/gitlab-catalog/tasks/main.yaml @@ -12,17 +12,6 @@ when: ansible_inventory.resources[0].data.GITLAB_TOKEN is defined and ansible_inventory.resources[0].data.GITLAB_TOKEN | length != 0 register: set_token_inv -- name: Create Catalog - community.general.gitlab_project: - api_url: https://{{ gitlab_domain }} - api_token: "{{ gitlab_token }}" - validate_certs: "{{ dsc.exposedCA.type == 'none' }}" - import_url: "{{ dsc.gitlabCatalog.catalogRepoUrl }}" - name: Catalog - path: catalog - group: "{{ dsc.global.projectsRootDir | join('/') }}" - visibility: internal - - name: Clone Git repository as bare ansible.builtin.git: repo: "{{ dsc.gitlabCatalog.catalogRepoUrl }}" @@ -38,3 +27,14 @@ git push --mirror "https://admin:{{ gitlab_token }}@{{ gitlab_domain }}/{{ dsc.global.projectsRootDir | join('/') }}/catalog" args: chdir: /tmp/test + +- name: Update Catalog visibility and path + community.general.gitlab_project: + api_url: https://{{ gitlab_domain }} + api_token: "{{ gitlab_token }}" + validate_certs: "{{ dsc.exposedCA.type == 'none' }}" + import_url: "{{ dsc.gitlabCatalog.catalogRepoUrl }}" + name: Catalog + path: catalog + group: "{{ dsc.global.projectsRootDir | join('/') }}" + visibility: internal diff --git a/roles/gitlab-ci-pipelines-exporter/tasks/main.yaml b/roles/gitlab-ci-pipelines-exporter/tasks/main.yaml index b1b11661..0e49e979 100644 --- a/roles/gitlab-ci-pipelines-exporter/tasks/main.yaml +++ b/roles/gitlab-ci-pipelines-exporter/tasks/main.yaml @@ -2,7 +2,7 @@ - name: GitLab CI Pipelines Exporter installation when: dsc.global.metrics.enabled - block: + block: - name: Get Gitlab namespace kubernetes.core.k8s_info: kind: Namespace @@ -28,7 +28,8 @@ - name: Add GitLab CI Pipelines Exporter helm repo kubernetes.core.helm_repository: name: mvisonneau - repo_url: https://charts.visonneau.fr + repo_url: "{{ dsc.gitlabCiPipelinesExporter.helmRepoUrl }}" + force_update: true - name: Set path fact ansible.builtin.set_fact: diff --git a/roles/gitlab-operator/tasks/main.yaml b/roles/gitlab-operator/tasks/main.yaml index 062a17a8..f96ed7ff 100644 --- a/roles/gitlab-operator/tasks/main.yaml +++ b/roles/gitlab-operator/tasks/main.yaml @@ -41,7 +41,11 @@ needs_update: true - name: Install GitLab Operator - when: (gl_api == 'absent') or (gl_vwhc.resources | length == 0) or (needs_update) + when: > + gl_api == 'absent' or + gl_vwhc.resources | length == 0 or + needs_update or + dsc.gitlabOperator.forcedInstall block: - name: Create GitLab Operator namespace kubernetes.core.k8s: @@ -53,7 +57,8 @@ - name: Add GitLab Operator helm repo kubernetes.core.helm_repository: name: gitlab-operator - repo_url: https://gitlab.com/api/v4/projects/18899486/packages/helm/stable + repo_url: "{{ dsc.gitlabOperator.helmRepoUrl }}" + force_update: true - name: Set GitLab Operator helm values ansible.builtin.set_fact: @@ -66,24 +71,6 @@ chart_version: "{{ dsc.gitlabOperator.chartVersion }}" release_namespace: "{{ dsc.gitlabOperator.namespace }}" values: "{{ operator_values }}" - when: not use_private_registry - - - name: Generate post_renderer script - template: - src: post_renderer_template.j2 - dest: /tmp/yq_script.sh - mode: 0755 - when: use_private_registry - - - name: Deploy GitLab Operator helm - kubernetes.core.helm: - name: gitlab-operator - chart_ref: gitlab-operator/gitlab-operator - chart_version: "{{ dsc.gitlabOperator.chartVersion }}" - release_namespace: "{{ dsc.gitlabOperator.namespace }}" - values: "{{ operator_values }}" - post_renderer: /tmp/yq_script.sh - when: use_private_registry - name: Wait gitlab-webhook-service endpoint kubernetes.core.k8s_info: @@ -94,3 +81,8 @@ until: endpoint.resources[0].subsets[0].addresses[0] is defined retries: 15 delay: 5 + + - name: Set alerting rules + when: dsc.global.alerting.enabled + kubernetes.core.k8s: + template: prometheusrule.yml.j2 diff --git a/roles/gitlab-operator/templates/post_renderer_template.j2 b/roles/gitlab-operator/templates/post_renderer_template.j2 deleted file mode 100644 index 5192c3d4..00000000 --- a/roles/gitlab-operator/templates/post_renderer_template.j2 +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -rm -f /tmp/all.yaml -cat <&0 > /tmp/all.yaml -yq eval '.spec.template.spec.containers[1].image = "{{ dsc.global.registry }}/kubebuilder/kube-rbac-proxy:v0.14.1"' /tmp/all.yaml 2> /dev/null && rm /tmp/all.yaml diff --git a/roles/gitlab-operator/templates/prometheusrule.yml.j2 b/roles/gitlab-operator/templates/prometheusrule.yml.j2 new file mode 100644 index 00000000..ccbcf06c --- /dev/null +++ b/roles/gitlab-operator/templates/prometheusrule.yml.j2 @@ -0,0 +1,22 @@ +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + labels: + app.kubernetes.io/name: gitlab + name: gitlab-operator + namespace: {{ dsc.gitlabOperator.namespace }} +spec: + groups: + - name: GitLab Operator + rules: + - alert: GitLab Operator Pod not healthy + annotations: + message: GitLab Operator {{"{{"}} $labels.pod {{"}}"}} pod in namespace {{ dsc.gitlabOperator.namespace }} has been unavailable for the last 5 minutes. + summary: GitLab Operator {{"{{"}} $labels.pod {{"}}"}} pod not healthy (container {{"{{"}} $labels.container {{"}}"}} is not ready) + expr: | + kube_pod_container_status_ready{ + pod=~"gitlab-controller-manager(-.*)*", + namespace="{{ dsc.gitlabOperator.namespace }}"} == 0 + for: 5m + labels: + severity: critical diff --git a/roles/gitlab-operator/templates/values.yaml.j2 b/roles/gitlab-operator/templates/values.yaml.j2 index 88ac99e0..82274e7e 100644 --- a/roles/gitlab-operator/templates/values.yaml.j2 +++ b/roles/gitlab-operator/templates/values.yaml.j2 @@ -1,7 +1,7 @@ watchCluster: true image: -{% if use_private_registry %} +{% if use_private_registry %} registry: "{{ dsc.global.registry }}" {% else %} registry: registry.gitlab.com @@ -36,6 +36,11 @@ tolerations: [] manager: debug: enabled: true +{% if use_private_registry %} + kubeRbacProxy: + image: + registry: "{{ dsc.global.registry }}" +{% endif %} serviceAccount: # Specifies whether a service account should be created create: true diff --git a/roles/gitlab-runner/tasks/main.yaml b/roles/gitlab-runner/tasks/main.yaml index aa860a0c..de2a0500 100644 --- a/roles/gitlab-runner/tasks/main.yaml +++ b/roles/gitlab-runner/tasks/main.yaml @@ -41,7 +41,8 @@ - name: Add GitLab Runner helm repo kubernetes.core.helm_repository: name: gitlab - repo_url: https://charts.gitlab.io + repo_url: "{{ dsc.gitlabRunner.helmRepoUrl }}" + force_update: true - name: Create gitlab-runner role kubernetes.core.k8s: diff --git a/roles/gitlab-runner/templates/values/00-main.j2 b/roles/gitlab-runner/templates/values/00-main.j2 index c5594b7b..e4782594 100644 --- a/roles/gitlab-runner/templates/values/00-main.j2 +++ b/roles/gitlab-runner/templates/values/00-main.j2 @@ -57,6 +57,27 @@ runners: image = "ubuntu:22.04" # multiple "always" to retry pull on fail (see. https://docs.gitlab.com/runner/executors/kubernetes.html#set-a-pull-policy) pull_policy = ["always", "always"] +{% if dsc.gitlabRunner.resources is defined and dsc.gitlabRunner.resources != 'none' %} + # request and limit of build pod and override allowed in ci + {% if dsc.gitlabRunner.resources.requests is defined and dsc.gitlabRunner.resources.requests != 'none' %} + cpu_request = "{{ dsc.gitlabRunner.resources.requests.cpu }}" + memory_request = "{{ dsc.gitlabRunner.resources.requests.memory }}" + {% endif %} + {% if dsc.gitlabRunner.resources.limits is defined and dsc.gitlabRunner.resources.limits != 'none' %} + cpu_limit = "{{ dsc.gitlabRunner.resources.limits.cpu }}" + memory_limit = "{{ dsc.gitlabRunner.resources.limits.memory }}" + {% endif %} + {% if dsc.gitlabRunner.resources.overwrite != 'none' %} + {% if dsc.gitlabRunner.resources.overwrite.requests != 'none' %} + cpu_request_overwrite_max_allowed = "{{ dsc.gitlabRunner.resources.overwrite.requests.cpu }}" + memory_request_overwrite_max_allowed = "{{ dsc.gitlabRunner.resources.overwrite.requests.memory }}" + {% endif %} + {% if dsc.gitlabRunner.resources.overwrite.limits != 'none' %} + memory_limit_overwrite_max_allowed = "{{ dsc.gitlabRunner.resources.overwrite.limits.cpu }}" + cpu_limit_overwrite_max_allowed = "{{ dsc.gitlabRunner.resources.overwrite.limits.memory }}" + {% endif %} + {% endif %} +{% endif %} ## Specify the name for the runner. name: gitlab-runner diff --git a/roles/gitlab/tasks/main.yaml b/roles/gitlab/tasks/main.yaml index 9c17d37f..1adcc162 100644 --- a/roles/gitlab/tasks/main.yaml +++ b/roles/gitlab/tasks/main.yaml @@ -6,6 +6,95 @@ kind: Namespace state: present +- name: CNPG s3 CA (secret) + when: > + dsc.global.backup.cnpg.enabled and + dsc.global.backup.cnpg.endpointCA.namespace is defined and + dsc.global.backup.cnpg.endpointCA.name is defined and + dsc.global.backup.cnpg.endpointCA.key is defined + block: + - name: Get secret + kubernetes.core.k8s_info: + name: "{{ dsc.global.backup.endpointCa.name }}" + namespace: "{{ dsc.global.backup.endpointCa.namespace }}" + kind: Secret + register: cnpg_s3_ca_resource + + - name: Extract key + ansible.builtin.set_fact: + cnpg_s3_ca_pem: "{{ cnpg_s3_ca_resource.resources[0].data[dsc.global.backup.cnpg.endpointCA.key] }}" + + - name: Set cnpg bundle-ca secret + kubernetes.core.k8s: + name: "bundle-cnpg-s3" + namespace: "{{ dsc.gitlab.namespace }}" + kind: Secret + api_version: v1 + definition: + data: + ca.pem: "{{ cnpg_s3_ca_pem }}" + +- name: Set cnpg backup secret + kubernetes.core.k8s: + name: "{{ dsc.global.backup.s3Credentials.name }}" + namespace: "{{ dsc.gitlab.namespace }}" + kind: Secret + api_version: v1 + definition: + data: + accessKeyId: "{{ dsc.global.backup.s3Credentials.accessKeyId.value | b64encode }}" + secretAccessKey: "{{ dsc.global.backup.s3Credentials.secretAccessKey.value | b64encode }}" + when: dsc.global.backup.cnpg.enabled + +- name: Remove cnpg scheduled backup + kubernetes.core.k8s: + api_version: v1 + kind: ScheduledBackup + namespace: "{{ dsc.gitlab.namespace }}" + name: pg-cluster-gitlab + state: absent + when: not dsc.global.backup.cnpg.enabled + +- name: Create PostgreSQL cluster and gitlab database + kubernetes.core.k8s: + template: "{{ item }}" + with_items: + - pg-cluster-gitlab.yaml.j2 + - pg-cluster-gitlab-backup.yaml.j2 + - pg-cluster-gitlab-nodeport.yaml.j2 + +- name: Wait pg-cluster-gitlab-rw endpoint + kubernetes.core.k8s_info: + kind: Endpoints + namespace: "{{ dsc.gitlab.namespace }}" + name: pg-cluster-gitlab-rw + register: endpoint + until: endpoint.resources[0].subsets[0].addresses[0] is defined + retries: 30 + delay: 5 + +- name: Wait job.batch/pg-cluster-gitlab-1-initdb to be terminated + kubernetes.core.k8s_info: + kind: Job + api_version: batch/v1 + namespace: "{{ dsc.gitlab.namespace }}" + name: pg-cluster-gitlab-1-initdb + register: job1 + until: job1.resources | length == 0 + retries: 30 + delay: 5 + +- name: Wait job.batch/pg-cluster-gitlab-2-join to be terminated + kubernetes.core.k8s_info: + kind: Job + api_version: batch/v1 + namespace: "{{ dsc.gitlab.namespace }}" + name: pg-cluster-gitlab-2-join + register: job2 + until: job2.resources | length == 0 + retries: 30 + delay: 5 + - name: Get existing control-plane deployments kubernetes.core.k8s_info: kind: Deployment @@ -328,26 +417,18 @@ namespace: "{{ dsc.gitlab.namespace }}" register: gitlab_pods - - name: Get Gitlab ServiceMonitors - kubernetes.core.k8s_info: - api_version: monitoring.coreos.com/v1 - kind: ServiceMonitor - namespace: "{{ dsc.gitlab.namespace }}" - register: service_monitors - - name: Get Gitlab endpoints kubernetes.core.k8s_info: kind: Endpoints namespace: "{{ dsc.gitlab.namespace }}" register: endpoints - - name: Patch existing ServiceMonitors - ansible.builtin.include_tasks: - file: patch-servicemonitors.yaml - loop: "{{ gitlab_service_monitors }}" - - name: Declare some additionnal ServiceMonitors ansible.builtin.include_tasks: file: add-servicemonitors.yaml loop: "{{ gitlab_additional_service_monitors }}" +- name: Set alerting rules + when: dsc.global.alerting.enabled + kubernetes.core.k8s: + template: prometheusrule.yml.j2 diff --git a/roles/gitlab/tasks/patch-servicemonitors.yaml b/roles/gitlab/tasks/patch-servicemonitors.yaml deleted file mode 100644 index 65bc4365..00000000 --- a/roles/gitlab/tasks/patch-servicemonitors.yaml +++ /dev/null @@ -1,32 +0,0 @@ ---- -- name: Get metrics endpoint port name - ansible.builtin.set_fact: - metrics_port_name: "{{ endpoints.resources - | selectattr('metadata.name', 'contains', item.name) - | selectattr('metadata.name', 'contains', item.metrics_endpoint_name | default(item.name)) - | map(attribute='subsets') | first - | map(attribute='ports') | first - | selectattr('port', 'equalto', item.port) - | map(attribute='name') | first }}" - -- name: Get Service Monitor name - ansible.builtin.set_fact: - service_monitor: "{{ service_monitors.resources - | selectattr('metadata.name', 'contains', item.name) - | map(attribute='metadata.name') | first }}" - -- name: Patch ServiceMonitor - kubernetes.core.k8s: - api_version: monitoring.coreos.com/v1 - kind: ServiceMonitor - namespace: "{{ dsc.gitlab.namespace }}" - name: "{{ service_monitor }}" - state: patched - definition: - spec: - endpoints: - - bearerTokenSecret: - key: "" - interval: 30s - path: "{{item.path}}" - port: "{{ metrics_port_name }}" diff --git a/roles/gitlab/templates/pg-cluster-gitlab-backup.yaml.j2 b/roles/gitlab/templates/pg-cluster-gitlab-backup.yaml.j2 new file mode 100644 index 00000000..a2ce259b --- /dev/null +++ b/roles/gitlab/templates/pg-cluster-gitlab-backup.yaml.j2 @@ -0,0 +1,13 @@ +--- +{% if dsc.global.backup.cnpg.enabled %} +apiVersion: postgresql.cnpg.io/v1 +kind: ScheduledBackup +metadata: + name: pg-cluster-gitlab + namespace: {{ dsc.gitlab.namespace }} +spec: + schedule: "{{ dsc.global.backup.cnpg.cron }}" + backupOwnerReference: self + cluster: + name: pg-cluster-gitlab +{% endif %} diff --git a/roles/gitlab/templates/pg-cluster-gitlab-nodeport.yaml.j2 b/roles/gitlab/templates/pg-cluster-gitlab-nodeport.yaml.j2 new file mode 100644 index 00000000..9fadecda --- /dev/null +++ b/roles/gitlab/templates/pg-cluster-gitlab-nodeport.yaml.j2 @@ -0,0 +1,20 @@ +--- +{% if dsc.gitlab.cnpg.exposed %} +apiVersion: v1 +kind: Service +metadata: + labels: + cnpg.io/cluster: pg-cluster-gitlab + name: pg-cluster-gitlab-rw-nodeport + namespace: {{ dsc.gitlab.namespace }} +spec: + ports: + - name: postgres + port: 5432 + protocol: TCP + nodePort: {{ dsc.gitlab.cnpg.nodePort }} + selector: + cnpg.io/cluster: pg-cluster-gitlab + role: primary + type: NodePort +{% endif %} diff --git a/roles/gitlab/templates/pg-cluster-gitlab.yaml.j2 b/roles/gitlab/templates/pg-cluster-gitlab.yaml.j2 new file mode 100644 index 00000000..39da3bcf --- /dev/null +++ b/roles/gitlab/templates/pg-cluster-gitlab.yaml.j2 @@ -0,0 +1,112 @@ +--- +apiVersion: postgresql.cnpg.io/v1 +kind: Cluster +metadata: + name: pg-cluster-gitlab + namespace: {{ dsc.gitlab.namespace }} +{% if dsc.global.backup.velero.enabled %} + annotations: + pre.hook.backup.velero.io/command: '["/bin/bash", "-c", "(( $(date +%d) %2 == 0 )) && index=0 || index=1; pg_dump -U postgres -Fc -d gitlabhq_production > /var/lib/postgresql/data/app.dump-${index}"]' + pre.hook.backup.velero.io/container: postgres + pre.hook.backup.velero.io/on-error: Fail + pre.hook.backup.velero.io/timeout: 90s +{% endif %} +spec: + instances: 3 + # Parameters and pg_hba configuration will be append + # to the default ones to make the cluster work +{% if use_private_registry %} + imageName: "{{ dsc.global.registry }}/cloudnative-pg/postgresql:16.1" +{% endif %} +{% if use_image_pull_secrets %} + imagePullSecrets: + - name: dso-config-pull-secret +{% endif %} + postgresql: + parameters: + max_worker_processes: "60" +{% if dsc.gitlab.cnpg.mode == "primary" %} + pg_hba: + # To access through TCP/IP you will need to get username + # and password from the secret pg-cluster-gitlab-app + - host gitlabhq_production gitlab all md5 + - host gitlabhq_production streaming_replica all md5 +{% endif %} + bootstrap: +{% if dsc.gitlab.cnpg.mode == "primary" %} + initdb: + database: gitlabhq_production + owner: gitlab + recovery: null +{% elif dsc.gitlab.cnpg.mode == "replica" or dsc.gitlab.cnpg.mode == "restore" %} + recovery: + source: pg-cluster-gitlab + database: gitlabhq_production + owner: gitlab + initdb: null + externalClusters: + - name: pg-cluster-gitlab +{% if dsc.gitlab.cnpg.mode == "restore" %} + barmanObjectStore: + destinationPath: "s3://{{ dsc.global.backup.s3.bucketName }}/{{ dsc.global.backup.cnpg.pathPrefix }}" + endpointURL: "{{ dsc.global.backup.s3.endpointUrl }}" +{% if dsc.exposedCA.type != 'none' %} + endpointCA: + name: "bundle-cnpg-s3" + key: "ca.pem" +{% endif %} + s3Credentials: + accessKeyId: + name: "{{ dsc.global.backup.s3.credentials.name }}" + key: "{{ dsc.global.backup.s3.credentials.accessKeyId.key }}" + secretAccessKey: + name: "{{ dsc.global.backup.s3.credentials.name }}" + key: "{{ dsc.global.backup.s3.credentials.secretAccessKey.key }}" +{% endif %} +{% if dsc.gitlab.cnpg.mode == "replica" %} +{%- filter indent(width=4) %} +{{ dsc.gitlab.cnpg.connectionParameters }} +{%- endfilter %} +{% endif %} +{% endif %} + +{% if dsc.gitlab.cnpg.mode == "replica" %} + replica: + enabled: true + source: pg-cluster-gitlab +{% endif %} + + enableSuperuserAccess: true + # Example of rolling update strategy: + # - unsupervised: automated update of the primary once all + # replicas have been upgraded (default) + # - supervised: requires manual supervision to perform + # the switchover of the primary + primaryUpdateStrategy: unsupervised + # Require 1Gi of space per instance using default storage class + storage: + size: {{ dsc.gitlab.postgresPvcSize }} + monitoring: + enablePodMonitor: {{ dsc.global.metrics.enabled }} + +{% if dsc.global.backup.cnpg.enabled %} + backup: + barmanObjectStore: + destinationPath: "s3://{{ dsc.global.backup.s3.bucketName }}/{{ dsc.global.backup.cnpg.pathPrefix }}" + endpointURL: "{{ dsc.global.backup.s3.endpointUrl }}" +{% if dsc.exposedCA.type != 'none' %} + endpointCA: + name: "bundle-cnpg-s3" + key: "ca.pem" +{% endif %} + s3Credentials: + accessKeyId: + name: "{{ dsc.global.backup.s3.credentials.name }}" + key: "{{ dsc.global.backup.s3.credentials.accessKeyId.key }}" + secretAccessKey: + name: "{{ dsc.global.backup.s3.credentials.name }}" + key: "{{ dsc.global.backup.s3.credentials.secretAccessKey.key }}" + retentionPolicy: "{{ dsc.global.backup.cnpg.retentionPolicy }}" +{% else %} + backup: null +{% endif %} diff --git a/roles/gitlab/templates/prometheusrule.yml.j2 b/roles/gitlab/templates/prometheusrule.yml.j2 new file mode 100644 index 00000000..7eec522b --- /dev/null +++ b/roles/gitlab/templates/prometheusrule.yml.j2 @@ -0,0 +1,205 @@ +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + labels: + app.kubernetes.io/name: gitlab + name: gitlab + namespace: {{ dsc.gitlab.namespace }} +spec: + groups: + - name: GitLab + rules: + - alert: GitLab webservice not available + annotations: + message: GitLab webservice in namespace {{ dsc.gitlab.namespace }} has not been available for the last 5 minutes. + summary: GitLab webservice down (no ready pod)" + expr: | + sum(kube_pod_status_ready{ + pod=~"gitlab-webservice-.*", + namespace="{{ dsc.gitlab.namespace }}", + condition="true"}) == 0 + for: 5m + labels: + severity: critical + - alert: GitLab toolbox not available + annotations: + message: GitLab toolbox in namespace {{ dsc.gitlab.namespace }} has not been available for the last 5 minutes. + summary: GitLab toolbox down (no ready pod)" + expr: | + sum(kube_pod_status_ready{ + pod=~"gitlab-toolbox-.*", + namespace="{{ dsc.gitlab.namespace }}", + condition="true"}) == 0 + for: 5m + labels: + severity: critical + - alert: GitLab sidekiq not available + annotations: + message: GitLab sidekiq in namespace {{ dsc.gitlab.namespace }} has not been available for the last 5 minutes. + summary: GitLab sidekiq down (no ready pod)" + expr: | + sum(kube_pod_status_ready{ + pod=~"gitlab-sidekiq-.*", + namespace="{{ dsc.gitlab.namespace }}", + condition="true"}) == 0 + for: 5m + labels: + severity: critical + - alert: GitLab runner not available + annotations: + message: GitLab runner in namespace {{ dsc.gitlab.namespace }} has not been available for the last 5 minutes. + summary: GitLab runner down (no ready pod)" + expr: | + sum(kube_pod_status_ready{ + pod=~"gitlab-runner-.*", + namespace="{{ dsc.gitlab.namespace }}", + condition="true"}) == 0 + for: 5m + labels: + severity: critical + - alert: GitLab redis not available + annotations: + message: GitLab redis in namespace {{ dsc.gitlab.namespace }} has not been available for the last 5 minutes. + summary: GitLab redis down (no ready pod)" + expr: | + sum(kube_pod_status_ready{ + pod=~"gitlab-redis-.*", + namespace="{{ dsc.gitlab.namespace }}", + condition="true"}) == 0 + for: 5m + labels: + severity: critical + - alert: GitLab minio not available + annotations: + message: GitLab minio in namespace {{ dsc.gitlab.namespace }} has not been available for the last 5 minutes. + summary: GitLab minio down (no ready pod)" + expr: | + sum(kube_pod_status_ready{ + pod=~"gitlab-minio-.*", + namespace="{{ dsc.gitlab.namespace }}", + condition="true"}) == 0 + for: 5m + labels: + severity: critical + - alert: GitLab kas not available + annotations: + message: GitLab kas in namespace {{ dsc.gitlab.namespace }} has not been available for the last 5 minutes. + summary: GitLab kas down (no ready pod)" + expr: | + sum(kube_pod_status_ready{ + pod=~"gitlab-kas-.*", + namespace="{{ dsc.gitlab.namespace }}", + condition="true"}) == 0 + for: 5m + labels: + severity: critical + - alert: GitLab shell not available + annotations: + message: GitLab shell in namespace {{ dsc.gitlab.namespace }} has not been available for the last 5 minutes. + summary: GitLab shell down (no ready pod)" + expr: | + sum(kube_pod_status_ready{ + pod=~"gitlab-gitlab-shell-.*", + namespace="{{ dsc.gitlab.namespace }}", + condition="true"}) == 0 + for: 5m + labels: + severity: critical + - alert: GitLab exporter not available + annotations: + message: GitLab exporter in namespace {{ dsc.gitlab.namespace }} has not been available for the last 5 minutes. + summary: GitLab exporter down (no ready pod)" + expr: | + sum(kube_pod_status_ready{ + pod=~"gitlab-gitlab-exporter-.*", + namespace="{{ dsc.gitlab.namespace }}", + condition="true"}) == 0 + for: 5m + labels: + severity: critical + - alert: GitLab gitaly not available + annotations: + message: GitLab gitaly in namespace {{ dsc.gitlab.namespace }} has not been available for the last 5 minutes. + summary: GitLab gitaly down (no ready pod)" + expr: | + sum(kube_pod_status_ready{ + pod=~"gitlab-gitaly-.*", + namespace="{{ dsc.gitlab.namespace }}", + condition="true"}) == 0 + for: 5m + labels: + severity: critical + - alert: GitLab ci-pipelines-exporter not available + annotations: + message: GitLab ci-pipelines-exporter in namespace {{ dsc.gitlab.namespace }} has not been available for the last 5 minutes. + summary: GitLab ci-pipelines-exporter down (no ready pod)" + expr: | + sum(kube_pod_status_ready{ + pod=~"gitlab-ci-pipelines-exporter-.*", + namespace="{{ dsc.gitlab.namespace }}", + condition="true"}) == 0 + for: 5m + labels: + severity: critical + - alert: GitLab Pod not healthy + annotations: + message: GitLab {{"{{"}} $labels.pod {{"}}"}} pod in namespace {{ dsc.gitlab.namespace }} has been unavailable for the last 5 minutes. + summary: GitLab {{"{{"}} $labels.pod {{"}}"}} pod not healthy (container {{"{{"}} $labels.container {{"}}"}} is not ready) + expr: | + kube_pod_container_status_ready{ + pod=~"gitlab-.*", + container!~"gitlab|kubectl|minio-mc|migrations", namespace="{{ dsc.gitlab.namespace }}"} == 0 + for: 5m + labels: + severity: warning + - alert: GitLab DB not available + annotations: + message: All GitLab CNPG pods in namespace {{ dsc.gitlab.namespace }} have been unavailable for the last 5 minutes. + summary: GitLab database down (containers not ready) + expr: | + (absent(kube_pod_container_status_ready{ + pod=~"pg-cluster-gitlab-\\d+", + container="postgres", namespace="{{ dsc.gitlab.namespace }}"}) == 1) + or sum(kube_pod_container_status_ready{ + pod=~"pg-cluster-gitlab-\\d+", + container="postgres", namespace="{{ dsc.gitlab.namespace }}"}) == 0 + for: 5m + labels: + severity: critical + - alert: GitLab DB Pod not healthy + annotations: + message: GitLab {{"{{"}} $labels.pod {{"}}"}} pod in namespace {{ dsc.gitlab.namespace }} has been unavailable for the last 5 minutes. + summary: Gitlab database pod not healthy (container is not ready) + expr: | + kube_pod_container_status_ready{ + pod=~"pg-cluster-gitlab-\\d+", + container="postgres", namespace="{{ dsc.gitlab.namespace }}"} == 0 + for: 5m + labels: + severity: warning + - alert: GitLab PVC almost out of disk space + annotations: + message: PVC {{"{{"}} $labels.persistentvolumeclaim {{"}}"}} in namespace {{ dsc.gitlab.namespace }} is almost full (< 10% left). VALUE = {{"{{"}} $value {{"}}"}}% + summary: GitLab PVC almost out of disk space in namespace {{ dsc.gitlab.namespace }} + expr: | + round( + kubelet_volume_stats_available_bytes{ + persistentvolumeclaim=~"(.*-)*gitlab(-.*)*", + namespace="{{ dsc.gitlab.namespace }}"} + / kubelet_volume_stats_capacity_bytes{ + persistentvolumeclaim=~"(.*-)*gitlab(-.*)*", + namespace="{{ dsc.gitlab.namespace }}"} * 100, 0.01) < 10 > 0 + for: 1m + labels: + severity: warning + - alert: GitLab PVC out of disk space + annotations: + message: PVC {{"{{"}} $labels.persistentvolumeclaim {{"}}"}} in namespace {{ dsc.gitlab.namespace }} is full (0% left). + summary: GitLab PVC out of disk space in namespace {{ dsc.gitlab.namespace }} + expr: | + kubelet_volume_stats_available_bytes{ + persistentvolumeclaim=~"(.*-)*gitlab(-.*)*", + namespace="{{ dsc.gitlab.namespace }}"} == 0 + for: 1m + labels: + severity: critical diff --git a/roles/gitlab/templates/values/00-main.j2 b/roles/gitlab/templates/values/00-main.j2 index 321c5329..30ec1901 100644 --- a/roles/gitlab/templates/values/00-main.j2 +++ b/roles/gitlab/templates/values/00-main.j2 @@ -50,6 +50,14 @@ gitlab: {% endif %} global: + psql: + serviceName: pg-cluster-gitlab-rw + port: 5432 + database: gitlabhq_production + username: gitlab + password: + secret: pg-cluster-gitlab-app + key: password registry: enabled: false certificates: @@ -95,12 +103,11 @@ global: providers: - secret: openid-connect + extraEnv: + GITLAB_ROOT_EMAIL: "admin@example.com" + prometheus: install: false -{% if dsc.global.backup.velero.enabled %} postgresql: - primary: - podAnnotations: - pre.hook.backup.velero.io/command: '["/bin/bash", "-c", "PGPASSWORD=$POSTGRES_POSTGRES_PASSWORD pg_dump -Fc -U postgres -d gitlabhq_production > /bitnami/postgresql/data/app.dump"]' -{% endif %} \ No newline at end of file + install: false diff --git a/roles/gitlab/templates/values/10-registry.j2 b/roles/gitlab/templates/values/10-registry.j2 index 0f1b5472..4b25fe24 100644 --- a/roles/gitlab/templates/values/10-registry.j2 +++ b/roles/gitlab/templates/values/10-registry.j2 @@ -75,3 +75,10 @@ redis: image: registry: "{{ dsc.global.registry }}" {% endif %} + +{% if use_image_pull_secrets %} +global: + image: + pullSecrets: + - name: dso-config-pull-secret +{% endif %} \ No newline at end of file diff --git a/roles/gitlab/vars/main.yaml b/roles/gitlab/vars/main.yaml index 811d09cd..02e8f4e9 100644 --- a/roles/gitlab/vars/main.yaml +++ b/roles/gitlab/vars/main.yaml @@ -1,13 +1,6 @@ --- -gitlab_service_monitors: - - name: postgresql - port: 9187 - path: /metrics - metrics_endpoint_name: metrics - gitlab_additional_service_monitors: - name: redis port: 9121 path: /metrics metrics_endpoint_name: metrics - diff --git a/roles/grafana-dashboards/templates/argo-cd-dashboard.yaml.j2 b/roles/grafana-dashboards/templates/argo-cd-dashboard.yaml.j2 index cfd690bb..b5b393de 100644 --- a/roles/grafana-dashboards/templates/argo-cd-dashboard.yaml.j2 +++ b/roles/grafana-dashboards/templates/argo-cd-dashboard.yaml.j2 @@ -31,19 +31,17 @@ spec: } ] }, - "description": "Official ArgoCD Dashboard as of June 2021", "editable": true, "fiscalYearStartMonth": 0, - "gnetId": 14584, "graphTooltip": 0, - "id": 31, + "id": 28, "links": [], "liveNow": false, "panels": [ { "collapsed": false, "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "gridPos": { "h": 1, @@ -56,7 +54,7 @@ spec: "targets": [ { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "refId": "A" } @@ -66,7 +64,7 @@ spec: }, { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "gridPos": { "h": 4, @@ -85,11 +83,11 @@ spec: "content": "![argoimage](https://avatars1.githubusercontent.com/u/30269780?s=110&v=4)", "mode": "markdown" }, - "pluginVersion": "9.5.5", + "pluginVersion": "10.3.1", "targets": [ { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "refId": "A" } @@ -99,14 +97,24 @@ spec: }, { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "fieldConfig": { "defaults": { "color": { "mode": "thresholds" }, - "mappings": [], + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], "thresholds": { "mode": "absolute", "steps": [ @@ -120,7 +128,8 @@ spec: } ] }, - "unit": "dtdurations" + "unit": "dtdurations", + "unitScale": true }, "overrides": [] }, @@ -134,7 +143,7 @@ spec: "links": [], "maxDataPoints": 100, "options": { - "colorMode": "value", + "colorMode": "none", "graphMode": "none", "justifyMode": "auto", "orientation": "horizontal", @@ -145,16 +154,17 @@ spec: "fields": "", "values": false }, - "text": {}, - "textMode": "auto" + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true }, - "pluginVersion": "9.5.5", + "pluginVersion": "10.3.1", "targets": [ { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, - "expr": "time() - max(process_start_time_seconds{job=\"argo-argo-cd-server-metrics\",namespace=~\"$namespace\"})", + "expr": "time() - max(process_start_time_seconds{job=\"{% endraw %}{{ dsc_name }}{% raw %}-argocd-server-metrics\",namespace=~\"$namespace\"})", "format": "time_series", "intervalFactor": 1, "refId": "A" @@ -165,14 +175,25 @@ spec: }, { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "fieldConfig": { "defaults": { "color": { - "mode": "thresholds" + "fixedColor": "rgb(31, 120, 193)", + "mode": "fixed" }, - "mappings": [], + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "0" + } + }, + "type": "special" + } + ], "thresholds": { "mode": "absolute", "steps": [ @@ -186,7 +207,8 @@ spec: } ] }, - "unit": "none" + "unit": "none", + "unitScale": true }, "overrides": [] }, @@ -200,7 +222,7 @@ spec: "links": [], "maxDataPoints": 100, "options": { - "colorMode": "value", + "colorMode": "none", "graphMode": "area", "justifyMode": "auto", "orientation": "horizontal", @@ -211,14 +233,15 @@ spec: "fields": "", "values": false }, - "text": {}, - "textMode": "auto" + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true }, - "pluginVersion": "9.5.5", + "pluginVersion": "10.3.1", "targets": [ { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "expr": "count(count by (server) (argocd_cluster_info{namespace=~\"$namespace\"}))", "format": "time_series", @@ -232,14 +255,25 @@ spec: }, { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "fieldConfig": { "defaults": { "color": { - "mode": "thresholds" + "fixedColor": "rgb(31, 120, 193)", + "mode": "fixed" }, - "mappings": [], + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], "thresholds": { "mode": "absolute", "steps": [ @@ -253,7 +287,8 @@ spec: } ] }, - "unit": "none" + "unit": "none", + "unitScale": true }, "overrides": [] }, @@ -267,7 +302,7 @@ spec: "links": [], "maxDataPoints": 100, "options": { - "colorMode": "value", + "colorMode": "none", "graphMode": "area", "justifyMode": "auto", "orientation": "horizontal", @@ -278,15 +313,16 @@ spec: "fields": "", "values": false }, - "text": {}, - "textMode": "auto" + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true }, - "pluginVersion": "9.5.5", + "pluginVersion": "10.3.1", "repeatDirection": "h", "targets": [ { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "expr": "sum(argocd_app_info{namespace=~\"$namespace\",dest_server=~\"$cluster\",health_status=~\"$health_status\",sync_status=~\"$sync_status\"})", "format": "time_series", @@ -300,14 +336,25 @@ spec: }, { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "fieldConfig": { "defaults": { "color": { - "mode": "thresholds" + "fixedColor": "rgb(31, 120, 193)", + "mode": "fixed" }, - "mappings": [], + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "0" + } + }, + "type": "special" + } + ], "thresholds": { "mode": "absolute", "steps": [ @@ -321,7 +368,8 @@ spec: } ] }, - "unit": "none" + "unit": "none", + "unitScale": true }, "overrides": [] }, @@ -335,7 +383,7 @@ spec: "links": [], "maxDataPoints": 100, "options": { - "colorMode": "value", + "colorMode": "none", "graphMode": "area", "justifyMode": "auto", "orientation": "horizontal", @@ -346,14 +394,15 @@ spec: "fields": "", "values": false }, - "text": {}, - "textMode": "auto" + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true }, - "pluginVersion": "9.5.5", + "pluginVersion": "10.3.1", "targets": [ { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "expr": "count(count by (repo) (argocd_app_info{namespace=~\"$namespace\"}))", "format": "time_series", @@ -367,8 +416,7 @@ spec: }, { "datasource": { - "type": "prometheus", - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "fieldConfig": { "defaults": { @@ -386,7 +434,6 @@ spec: ], "max": 100, "min": 0, - "noValue": "0", "thresholds": { "mode": "absolute", "steps": [ @@ -400,7 +447,8 @@ spec: } ] }, - "unit": "none" + "unit": "none", + "unitScale": true }, "overrides": [] }, @@ -413,6 +461,8 @@ spec: "id": 100, "links": [], "options": { + "minVizHeight": 75, + "minVizWidth": 75, "orientation": "horizontal", "reduceOptions": { "calcs": [ @@ -423,16 +473,15 @@ spec: }, "showThresholdLabels": false, "showThresholdMarkers": true, - "text": {} + "sizing": "auto" }, - "pluginVersion": "9.5.5", + "pluginVersion": "10.3.1", "repeatDirection": "h", "targets": [ { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, - "editorMode": "code", "expr": "sum(argocd_app_info{namespace=~\"$namespace\",dest_server=~\"$cluster\",operation!=\"\"})", "format": "time_series", "instant": true, @@ -450,11 +499,12 @@ spec: "dashLength": 10, "dashes": false, "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "fieldConfig": { "defaults": { - "links": [] + "links": [], + "unitScale": true }, "overrides": [] }, @@ -487,12 +537,9 @@ spec: "linewidth": 1, "links": [], "nullPointMode": "connected", - "options": { - "alertThreshold": true - }, "paceLength": 10, "percentage": false, - "pluginVersion": "9.5.5", + "pluginVersion": "10.3.1", "pointradius": 2, "points": false, "renderer": "flot", @@ -503,7 +550,7 @@ spec: "targets": [ { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "expr": "sum(argocd_app_info{namespace=~\"$namespace\",dest_server=~\"$cluster\",health_status=~\"$health_status\",sync_status=~\"$sync_status\"}) by (namespace)", "format": "time_series", @@ -521,7 +568,7 @@ spec: "sort": 2, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -547,7 +594,7 @@ spec: { "collapsed": true, "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "gridPos": { "h": 1, @@ -570,11 +617,12 @@ spec: "dashLength": 10, "dashes": false, "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "fieldConfig": { "defaults": { - "links": [] + "links": [], + "unitScale": true }, "overrides": [] }, @@ -613,7 +661,7 @@ spec: }, "paceLength": 10, "percentage": false, - "pluginVersion": "9.5.5", + "pluginVersion": "10.3.1", "pointradius": 2, "points": false, "renderer": "flot", @@ -624,7 +672,7 @@ spec: "targets": [ { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "expr": "sum(argocd_app_info{namespace=~\"$namespace\",dest_server=~\"$cluster\",health_status=~\"$health_status\",sync_status=~\"$sync_status\",health_status!=\"\"}) by (health_status)", "format": "time_series", @@ -642,7 +690,7 @@ spec: "sort": 2, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -679,11 +727,12 @@ spec: "dashLength": 10, "dashes": false, "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "fieldConfig": { "defaults": { - "links": [] + "links": [], + "unitScale": true }, "overrides": [] }, @@ -722,7 +771,7 @@ spec: }, "paceLength": 10, "percentage": false, - "pluginVersion": "9.5.5", + "pluginVersion": "10.3.1", "pointradius": 2, "points": false, "renderer": "flot", @@ -733,7 +782,7 @@ spec: "targets": [ { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "expr": "sum(argocd_app_info{namespace=~\"$namespace\",dest_server=~\"$cluster\",health_status=~\"$health_status\",sync_status=~\"$sync_status\",health_status!=\"\"}) by (sync_status)", "format": "time_series", @@ -751,7 +800,7 @@ spec: "sort": 2, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -777,7 +826,7 @@ spec: "targets": [ { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "refId": "A" } @@ -788,7 +837,7 @@ spec: { "collapsed": true, "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "gridPos": { "h": 1, @@ -804,13 +853,7 @@ spec: "dashLength": 10, "dashes": false, "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" - }, - "fieldConfig": { - "defaults": { - "links": [] - }, - "overrides": [] + "uid": "$datasource" }, "fill": 1, "fillGradient": 0, @@ -818,7 +861,7 @@ spec: "h": 6, "w": 24, "x": 0, - "y": 13 + "y": 3 }, "hiddenSeries": false, "id": 56, @@ -843,11 +886,10 @@ spec: "links": [], "nullPointMode": "null", "options": { - "alertThreshold": true + "dataLinks": [] }, "paceLength": 10, "percentage": false, - "pluginVersion": "9.5.5", "pointradius": 1, "points": false, "renderer": "flot", @@ -858,7 +900,7 @@ spec: "targets": [ { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "expr": "sum(round(increase(argocd_app_sync_total{namespace=~\"$namespace\",dest_server=~\"$cluster\"}[$interval]))) by ($grouping)", "format": "time_series", @@ -875,7 +917,7 @@ spec: "sort": 2, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -908,13 +950,7 @@ spec: "dashLength": 10, "dashes": false, "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" - }, - "fieldConfig": { - "defaults": { - "links": [] - }, - "overrides": [] + "uid": "$datasource" }, "fill": 1, "fillGradient": 0, @@ -922,7 +958,7 @@ spec: "h": 5, "w": 24, "x": 0, - "y": 19 + "y": 9 }, "hiddenSeries": false, "id": 73, @@ -946,11 +982,10 @@ spec: "links": [], "nullPointMode": "null", "options": { - "alertThreshold": true + "dataLinks": [] }, "paceLength": 10, "percentage": false, - "pluginVersion": "9.5.5", "pointradius": 2, "points": false, "renderer": "flot", @@ -961,7 +996,7 @@ spec: "targets": [ { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "expr": "sum(round(increase(argocd_app_sync_total{namespace=~\"$namespace\",phase=~\"Error|Failed\",dest_server=~\"$cluster\"}[$interval]))) by ($grouping, phase)", "format": "time_series", @@ -978,7 +1013,7 @@ spec: "sort": 2, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -1008,7 +1043,7 @@ spec: "targets": [ { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "refId": "A" } @@ -1019,7 +1054,7 @@ spec: { "collapsed": true, "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "gridPos": { "h": 1, @@ -1035,13 +1070,7 @@ spec: "dashLength": 10, "dashes": false, "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" - }, - "fieldConfig": { - "defaults": { - "links": [] - }, - "overrides": [] + "uid": "$datasource" }, "fill": 1, "fillGradient": 0, @@ -1049,7 +1078,7 @@ spec: "h": 6, "w": 24, "x": 0, - "y": 8 + "y": 12 }, "hiddenSeries": false, "id": 58, @@ -1071,11 +1100,10 @@ spec: "links": [], "nullPointMode": "null", "options": { - "alertThreshold": true + "dataLinks": [] }, "paceLength": 10, "percentage": false, - "pluginVersion": "9.5.5", "pointradius": 2, "points": false, "renderer": "flot", @@ -1086,7 +1114,7 @@ spec: "targets": [ { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "expr": "sum(increase(argocd_app_reconcile_count{namespace=~\"$namespace\",dest_server=~\"$cluster\"}[$interval])) by ($grouping)", "format": "time_series", @@ -1103,7 +1131,7 @@ spec: "sort": 2, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -1136,28 +1164,13 @@ spec: }, "dataFormat": "tsbuckets", "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" - }, - "fieldConfig": { - "defaults": { - "custom": { - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "scaleDistribution": { - "type": "linear" - } - } - }, - "overrides": [] + "uid": "$datasource" }, "gridPos": { "h": 7, "w": 24, "x": 0, - "y": 14 + "y": 18 }, "heatmap": {}, "hideZeroBuckets": false, @@ -1167,51 +1180,12 @@ spec: "show": true }, "links": [], - "options": { - "calculate": false, - "calculation": {}, - "cellGap": 2, - "cellValues": { - "decimals": 0 - }, - "color": { - "exponent": 0.5, - "fill": "#b4ff00", - "mode": "scheme", - "reverse": false, - "scale": "exponential", - "scheme": "Spectral", - "steps": 128 - }, - "exemplars": { - "color": "rgba(255,0,255,0.7)" - }, - "filterValues": { - "le": 1e-9 - }, - "legend": { - "show": true - }, - "rowsFrame": { - "layout": "auto" - }, - "showValue": "never", - "tooltip": { - "show": true, - "yHistogram": true - }, - "yAxis": { - "axisPlacement": "left", - "reverse": false, - "unit": "short" - } - }, - "pluginVersion": "9.5.5", + "options": {}, "reverseYBuckets": false, "targets": [ { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "expr": "sum(increase(argocd_app_reconcile_bucket{namespace=~\"$namespace\"}[$interval])) by (le)", "format": "heatmap", @@ -1244,13 +1218,7 @@ spec: "dashLength": 10, "dashes": false, "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" - }, - "fieldConfig": { - "defaults": { - "links": [] - }, - "overrides": [] + "uid": "$datasource" }, "fill": 1, "fillGradient": 0, @@ -1258,7 +1226,7 @@ spec: "h": 6, "w": 24, "x": 0, - "y": 21 + "y": 25 }, "hiddenSeries": false, "id": 80, @@ -1282,11 +1250,10 @@ spec: "links": [], "nullPointMode": "null as zero", "options": { - "alertThreshold": true + "dataLinks": [] }, "paceLength": 10, "percentage": false, - "pluginVersion": "9.5.5", "pointradius": 2, "points": false, "renderer": "flot", @@ -1297,7 +1264,7 @@ spec: "targets": [ { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "expr": "sum(increase(argocd_app_k8s_request_total{namespace=~\"$namespace\",server=~\"$cluster\"}[$interval])) by (verb, resource_kind)", "format": "time_series", @@ -1315,7 +1282,7 @@ spec: "sort": 2, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -1343,13 +1310,7 @@ spec: "dashLength": 10, "dashes": false, "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" - }, - "fieldConfig": { - "defaults": { - "links": [] - }, - "overrides": [] + "uid": "$datasource" }, "fill": 1, "fillGradient": 0, @@ -1357,7 +1318,7 @@ spec: "h": 7, "w": 12, "x": 0, - "y": 27 + "y": 31 }, "hiddenSeries": false, "id": 96, @@ -1378,10 +1339,9 @@ spec: "links": [], "nullPointMode": "null", "options": { - "alertThreshold": true + "dataLinks": [] }, "percentage": false, - "pluginVersion": "9.5.5", "pointradius": 2, "points": false, "renderer": "flot", @@ -1392,7 +1352,7 @@ spec: "targets": [ { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "expr": "sum(workqueue_depth{namespace=~\"$namespace\",name=~\"app_.*\"}) by (name)", "format": "time_series", @@ -1409,7 +1369,7 @@ spec: "sort": 2, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -1439,13 +1399,7 @@ spec: "dashLength": 10, "dashes": false, "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" - }, - "fieldConfig": { - "defaults": { - "links": [] - }, - "overrides": [] + "uid": "$datasource" }, "fill": 1, "fillGradient": 0, @@ -1453,7 +1407,7 @@ spec: "h": 7, "w": 12, "x": 12, - "y": 27 + "y": 31 }, "hiddenSeries": false, "id": 98, @@ -1473,10 +1427,9 @@ spec: "links": [], "nullPointMode": "null", "options": { - "alertThreshold": true + "dataLinks": [] }, "percentage": false, - "pluginVersion": "9.5.5", "pointradius": 2, "points": false, "renderer": "flot", @@ -1487,7 +1440,7 @@ spec: "targets": [ { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "expr": "sum(argocd_kubectl_exec_pending{namespace=~\"$namespace\"}) by (command)", "format": "time_series", @@ -1504,7 +1457,7 @@ spec: "sort": 2, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -1536,7 +1489,7 @@ spec: "targets": [ { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "refId": "A" } @@ -1547,7 +1500,7 @@ spec: { "collapsed": true, "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "gridPos": { "h": 1, @@ -1563,11 +1516,334 @@ spec: "dashLength": 10, "dashes": false, "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "fieldConfig": { "defaults": { - "links": [] + "links": [], + "unitScale": true + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 9 + }, + "hiddenSeries": false, + "id": 34, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": false, + "rightSide": true, + "show": true, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "connected", + "options": { + "alertThreshold": true + }, + "paceLength": 10, + "percentage": false, + "pluginVersion": "10.3.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "$datasource" + }, + "expr": "go_memstats_heap_alloc_bytes{job=\"{% endraw %}{{ dsc_name }}{% raw %}-argocd-server-metrics\",namespace=~\"$namespace\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{namespace}}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Memory Usage", + "tooltip": { + "shared": false, + "sort": 2, + "value_type": "individual" + }, + "type": "timeseries", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "$datasource" + }, + "fieldConfig": { + "defaults": { + "links": [], + "unitScale": true + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 16 + }, + "hiddenSeries": false, + "id": 108, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": true, + "hideZero": true, + "max": true, + "min": false, + "rightSide": true, + "show": true, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "connected", + "options": { + "alertThreshold": true + }, + "paceLength": 10, + "percentage": false, + "pluginVersion": "10.3.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "$datasource" + }, + "expr": "irate(process_cpu_seconds_total{job=\"{% endraw %}{{ dsc_name }}{% raw %}-argocd-server-metrics\",namespace=~\"$namespace\"}[1m])", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{namespace}}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "CPU Usage", + "tooltip": { + "shared": false, + "sort": 2, + "value_type": "individual" + }, + "type": "timeseries", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "format": "none", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "$datasource" + }, + "fieldConfig": { + "defaults": { + "links": [], + "unitScale": true + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 23 + }, + "hiddenSeries": false, + "id": 62, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": false, + "rightSide": true, + "show": true, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "paceLength": 10, + "percentage": false, + "pluginVersion": "10.3.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "$datasource" + }, + "expr": "go_goroutines{job=\"{% endraw %}{{ dsc_name }}{% raw %}-argocd-server-metrics\",namespace=~\"$namespace\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{namespace}}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Goroutines", + "tooltip": { + "shared": false, + "sort": 2, + "value_type": "individual" + }, + "type": "timeseries", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + ], + "targets": [ + { + "datasource": { + "uid": "$datasource" + }, + "refId": "A" + } + ], + "title": "Controller Telemetry", + "type": "row" + }, + + { + "collapsed": true, + "datasource": { + "uid": "$datasource" + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 8 + }, + "id": 102, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "$datasource" + }, + "fieldConfig": { + "defaults": { + "links": [], + "unitScale": true }, "overrides": [] }, @@ -1603,7 +1879,7 @@ spec: }, "paceLength": 10, "percentage": false, - "pluginVersion": "9.5.5", + "pluginVersion": "10.3.1", "pointradius": 5, "points": false, "renderer": "flot", @@ -1614,9 +1890,9 @@ spec: "targets": [ { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, - "expr": "go_memstats_heap_alloc_bytes{job=\"argo-argo-cd-server-metrics\",namespace=~\"$namespace\"}", + "expr": "go_memstats_heap_alloc_bytes{job=\"{% endraw %}{{ dsc_name }}{% raw %}-argocd-applicationset-controller-metrics\",namespace=~\"$namespace\"}", "format": "time_series", "intervalFactor": 1, "legendFormat": "{{namespace}}", @@ -1631,7 +1907,7 @@ spec: "sort": 2, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -1659,11 +1935,12 @@ spec: "dashLength": 10, "dashes": false, "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "fieldConfig": { "defaults": { - "links": [] + "links": [], + "unitScale": true }, "overrides": [] }, @@ -1701,7 +1978,7 @@ spec: }, "paceLength": 10, "percentage": false, - "pluginVersion": "9.5.5", + "pluginVersion": "10.3.1", "pointradius": 5, "points": false, "renderer": "flot", @@ -1712,9 +1989,9 @@ spec: "targets": [ { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, - "expr": "irate(process_cpu_seconds_total{job=\"argo-argo-cd-app-controller-metrics\",namespace=~\"$namespace\"}[1m])", + "expr": "irate(process_cpu_seconds_total{job=\"{% endraw %}{{ dsc_name }}{% raw %}-argocd-applicationset-controller-metrics\",namespace=~\"$namespace\"}[1m])", "format": "time_series", "intervalFactor": 1, "legendFormat": "{{namespace}}", @@ -1729,7 +2006,7 @@ spec: "sort": 2, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -1758,11 +2035,12 @@ spec: "dashLength": 10, "dashes": false, "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "fieldConfig": { "defaults": { - "links": [] + "links": [], + "unitScale": true }, "overrides": [] }, @@ -1800,7 +2078,7 @@ spec: }, "paceLength": 10, "percentage": false, - "pluginVersion": "9.5.5", + "pluginVersion": "10.3.1", "pointradius": 5, "points": false, "renderer": "flot", @@ -1811,9 +2089,9 @@ spec: "targets": [ { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, - "expr": "go_goroutines{job=\"argo-argo-cd-app-controller-metrics\",namespace=~\"$namespace\"}", + "expr": "go_goroutines{job=\"{% endraw %}{{ dsc_name }}{% raw %}-argocd-applicationset-controller-metrics\",namespace=~\"$namespace\"}", "format": "time_series", "intervalFactor": 1, "legendFormat": "{{namespace}}", @@ -1828,7 +2106,7 @@ spec: "sort": 2, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -1854,18 +2132,18 @@ spec: "targets": [ { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "refId": "A" } ], - "title": "Controller Telemetry", + "title": "AppSet Controller Telemetry", "type": "row" }, { "collapsed": true, "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "gridPos": { "h": 1, @@ -1881,13 +2159,7 @@ spec: "dashLength": 10, "dashes": false, "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" - }, - "fieldConfig": { - "defaults": { - "links": [] - }, - "overrides": [] + "uid": "$datasource" }, "fill": 1, "fillGradient": 0, @@ -1895,7 +2167,7 @@ spec: "h": 7, "w": 24, "x": 0, - "y": 10 + "y": 27 }, "hiddenSeries": false, "id": 90, @@ -1917,10 +2189,9 @@ spec: "links": [], "nullPointMode": "null", "options": { - "alertThreshold": true + "dataLinks": [] }, "percentage": false, - "pluginVersion": "9.5.5", "pointradius": 2, "points": false, "renderer": "flot", @@ -1931,7 +2202,7 @@ spec: "targets": [ { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "expr": "sum(argocd_cluster_api_resource_objects{namespace=~\"$namespace\",server=~\"$cluster\"}) by (server)", "format": "time_series", @@ -1948,7 +2219,7 @@ spec: "sort": 2, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -1976,13 +2247,7 @@ spec: "dashLength": 10, "dashes": false, "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" - }, - "fieldConfig": { - "defaults": { - "links": [] - }, - "overrides": [] + "uid": "$datasource" }, "fill": 1, "fillGradient": 0, @@ -1990,7 +2255,7 @@ spec: "h": 6, "w": 24, "x": 0, - "y": 17 + "y": 34 }, "hiddenSeries": false, "id": 92, @@ -2013,10 +2278,9 @@ spec: "links": [], "nullPointMode": "null", "options": { - "alertThreshold": true + "dataLinks": [] }, "percentage": false, - "pluginVersion": "9.5.5", "pointradius": 2, "points": false, "renderer": "flot", @@ -2027,7 +2291,7 @@ spec: "targets": [ { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "expr": " sum(argocd_cluster_api_resources{namespace=~\"$namespace\",server=~\"$cluster\"}) by (server)", "format": "time_series", @@ -2044,7 +2308,7 @@ spec: "sort": 2, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -2072,13 +2336,7 @@ spec: "dashLength": 10, "dashes": false, "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" - }, - "fieldConfig": { - "defaults": { - "links": [] - }, - "overrides": [] + "uid": "$datasource" }, "fill": 1, "fillGradient": 0, @@ -2086,7 +2344,7 @@ spec: "h": 7, "w": 24, "x": 0, - "y": 23 + "y": 40 }, "hiddenSeries": false, "id": 86, @@ -2108,10 +2366,9 @@ spec: "links": [], "nullPointMode": "null", "options": { - "alertThreshold": true + "dataLinks": [] }, "percentage": false, - "pluginVersion": "9.5.5", "pointradius": 2, "points": false, "renderer": "flot", @@ -2122,7 +2379,7 @@ spec: "targets": [ { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "expr": "sum(increase(argocd_cluster_events_total{namespace=~\"$namespace\",server=~\"$cluster\"}[$interval])) by (server)", "format": "time_series", @@ -2139,7 +2396,7 @@ spec: "sort": 2, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -2165,7 +2422,7 @@ spec: "targets": [ { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "refId": "A" } @@ -2176,7 +2433,7 @@ spec: { "collapsed": true, "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "gridPos": { "h": 1, @@ -2192,11 +2449,12 @@ spec: "dashLength": 10, "dashes": false, "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "fieldConfig": { "defaults": { - "links": [] + "links": [], + "unitScale": true }, "overrides": [] }, @@ -2227,7 +2485,7 @@ spec: "alertThreshold": true }, "percentage": false, - "pluginVersion": "9.5.5", + "pluginVersion": "10.3.1", "pointradius": 2, "points": false, "renderer": "flot", @@ -2238,7 +2496,7 @@ spec: "targets": [ { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "expr": "sum(increase(argocd_git_request_total{request_type=\"ls-remote\", namespace=~\"$namespace\"}[10m])) by (namespace)", "format": "time_series", @@ -2255,7 +2513,7 @@ spec: "sort": 2, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -2283,11 +2541,12 @@ spec: "dashLength": 10, "dashes": false, "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "fieldConfig": { "defaults": { - "links": [] + "links": [], + "unitScale": true }, "overrides": [] }, @@ -2318,7 +2577,7 @@ spec: "alertThreshold": true }, "percentage": false, - "pluginVersion": "9.5.5", + "pluginVersion": "10.3.1", "pointradius": 2, "points": false, "renderer": "flot", @@ -2329,7 +2588,7 @@ spec: "targets": [ { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "expr": "sum(increase(argocd_git_request_total{request_type=\"fetch\", namespace=~\"$namespace\"}[10m])) by (namespace)", "format": "time_series", @@ -2346,7 +2605,7 @@ spec: "sort": 2, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -2380,7 +2639,7 @@ spec: }, "dataFormat": "tsbuckets", "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "fieldConfig": { "defaults": { @@ -2393,7 +2652,8 @@ spec: "scaleDistribution": { "type": "linear" } - } + }, + "unitScale": true }, "overrides": [] }, @@ -2438,7 +2698,8 @@ spec: }, "showValue": "never", "tooltip": { - "show": true, + "mode": "single", + "showColorScale": false, "yHistogram": false }, "yAxis": { @@ -2447,12 +2708,12 @@ spec: "unit": "short" } }, - "pluginVersion": "9.5.5", + "pluginVersion": "10.3.1", "reverseYBuckets": false, "targets": [ { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "expr": "sum(increase(argocd_git_request_duration_seconds_bucket{request_type=\"fetch\", namespace=~\"$namespace\"}[$interval])) by (le)", "format": "heatmap", @@ -2488,7 +2749,7 @@ spec: }, "dataFormat": "tsbuckets", "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "fieldConfig": { "defaults": { @@ -2501,7 +2762,8 @@ spec: "scaleDistribution": { "type": "linear" } - } + }, + "unitScale": true }, "overrides": [] }, @@ -2546,7 +2808,8 @@ spec: }, "showValue": "never", "tooltip": { - "show": true, + "mode": "single", + "showColorScale": false, "yHistogram": false }, "yAxis": { @@ -2555,12 +2818,12 @@ spec: "unit": "short" } }, - "pluginVersion": "9.5.5", + "pluginVersion": "10.3.1", "reverseYBuckets": false, "targets": [ { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "expr": "sum(increase(argocd_git_request_duration_seconds_bucket{request_type=\"ls-remote\", namespace=~\"$namespace\"}[$interval])) by (le)", "format": "heatmap", @@ -2591,13 +2854,7 @@ spec: "dashLength": 10, "dashes": false, "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" - }, - "fieldConfig": { - "defaults": { - "links": [] - }, - "overrides": [] + "uid": "$datasource" }, "fill": 1, "fillGradient": 0, @@ -2623,11 +2880,10 @@ spec: "links": [], "nullPointMode": "connected", "options": { - "alertThreshold": true + "dataLinks": [] }, "paceLength": 10, "percentage": false, - "pluginVersion": "9.5.5", "pointradius": 5, "points": false, "renderer": "flot", @@ -2638,9 +2894,9 @@ spec: "targets": [ { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, - "expr": "go_memstats_heap_alloc_bytes{job=\"argo-argo-cd-repo-server-metrics\",namespace=~\"$namespace\"}", + "expr": "go_memstats_heap_alloc_bytes{job=\"{% endraw %}{{ dsc_name }}{% raw %}-argocd-repo-server-metrics\",namespace=~\"$namespace\"}", "format": "time_series", "intervalFactor": 1, "legendFormat": "{{pod}}", @@ -2655,7 +2911,7 @@ spec: "sort": 2, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -2683,13 +2939,7 @@ spec: "dashLength": 10, "dashes": false, "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" - }, - "fieldConfig": { - "defaults": { - "links": [] - }, - "overrides": [] + "uid": "$datasource" }, "fill": 1, "fillGradient": 0, @@ -2715,11 +2965,10 @@ spec: "links": [], "nullPointMode": "null", "options": { - "alertThreshold": true + "dataLinks": [] }, "paceLength": 10, "percentage": false, - "pluginVersion": "9.5.5", "pointradius": 5, "points": false, "renderer": "flot", @@ -2730,9 +2979,9 @@ spec: "targets": [ { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, - "expr": "go_goroutines{job=\"argo-argo-cd-repo-server-metrics\",namespace=~\"$namespace\"}", + "expr": "go_goroutines{job=\"{% endraw %}{{ dsc_name }}{% raw %}-argocd-repo-server-metrics\",namespace=~\"$namespace\"}", "format": "time_series", "intervalFactor": 1, "legendFormat": "{{pod}}", @@ -2747,7 +2996,7 @@ spec: "sort": 2, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -2773,7 +3022,7 @@ spec: "targets": [ { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "refId": "A" } @@ -2784,7 +3033,7 @@ spec: { "collapsed": true, "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "gridPos": { "h": 1, @@ -2800,7 +3049,13 @@ spec: "dashLength": 10, "dashes": false, "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" + }, + "fieldConfig": { + "defaults": { + "unitScale": true + }, + "overrides": [] }, "fill": 1, "fillGradient": 0, @@ -2830,7 +3085,7 @@ spec: }, "paceLength": 10, "percentage": false, - "pluginVersion": "9.5.5", + "pluginVersion": "10.3.1", "pointradius": 5, "points": false, "renderer": "flot", @@ -2841,9 +3096,9 @@ spec: "targets": [ { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, - "expr": "go_memstats_heap_alloc_bytes{job=\"argo-argo-cd-server-metrics\",namespace=~\"$namespace\"}", + "expr": "go_memstats_heap_alloc_bytes{job=\"{% endraw %}{{ dsc_name }}{% raw %}-argocd-repo-server-metrics\",namespace=~\"$namespace\"}", "format": "time_series", "intervalFactor": 1, "legendFormat": "{{pod}}", @@ -2858,7 +3113,7 @@ spec: "sort": 2, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -2887,7 +3142,13 @@ spec: "dashLength": 10, "dashes": false, "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" + }, + "fieldConfig": { + "defaults": { + "unitScale": true + }, + "overrides": [] }, "fill": 1, "fillGradient": 0, @@ -2917,7 +3178,7 @@ spec: }, "paceLength": 10, "percentage": false, - "pluginVersion": "9.5.5", + "pluginVersion": "10.3.1", "pointradius": 5, "points": false, "renderer": "flot", @@ -2928,9 +3189,9 @@ spec: "targets": [ { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, - "expr": "go_goroutines{job=\"argo-argo-cd-server-metrics\",namespace=~\"$namespace\"}", + "expr": "go_goroutines{job=\"{% endraw %}{{ dsc_name }}{% raw %}-argocd-repo-server-metrics\",namespace=~\"$namespace\"}", "format": "time_series", "intervalFactor": 1, "legendFormat": "{{pod}}", @@ -2945,7 +3206,7 @@ spec: "sort": 2, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -2973,7 +3234,13 @@ spec: "dashLength": 10, "dashes": false, "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" + }, + "fieldConfig": { + "defaults": { + "unitScale": true + }, + "overrides": [] }, "fill": 1, "fillGradient": 0, @@ -3003,7 +3270,7 @@ spec: }, "paceLength": 10, "percentage": false, - "pluginVersion": "9.5.5", + "pluginVersion": "10.3.1", "pointradius": 5, "points": false, "renderer": "flot", @@ -3014,9 +3281,9 @@ spec: "targets": [ { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, - "expr": "go_gc_duration_seconds{job=\"argo-argo-cd-server-metrics\", quantile=\"1\", namespace=~\"$namespace\"}", + "expr": "go_gc_duration_seconds{job=\"{% endraw %}{{ dsc_name }}{% raw %}-argocd-repo-server-metrics\", quantile=\"1\", namespace=~\"$namespace\"}", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{pod}}", @@ -3031,7 +3298,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -3054,6 +3321,7 @@ spec: } }, { + "content": "#### gRPC Services:", "gridPos": { "h": 2, "w": 24, @@ -3062,16 +3330,7 @@ spec: }, "id": 54, "links": [], - "options": { - "code": { - "language": "plaintext", - "showLineNumbers": false, - "showMiniMap": false - }, - "content": "#### gRPC Services:", - "mode": "markdown" - }, - "pluginVersion": "9.5.5", + "mode": "markdown", "transparent": true, "type": "text" }, @@ -3081,17 +3340,15 @@ spec: "dashLength": 10, "dashes": false, "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "fill": 1, - "fillGradient": 0, "gridPos": { "h": 9, "w": 12, "x": 0, "y": 40 }, - "hiddenSeries": false, "id": 40, "legend": { "alignAsTable": true, @@ -3112,12 +3369,8 @@ spec: "linewidth": 1, "links": [], "nullPointMode": "null as zero", - "options": { - "alertThreshold": true - }, "paceLength": 10, "percentage": false, - "pluginVersion": "9.5.5", "pointradius": 5, "points": false, "renderer": "flot", @@ -3128,9 +3381,9 @@ spec: "targets": [ { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, - "expr": "sum(increase(grpc_server_handled_total{job=\"argo-argo-cd-server-metrics\",grpc_service=\"application.ApplicationService\",namespace=~\"$namespace\"}[$interval])) by (grpc_code, grpc_method)", + "expr": "sum(increase(grpc_server_handled_total{job=\"{% endraw %}{{ dsc_name }}{% raw %}-argocd-server-metrics\",grpc_service=\"application.ApplicationService\",namespace=~\"$namespace\"}[$interval])) by (grpc_code, grpc_method)", "format": "time_series", "intervalFactor": 1, "legendFormat": "{{grpc_code}},{{grpc_method}}", @@ -3145,7 +3398,7 @@ spec: "sort": 2, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -3173,17 +3426,15 @@ spec: "dashLength": 10, "dashes": false, "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "fill": 1, - "fillGradient": 0, "gridPos": { "h": 9, "w": 12, "x": 12, "y": 40 }, - "hiddenSeries": false, "id": 42, "legend": { "alignAsTable": true, @@ -3202,12 +3453,8 @@ spec: "linewidth": 1, "links": [], "nullPointMode": "null as zero", - "options": { - "alertThreshold": true - }, "paceLength": 10, "percentage": false, - "pluginVersion": "9.5.5", "pointradius": 5, "points": false, "renderer": "flot", @@ -3218,9 +3465,9 @@ spec: "targets": [ { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, - "expr": "sum(increase(grpc_server_handled_total{job=\"argo-argo-cd-server-metrics\",grpc_service=\"cluster.ClusterService\",namespace=~\"$namespace\"}[$interval])) by (grpc_code, grpc_method)", + "expr": "sum(increase(grpc_server_handled_total{job=\"{% endraw %}{{ dsc_name }}{% raw %}-argocd-server-metrics\",grpc_service=\"cluster.ClusterService\",namespace=~\"$namespace\"}[$interval])) by (grpc_code, grpc_method)", "format": "time_series", "intervalFactor": 1, "legendFormat": "{{grpc_code}},{{grpc_method}}", @@ -3235,7 +3482,7 @@ spec: "sort": 2, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -3263,17 +3510,15 @@ spec: "dashLength": 10, "dashes": false, "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "fill": 1, - "fillGradient": 0, "gridPos": { "h": 9, "w": 12, "x": 0, "y": 49 }, - "hiddenSeries": false, "id": 44, "legend": { "alignAsTable": true, @@ -3292,12 +3537,8 @@ spec: "linewidth": 1, "links": [], "nullPointMode": "null as zero", - "options": { - "alertThreshold": true - }, "paceLength": 10, "percentage": false, - "pluginVersion": "9.5.5", "pointradius": 5, "points": false, "renderer": "flot", @@ -3308,9 +3549,9 @@ spec: "targets": [ { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, - "expr": "sum(increase(grpc_server_handled_total{job=\"argo-argo-cd-server-metrics\",grpc_service=\"project.ProjectService\",namespace=~\"$namespace\"}[$interval])) by (grpc_code, grpc_method)", + "expr": "sum(increase(grpc_server_handled_total{job=\"{% endraw %}{{ dsc_name }}{% raw %}-argocd-server-metrics\",grpc_service=\"project.ProjectService\",namespace=~\"$namespace\"}[$interval])) by (grpc_code, grpc_method)", "format": "time_series", "intervalFactor": 1, "legendFormat": "{{grpc_code}},{{grpc_method}}", @@ -3325,7 +3566,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -3353,17 +3594,15 @@ spec: "dashLength": 10, "dashes": false, "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "fill": 1, - "fillGradient": 0, "gridPos": { "h": 9, "w": 12, "x": 12, "y": 49 }, - "hiddenSeries": false, "id": 46, "legend": { "alignAsTable": true, @@ -3381,12 +3620,8 @@ spec: "linewidth": 1, "links": [], "nullPointMode": "null as zero", - "options": { - "alertThreshold": true - }, "paceLength": 10, "percentage": false, - "pluginVersion": "9.5.5", "pointradius": 5, "points": false, "renderer": "flot", @@ -3397,9 +3632,9 @@ spec: "targets": [ { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, - "expr": "sum(increase(grpc_server_handled_total{job=\"argo-argo-cd-server-metrics\",grpc_service=\"repository.RepositoryService\",namespace=~\"$namespace\"}[$interval])) by (grpc_code, grpc_method)", + "expr": "sum(increase(grpc_server_handled_total{job=\"{% endraw %}{{ dsc_name }}{% raw %}-argocd-server-metrics\",grpc_service=\"repository.RepositoryService\",namespace=~\"$namespace\"}[$interval])) by (grpc_code, grpc_method)", "format": "time_series", "intervalFactor": 1, "legendFormat": "{{grpc_code}},{{grpc_method}}", @@ -3422,7 +3657,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -3450,17 +3685,15 @@ spec: "dashLength": 10, "dashes": false, "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "fill": 1, - "fillGradient": 0, "gridPos": { "h": 9, "w": 12, "x": 0, "y": 58 }, - "hiddenSeries": false, "id": 48, "legend": { "alignAsTable": true, @@ -3478,12 +3711,8 @@ spec: "linewidth": 1, "links": [], "nullPointMode": "null as zero", - "options": { - "alertThreshold": true - }, "paceLength": 10, "percentage": false, - "pluginVersion": "9.5.5", "pointradius": 5, "points": false, "renderer": "flot", @@ -3494,9 +3723,9 @@ spec: "targets": [ { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, - "expr": "sum(increase(grpc_server_handled_total{job=\"argo-argo-cd-server-metrics\",grpc_service=\"session.SessionService\",namespace=~\"$namespace\"}[$interval])) by (grpc_code, grpc_method)", + "expr": "sum(increase(grpc_server_handled_total{job=\"{% endraw %}{{ dsc_name }}{% raw %}-argocd-server-metrics\",grpc_service=\"session.SessionService\",namespace=~\"$namespace\"}[$interval])) by (grpc_code, grpc_method)", "format": "time_series", "intervalFactor": 1, "legendFormat": "{{grpc_code}},{{grpc_method}}", @@ -3511,7 +3740,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -3539,17 +3768,15 @@ spec: "dashLength": 10, "dashes": false, "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "fill": 1, - "fillGradient": 0, "gridPos": { "h": 9, "w": 12, "x": 12, "y": 58 }, - "hiddenSeries": false, "id": 49, "legend": { "alignAsTable": true, @@ -3567,12 +3794,8 @@ spec: "linewidth": 1, "links": [], "nullPointMode": "null as zero", - "options": { - "alertThreshold": true - }, "paceLength": 10, "percentage": false, - "pluginVersion": "9.5.5", "pointradius": 5, "points": false, "renderer": "flot", @@ -3583,9 +3806,9 @@ spec: "targets": [ { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, - "expr": "sum(increase(grpc_server_handled_total{job=\"argo-argo-cd-server-metrics\",grpc_service=\"version.VersionService\",namespace=~\"$namespace\"}[$interval])) by (grpc_code, grpc_method)", + "expr": "sum(increase(grpc_server_handled_total{job=\"{% endraw %}{{ dsc_name }}{% raw %}-argocd-server-metrics\",grpc_service=\"version.VersionService\",namespace=~\"$namespace\"}[$interval])) by (grpc_code, grpc_method)", "format": "time_series", "intervalFactor": 1, "legendFormat": "{{grpc_code}},{{grpc_method}}", @@ -3600,7 +3823,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -3628,17 +3851,15 @@ spec: "dashLength": 10, "dashes": false, "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "fill": 1, - "fillGradient": 0, "gridPos": { "h": 9, "w": 12, "x": 0, "y": 67 }, - "hiddenSeries": false, "id": 50, "legend": { "alignAsTable": true, @@ -3656,12 +3877,8 @@ spec: "linewidth": 1, "links": [], "nullPointMode": "null as zero", - "options": { - "alertThreshold": true - }, "paceLength": 10, "percentage": false, - "pluginVersion": "9.5.5", "pointradius": 5, "points": false, "renderer": "flot", @@ -3672,9 +3889,9 @@ spec: "targets": [ { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, - "expr": "sum(increase(grpc_server_handled_total{job=\"argo-argo-cd-server-metrics\",grpc_service=\"account.AccountService\",namespace=~\"$namespace\"}[$interval])) by (grpc_code, grpc_method)", + "expr": "sum(increase(grpc_server_handled_total{job=\"{% endraw %}{{ dsc_name }}{% raw %}-argocd-server-metrics\",grpc_service=\"account.AccountService\",namespace=~\"$namespace\"}[$interval])) by (grpc_code, grpc_method)", "format": "time_series", "intervalFactor": 1, "legendFormat": "{{grpc_code}},{{grpc_method}}", @@ -3689,7 +3906,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -3712,61 +3929,14 @@ spec: } }, { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 10, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "never", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "short" - }, - "overrides": [] + "uid": "$datasource" }, + "fill": 1, "gridPos": { "h": 9, "w": 12, @@ -3774,44 +3944,78 @@ spec: "y": 67 }, "id": 99, - "links": [], - "options": { - "legend": { - "calcs": [ - "mean", - "lastNotNull", - "sum" - ], - "displayMode": "table", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "multi", - "sort": "none" - } + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "show": true, + "total": true, + "values": true }, - "pluginVersion": "9.5.5", + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null as zero", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, "targets": [ { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, - "expr": "sum(increase(grpc_server_handled_total{job=\"argo-argo-cd-server-metrics\",grpc_service=\"settings.SettingsService\",namespace=~\"$namespace\"}[$interval])) by (grpc_code, grpc_method)", + "expr": "sum(increase(grpc_server_handled_total{job=\"{% endraw %}{{ dsc_name }}{% raw %}-argocd-server-metrics\",grpc_service=\"cluster.SettingsService\",namespace=~\"$namespace\"}[$interval])) by (grpc_code, grpc_method)", "format": "time_series", "intervalFactor": 1, "legendFormat": "{{grpc_code}},{{grpc_method}}", "refId": "A" } ], + "thresholds": [], + "timeRegions": [], "title": "SettingsService Requests", - "type": "timeseries" + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "timeseries", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } } ], "targets": [ { "datasource": { - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "refId": "A" } @@ -3823,7 +4027,7 @@ spec: "collapsed": true, "datasource": { "type": "prometheus", - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "gridPos": { "h": 1, @@ -3834,104 +4038,101 @@ spec: "id": 110, "panels": [ { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, "datasource": { "type": "prometheus", - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "fieldConfig": { "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 10, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "never", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, "links": [], - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "short" + "unitScale": true }, "overrides": [] }, + "fill": 1, + "fillGradient": 0, "gridPos": { "h": 7, "w": 24, "x": 0, "y": 13 }, + "hiddenSeries": false, "id": 112, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "multi", - "sort": "none" - } + "alertThreshold": true }, - "pluginVersion": "9.5.5", + "percentage": false, + "pluginVersion": "10.3.1", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, "targets": [ { "datasource": { "type": "prometheus", - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, - "editorMode": "code", - "expr": "rate(redis_total_error_replies{job=\"argo-redis-metrics\", namespace=~\"$namespace\"}[$interval])", - "range": true, + "expr": "sum(increase(argocd_redis_request_total{namespace=~\"$namespace\"}[$interval])) by (failed)", "refId": "A" } ], - "title": "Total error replies", - "type": "timeseries" + "thresholds": [], + "timeRegions": [], + "title": "Requests by result", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "timeseries", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } } ], "targets": [ { "datasource": { "type": "prometheus", - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "refId": "A" } @@ -3941,8 +4142,7 @@ spec: } ], "refresh": "", - "schemaVersion": 38, - "style": "dark", + "schemaVersion": 39, "tags": [], "templating": { "list": [ @@ -3950,7 +4150,7 @@ spec: "current": { "selected": false, "text": "Prometheus", - "value": "Prometheus" + "value": "prometheus" }, "hide": 0, "includeAll": false, @@ -3958,6 +4158,7 @@ spec: "name": "datasource", "options": [], "query": "prometheus", + "queryValue": "", "refresh": 1, "regex": "", "skipUrlSync": false, @@ -3972,7 +4173,7 @@ spec: }, "datasource": { "type": "prometheus", - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "definition": "label_values(kube_pod_info, namespace)", "hide": 0, @@ -3980,10 +4181,7 @@ spec: "multi": false, "name": "namespace", "options": [], - "query": { - "query": "label_values(kube_pod_info, namespace)", - "refId": "Prometheus-namespace-Variable-Query" - }, + "query": "label_values(kube_pod_info, namespace)", "refresh": 1, "regex": ".*argocd.*", "skipUrlSync": false, @@ -4059,7 +4257,7 @@ spec: { "allValue": "", "current": { - "selected": true, + "selected": false, "text": "namespace", "value": "namespace" }, @@ -4085,6 +4283,7 @@ spec: } ], "query": "namespace,name,project", + "queryValue": "", "skipUrlSync": false, "type": "custom" }, @@ -4097,7 +4296,7 @@ spec: }, "datasource": { "type": "prometheus", - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "$datasource" }, "definition": "label_values(argocd_cluster_info, server)", "hide": 0, @@ -4105,10 +4304,7 @@ spec: "multi": false, "name": "cluster", "options": [], - "query": { - "query": "label_values(argocd_cluster_info, server)", - "refId": "Prometheus-cluster-Variable-Query" - }, + "query": "label_values(argocd_cluster_info, server)", "refresh": 1, "regex": "", "skipUrlSync": false, @@ -4121,7 +4317,7 @@ spec: { "allValue": ".*", "current": { - "selected": true, + "selected": false, "text": "All", "value": "$__all" }, @@ -4173,7 +4369,7 @@ spec: { "allValue": ".*", "current": { - "selected": true, + "selected": false, "text": "All", "value": "$__all" }, @@ -4210,7 +4406,7 @@ spec: ] }, "time": { - "from": "now-12h", + "from": "now-30m", "to": "now" }, "timepicker": { @@ -4239,9 +4435,9 @@ spec: ] }, "timezone": "", - "title": "Argo CD", - "uid": "dso-argocd", - "version": 1, + "title": "ArgoCD", + "uid": "LCAgc9rWz", + "version": 2, "weekStart": "" } {% endraw %} diff --git a/roles/grafana-dashboards/templates/gitlab-ci-pipelines-dashboard.yaml.j2 b/roles/grafana-dashboards/templates/gitlab-ci-pipelines-dashboard.yaml.j2 index d8499f92..2b0b0def 100644 --- a/roles/grafana-dashboards/templates/gitlab-ci-pipelines-dashboard.yaml.j2 +++ b/roles/grafana-dashboards/templates/gitlab-ci-pipelines-dashboard.yaml.j2 @@ -739,9 +739,6 @@ spec: "lines": false, "linewidth": 1, "nullPointMode": "null as zero", - "options": { - "alertThreshold": false - }, "percentage": false, "pluginVersion": "7.3.1", "pointradius": 2, @@ -761,7 +758,6 @@ spec: "refId": "A" } ], - "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, @@ -771,7 +767,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "buckets": null, "mode": "time", diff --git a/roles/grafana-dashboards/templates/gitlab-gitaly-dashboard.yaml.j2 b/roles/grafana-dashboards/templates/gitlab-gitaly-dashboard.yaml.j2 index 082cfd42..d01d7db3 100644 --- a/roles/grafana-dashboards/templates/gitlab-gitaly-dashboard.yaml.j2 +++ b/roles/grafana-dashboards/templates/gitlab-gitaly-dashboard.yaml.j2 @@ -72,9 +72,6 @@ spec: "linewidth": 1, "links": [], "nullPointMode": "null", - "options": { - "alertThreshold": true - }, "percentage": false, "pluginVersion": "9.5.5", "pointradius": 5, @@ -106,7 +103,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -237,9 +234,6 @@ spec: "linewidth": 1, "links": [], "nullPointMode": "null", - "options": { - "alertThreshold": true - }, "percentage": false, "pluginVersion": "9.5.5", "pointradius": 5, @@ -281,7 +275,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -419,9 +413,6 @@ spec: "linewidth": 1, "links": [], "nullPointMode": "null", - "options": { - "alertThreshold": true - }, "percentage": false, "pluginVersion": "9.5.5", "pointradius": 5, @@ -463,7 +454,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -518,9 +509,6 @@ spec: "linewidth": 1, "links": [], "nullPointMode": "null", - "options": { - "alertThreshold": true - }, "percentage": false, "pluginVersion": "9.5.5", "pointradius": 5, @@ -552,7 +540,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, diff --git a/roles/grafana-dashboards/templates/keycloak-dashboard.yaml.j2 b/roles/grafana-dashboards/templates/keycloak-dashboard.yaml.j2 index fc821e3c..d90be5b3 100644 --- a/roles/grafana-dashboards/templates/keycloak-dashboard.yaml.j2 +++ b/roles/grafana-dashboards/templates/keycloak-dashboard.yaml.j2 @@ -629,7 +629,6 @@ spec: "maxPerRow": 4, "nullPointMode": "null", "options": { - "alertThreshold": true, "legend": { "calcs": [], "displayMode": "list", @@ -789,7 +788,6 @@ spec: "maxPerRow": 4, "nullPointMode": "null", "options": { - "alertThreshold": true, "legend": { "calcs": [], "displayMode": "list", @@ -948,7 +946,6 @@ spec: "maxPerRow": 4, "nullPointMode": "null", "options": { - "alertThreshold": true, "legend": { "calcs": [], "displayMode": "list", @@ -1107,7 +1104,6 @@ spec: "maxPerRow": 4, "nullPointMode": "null", "options": { - "alertThreshold": true, "legend": { "calcs": [], "displayMode": "list", @@ -1266,7 +1262,6 @@ spec: "maxPerRow": 4, "nullPointMode": "null", "options": { - "alertThreshold": true, "legend": { "calcs": [], "displayMode": "list", @@ -1420,7 +1415,6 @@ spec: "links": [], "nullPointMode": "null", "options": { - "alertThreshold": true, "legend": { "calcs": [], "displayMode": "list", @@ -1572,7 +1566,6 @@ spec: "links": [], "nullPointMode": "null", "options": { - "alertThreshold": true, "legend": { "calcs": [], "displayMode": "list", @@ -2361,7 +2354,6 @@ spec: "maxPerRow": 4, "nullPointMode": "null", "options": { - "alertThreshold": true, "legend": { "calcs": [], "displayMode": "list", @@ -2521,7 +2513,6 @@ spec: "maxPerRow": 4, "nullPointMode": "null", "options": { - "alertThreshold": true, "legend": { "calcs": [], "displayMode": "list", @@ -2681,7 +2672,6 @@ spec: "maxPerRow": 4, "nullPointMode": "null", "options": { - "alertThreshold": true, "legend": { "calcs": [], "displayMode": "list", @@ -2839,7 +2829,6 @@ spec: "maxPerRow": 4, "nullPointMode": "null", "options": { - "alertThreshold": true, "legend": { "calcs": [], "displayMode": "list", @@ -3120,7 +3109,6 @@ spec: "maxPerRow": 4, "nullPointMode": "null", "options": { - "alertThreshold": true, "legend": { "calcs": [], "displayMode": "list", @@ -3280,7 +3268,6 @@ spec: "maxPerRow": 4, "nullPointMode": "null", "options": { - "alertThreshold": true, "legend": { "calcs": [], "displayMode": "list", @@ -3560,7 +3547,6 @@ spec: "maxPerRow": 4, "nullPointMode": "null", "options": { - "alertThreshold": true, "legend": { "calcs": [], "displayMode": "list", @@ -3961,7 +3947,6 @@ spec: "maxPerRow": 4, "nullPointMode": "null", "options": { - "alertThreshold": true, "legend": { "calcs": [], "displayMode": "list", @@ -4120,7 +4105,6 @@ spec: "maxPerRow": 4, "nullPointMode": "null", "options": { - "alertThreshold": true, "legend": { "calcs": [], "displayMode": "list", @@ -4279,7 +4263,6 @@ spec: "maxPerRow": 4, "nullPointMode": "null", "options": { - "alertThreshold": true, "legend": { "calcs": [], "displayMode": "list", @@ -4438,7 +4421,6 @@ spec: "maxPerRow": 4, "nullPointMode": "null", "options": { - "alertThreshold": true, "legend": { "calcs": [], "displayMode": "list", @@ -4960,7 +4942,6 @@ spec: "maxPerRow": 4, "nullPointMode": "null", "options": { - "alertThreshold": true, "legend": { "calcs": [], "displayMode": "list", diff --git a/roles/grafana-dashboards/templates/nexus-dashboard.yaml.j2 b/roles/grafana-dashboards/templates/nexus-dashboard.yaml.j2 index 9bb47126..574b7ed6 100644 --- a/roles/grafana-dashboards/templates/nexus-dashboard.yaml.j2 +++ b/roles/grafana-dashboards/templates/nexus-dashboard.yaml.j2 @@ -387,9 +387,6 @@ spec: "lines": true, "linewidth": 1, "nullPointMode": "null", - "options": { - "alertThreshold": true - }, "percentage": false, "pluginVersion": "9.5.5", "pointradius": 2, @@ -529,7 +526,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -590,9 +587,6 @@ spec: "lines": true, "linewidth": 1, "nullPointMode": "null", - "options": { - "alertThreshold": true - }, "percentage": false, "pluginVersion": "9.5.5", "pointradius": 2, @@ -684,7 +678,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -745,9 +739,6 @@ spec: "lines": true, "linewidth": 1, "nullPointMode": "null", - "options": { - "alertThreshold": true - }, "percentage": false, "pluginVersion": "9.5.5", "pointradius": 2, @@ -815,7 +806,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -876,9 +867,6 @@ spec: "lines": true, "linewidth": 1, "nullPointMode": "null", - "options": { - "alertThreshold": true - }, "percentage": false, "pluginVersion": "9.5.5", "pointradius": 2, @@ -946,7 +934,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -1007,9 +995,6 @@ spec: "lines": true, "linewidth": 1, "nullPointMode": "null", - "options": { - "alertThreshold": true - }, "percentage": false, "pluginVersion": "9.5.5", "pointradius": 2, @@ -1095,7 +1080,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -1156,9 +1141,6 @@ spec: "lines": true, "linewidth": 1, "nullPointMode": "null", - "options": { - "alertThreshold": true - }, "percentage": false, "pluginVersion": "9.5.5", "pointradius": 2, @@ -1202,7 +1184,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -1263,9 +1245,6 @@ spec: "lines": true, "linewidth": 1, "nullPointMode": "null", - "options": { - "alertThreshold": true - }, "percentage": false, "pluginVersion": "9.5.5", "pointradius": 2, @@ -1309,7 +1288,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -1370,9 +1349,6 @@ spec: "lines": true, "linewidth": 1, "nullPointMode": "null", - "options": { - "alertThreshold": true - }, "percentage": false, "pluginVersion": "9.5.5", "pointradius": 2, @@ -1632,7 +1608,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -1719,9 +1695,6 @@ spec: "lines": true, "linewidth": 1, "nullPointMode": "null", - "options": { - "alertThreshold": true - }, "percentage": false, "pluginVersion": "9.5.5", "pointradius": 2, @@ -1801,7 +1774,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -1862,9 +1835,6 @@ spec: "lines": true, "linewidth": 1, "nullPointMode": "null", - "options": { - "alertThreshold": true - }, "percentage": false, "pluginVersion": "9.5.5", "pointradius": 2, @@ -1908,7 +1878,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -1969,9 +1939,6 @@ spec: "lines": true, "linewidth": 1, "nullPointMode": "null", - "options": { - "alertThreshold": true - }, "percentage": false, "pluginVersion": "9.5.5", "pointradius": 2, @@ -2015,7 +1982,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -2096,9 +2063,6 @@ spec: "lines": true, "linewidth": 1, "nullPointMode": "null", - "options": { - "alertThreshold": true - }, "percentage": false, "pluginVersion": "9.5.5", "pointradius": 1, @@ -2143,7 +2107,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -2198,9 +2162,6 @@ spec: "lines": true, "linewidth": 1, "nullPointMode": "null", - "options": { - "alertThreshold": true - }, "percentage": false, "pluginVersion": "9.5.5", "pointradius": 1, @@ -2245,7 +2206,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -2334,9 +2295,6 @@ spec: "lines": true, "linewidth": 1, "nullPointMode": "null", - "options": { - "alertThreshold": true - }, "percentage": false, "pluginVersion": "9.5.5", "pointradius": 2, @@ -2405,7 +2363,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -2468,9 +2426,6 @@ spec: "lines": true, "linewidth": 1, "nullPointMode": "null", - "options": { - "alertThreshold": true - }, "percentage": false, "pluginVersion": "9.5.5", "pointradius": 2, @@ -2539,7 +2494,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -2602,9 +2557,6 @@ spec: "lines": true, "linewidth": 1, "nullPointMode": "null", - "options": { - "alertThreshold": true - }, "percentage": false, "pluginVersion": "9.5.5", "pointradius": 2, @@ -2673,7 +2625,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -2754,9 +2706,6 @@ spec: "lines": true, "linewidth": 1, "nullPointMode": "null", - "options": { - "alertThreshold": true - }, "percentage": false, "pluginVersion": "9.5.5", "pointradius": 2, @@ -2838,7 +2787,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -2893,9 +2842,6 @@ spec: "lines": true, "linewidth": 1, "nullPointMode": "null", - "options": { - "alertThreshold": true - }, "percentage": false, "pluginVersion": "9.5.5", "pointradius": 2, @@ -2975,7 +2921,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -3030,9 +2976,6 @@ spec: "lines": true, "linewidth": 1, "nullPointMode": "null", - "options": { - "alertThreshold": true - }, "percentage": false, "pluginVersion": "9.5.5", "pointradius": 2, @@ -3114,7 +3057,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -3195,9 +3138,6 @@ spec: "lines": true, "linewidth": 1, "nullPointMode": "null", - "options": { - "alertThreshold": true - }, "percentage": false, "pluginVersion": "9.5.5", "pointradius": 2, @@ -3266,7 +3206,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -3321,9 +3261,6 @@ spec: "lines": true, "linewidth": 1, "nullPointMode": "null", - "options": { - "alertThreshold": true - }, "percentage": false, "pluginVersion": "9.5.5", "pointradius": 2, @@ -3379,7 +3316,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -3434,9 +3371,6 @@ spec: "lines": true, "linewidth": 1, "nullPointMode": "null", - "options": { - "alertThreshold": true - }, "percentage": false, "pluginVersion": "9.5.5", "pointradius": 2, @@ -3492,7 +3426,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -3579,9 +3513,6 @@ spec: "lines": true, "linewidth": 1, "nullPointMode": "null", - "options": { - "alertThreshold": true - }, "percentage": false, "pluginVersion": "9.5.5", "pointradius": 2, @@ -3613,7 +3544,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -3675,9 +3606,6 @@ spec: "lines": true, "linewidth": 1, "nullPointMode": "null", - "options": { - "alertThreshold": true - }, "percentage": false, "pluginVersion": "9.5.5", "pointradius": 2, @@ -3721,7 +3649,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -3782,9 +3710,6 @@ spec: "lines": true, "linewidth": 1, "nullPointMode": "null", - "options": { - "alertThreshold": true - }, "percentage": false, "pluginVersion": "9.5.5", "pointradius": 2, @@ -3816,7 +3741,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -3878,9 +3803,6 @@ spec: "lines": true, "linewidth": 1, "nullPointMode": "null", - "options": { - "alertThreshold": true - }, "percentage": false, "pluginVersion": "9.5.5", "pointradius": 2, @@ -3924,7 +3846,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -3985,9 +3907,6 @@ spec: "lines": true, "linewidth": 1, "nullPointMode": "null", - "options": { - "alertThreshold": true - }, "percentage": false, "pluginVersion": "9.5.5", "pointradius": 2, @@ -4043,7 +3962,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -4104,9 +4023,6 @@ spec: "lines": true, "linewidth": 1, "nullPointMode": "null", - "options": { - "alertThreshold": true - }, "percentage": false, "pluginVersion": "9.5.5", "pointradius": 2, @@ -4198,7 +4114,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, diff --git a/roles/grafana-dashboards/templates/vault-dashboard.yaml.j2 b/roles/grafana-dashboards/templates/vault-dashboard.yaml.j2 index d80d2ae9..7f978a86 100644 --- a/roles/grafana-dashboards/templates/vault-dashboard.yaml.j2 +++ b/roles/grafana-dashboards/templates/vault-dashboard.yaml.j2 @@ -21,7 +21,7 @@ spec: "builtIn": 1, "datasource": { "type": "prometheus", - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" + "uid": "grafana" }, "enable": true, "hide": true, @@ -36,7 +36,7 @@ spec: "fiscalYearStartMonth": 0, "gnetId": 12904, "graphTooltip": 1, - "id": 26, + "id": 13, "links": [], "liveNow": false, "panels": [ @@ -97,9 +97,11 @@ spec: "fields": "", "values": false }, - "textMode": "auto" + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true }, - "pluginVersion": "9.5.5", + "pluginVersion": "10.4.3", "targets": [ { "datasource": { @@ -116,121 +118,6 @@ spec: "title": "Healthy status", "type": "stat" }, - { - "datasource": { - "type": "prometheus", - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" - }, - "fieldConfig": { - "defaults": { - "custom": { - "align": "auto", - "cellOptions": { - "type": "auto" - }, - "inspect": false - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "Mount Path" - }, - "properties": [ - { - "id": "custom.width", - "value": 166 - } - ] - } - ] - }, - "gridPos": { - "h": 8, - "w": 5, - "x": 9, - "y": 0 - }, - "id": 59, - "maxDataPoints": 100, - "options": { - "cellHeight": "sm", - "footer": { - "countRows": false, - "fields": "", - "reducer": [ - "sum" - ], - "show": false - }, - "showHeader": true, - "sortBy": [ - { - "desc": true, - "displayName": "Number of Entries" - } - ] - }, - "pluginVersion": "9.5.5", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" - }, - "expr": "avg without(instance) (vault_secret_kv_count)", - "format": "table", - "interval": "", - "legendFormat": "{{ mount_point }}", - "refId": "A" - } - ], - "title": "Secrets", - "transformations": [ - { - "id": "seriesToColumns", - "options": { - "byField": "mount_point" - } - }, - { - "id": "organize", - "options": { - "excludeByName": { - "Time": true, - "__name__": true, - "cluster": true, - "env": true, - "instance": true, - "job": true, - "namespace": true, - "project": true - }, - "indexByName": {}, - "renameByName": { - "Value": "Number of Entries", - "mount_point": "Mount Path" - } - } - } - ], - "type": "table" - }, { "datasource": { "type": "prometheus", @@ -254,10 +141,10 @@ spec: "gridPos": { "h": 4, "w": 5, - "x": 14, + "x": 9, "y": 0 }, - "id": 78, + "id": 105, "options": { "colorMode": "value", "graphMode": "none", @@ -270,22 +157,26 @@ spec: "fields": "", "values": false }, - "textMode": "auto" + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true }, - "pluginVersion": "9.5.5", + "pluginVersion": "10.4.3", "targets": [ { "datasource": { "type": "prometheus", "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" }, - "expr": "avg(vault_identity_num_entities)", + "editorMode": "code", + "expr": "avg(vault_secret_kv_count)", "interval": "", "legendFormat": "", + "range": true, "refId": "A" } ], - "title": "Number of Identity Entities", + "title": "Number of Secrets", "type": "stat" }, { @@ -311,10 +202,10 @@ spec: "gridPos": { "h": 4, "w": 5, - "x": 19, + "x": 14, "y": 0 }, - "id": 105, + "id": 78, "options": { "colorMode": "value", "graphMode": "none", @@ -327,24 +218,24 @@ spec: "fields": "", "values": false }, - "textMode": "auto" + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true }, - "pluginVersion": "9.5.5", + "pluginVersion": "10.4.3", "targets": [ { "datasource": { "type": "prometheus", "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}" }, - "editorMode": "code", - "expr": "avg(vault_secret_kv_count)", + "expr": "avg(vault_identity_num_entities)", "interval": "", "legendFormat": "", - "range": true, "refId": "A" } ], - "title": "Number of Secrets", + "title": "Number of Identity Entities", "type": "stat" }, { @@ -407,9 +298,11 @@ spec: "fields": "", "values": false }, - "textMode": "auto" + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true }, - "pluginVersion": "9.5.5", + "pluginVersion": "10.4.3", "targets": [ { "datasource": { @@ -477,9 +370,11 @@ spec: "fields": "", "values": false }, - "textMode": "auto" + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true }, - "pluginVersion": "9.5.5", + "pluginVersion": "10.4.3", "targets": [ { "datasource": { @@ -521,7 +416,55 @@ spec: "decimals": 0, "fieldConfig": { "defaults": { - "custom": {} + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } }, "overrides": [] }, @@ -531,7 +474,7 @@ spec: "h": 9, "w": 12, "x": 0, - "y": 17 + "y": 9 }, "hiddenSeries": false, "id": 24, @@ -550,10 +493,19 @@ spec: }, "lines": false, "linewidth": 1, - "links": [], "nullPointMode": "null as zero", "options": { - "dataLinks": [] + "dataLinks": [], + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } }, "percentage": false, "pointradius": 5, @@ -633,7 +585,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -671,7 +623,55 @@ spec: "decimals": 0, "fieldConfig": { "defaults": { - "custom": {} + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } }, "overrides": [] }, @@ -681,7 +681,7 @@ spec: "h": 9, "w": 12, "x": 12, - "y": 17 + "y": 9 }, "hiddenSeries": false, "id": 35, @@ -700,10 +700,19 @@ spec: }, "lines": true, "linewidth": 1, - "links": [], "nullPointMode": "null as zero", "options": { - "dataLinks": [] + "dataLinks": [], + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } }, "percentage": false, "pointradius": 5, @@ -778,7 +787,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -890,9 +899,11 @@ spec: "fields": "", "values": false }, - "textMode": "auto" + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true }, - "pluginVersion": "9.5.5", + "pluginVersion": "10.4.3", "targets": [ { "datasource": { @@ -961,9 +972,11 @@ spec: "fields": "", "values": false }, - "textMode": "auto" + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true }, - "pluginVersion": "9.5.5", + "pluginVersion": "10.4.3", "targets": [ { "datasource": { @@ -991,7 +1004,56 @@ spec: "decimals": 3, "fieldConfig": { "defaults": { - "links": [] + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "links": [], + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } }, "overrides": [] }, @@ -1022,7 +1084,16 @@ spec: "linewidth": 1, "nullPointMode": "null", "options": { - "alertThreshold": true + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } }, "percentage": false, "pluginVersion": "9.5.5", @@ -1054,7 +1125,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -1144,9 +1215,11 @@ spec: "fields": "", "values": false }, - "textMode": "auto" + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true }, - "pluginVersion": "9.5.5", + "pluginVersion": "10.4.3", "targets": [ { "datasource": { @@ -1174,7 +1247,56 @@ spec: "decimals": 0, "fieldConfig": { "defaults": { - "links": [] + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "links": [], + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } }, "overrides": [] }, @@ -1203,7 +1325,16 @@ spec: "linewidth": 1, "nullPointMode": "connected", "options": { - "alertThreshold": true + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } }, "percentage": false, "pluginVersion": "9.5.5", @@ -1234,7 +1365,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "series", "show": true, @@ -1297,7 +1428,6 @@ spec: "y": 20 }, "id": 8, - "links": [], "maxDataPoints": 100, "options": { "colorMode": "value", @@ -1316,9 +1446,11 @@ spec: "fields": "", "values": false }, - "textMode": "auto" + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true }, - "pluginVersion": "9.5.5", + "pluginVersion": "10.4.3", "targets": [ { "datasource": { @@ -1348,7 +1480,56 @@ spec: "decimals": 0, "fieldConfig": { "defaults": { - "links": [] + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "links": [], + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } }, "overrides": [] }, @@ -1377,7 +1558,16 @@ spec: "linewidth": 1, "nullPointMode": "connected", "options": { - "alertThreshold": true + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } }, "percentage": false, "pluginVersion": "9.5.5", @@ -1409,7 +1599,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "series", "show": true, @@ -1447,7 +1637,56 @@ spec: "decimals": 0, "fieldConfig": { "defaults": { - "links": [] + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "links": [], + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } }, "overrides": [] }, @@ -1476,7 +1715,16 @@ spec: "linewidth": 1, "nullPointMode": "connected", "options": { - "alertThreshold": true + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } }, "percentage": false, "pluginVersion": "9.5.5", @@ -1507,7 +1755,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "series", "show": true, @@ -1545,7 +1793,56 @@ spec: "decimals": 0, "fieldConfig": { "defaults": { - "links": [] + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "links": [], + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } }, "overrides": [] }, @@ -1575,7 +1872,16 @@ spec: "maxDataPoints": 100, "nullPointMode": "null as zero", "options": { - "alertThreshold": true + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } }, "percentage": false, "pluginVersion": "9.5.5", @@ -1609,7 +1915,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -1649,7 +1955,56 @@ spec: "decimals": 0, "fieldConfig": { "defaults": { - "links": [] + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "links": [], + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } }, "overrides": [] }, @@ -1674,10 +2029,18 @@ spec: }, "lines": false, "linewidth": 1, - "links": [], "nullPointMode": "null", "options": { - "alertThreshold": true + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } }, "percentage": false, "pluginVersion": "9.5.5", @@ -1725,7 +2088,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -1764,7 +2127,56 @@ spec: "decimals": 3, "fieldConfig": { "defaults": { - "links": [] + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "links": [], + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } }, "overrides": [] }, @@ -1792,10 +2204,18 @@ spec: }, "lines": true, "linewidth": 1, - "links": [], "nullPointMode": "null", "options": { - "alertThreshold": true + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } }, "percentage": false, "pluginVersion": "9.5.5", @@ -1827,7 +2247,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -1925,9 +2345,11 @@ spec: "fields": "", "values": false }, - "textMode": "auto" + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true }, - "pluginVersion": "9.5.5", + "pluginVersion": "10.4.3", "targets": [ { "datasource": { @@ -1956,7 +2378,56 @@ spec: "decimals": 3, "fieldConfig": { "defaults": { - "links": [] + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "links": [], + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } }, "overrides": [] }, @@ -1985,10 +2456,18 @@ spec: }, "lines": true, "linewidth": 1, - "links": [], "nullPointMode": "null", "options": { - "alertThreshold": true + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } }, "percentage": false, "pluginVersion": "9.5.5", @@ -2049,7 +2528,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -2121,9 +2600,11 @@ spec: "fields": "", "values": false }, - "textMode": "auto" + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true }, - "pluginVersion": "9.5.5", + "pluginVersion": "10.4.3", "targets": [ { "datasource": { @@ -2179,7 +2660,56 @@ spec: }, "fieldConfig": { "defaults": { - "links": [] + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "links": [], + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } }, "overrides": [] }, @@ -2205,10 +2735,18 @@ spec: }, "lines": true, "linewidth": 1, - "links": [], "nullPointMode": "null", "options": { - "alertThreshold": true + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } }, "percentage": false, "pluginVersion": "9.5.5", @@ -2241,7 +2779,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -2279,7 +2817,56 @@ spec: }, "fieldConfig": { "defaults": { - "links": [] + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "links": [], + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } }, "overrides": [] }, @@ -2304,10 +2891,18 @@ spec: }, "lines": true, "linewidth": 1, - "links": [], "nullPointMode": "null", "options": { - "alertThreshold": true + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } }, "percentage": false, "pluginVersion": "9.5.5", @@ -2340,7 +2935,7 @@ spec: "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "mode": "time", "show": true, @@ -2368,8 +2963,7 @@ spec: } ], "refresh": "", - "schemaVersion": 38, - "style": "dark", + "schemaVersion": 39, "tags": [ "vault" ], @@ -2433,9 +3027,13 @@ spec: { "allValue": "", "current": { - "selected": false, - "text": "All", - "value": "$__all" + "selected": true, + "text": [ + "All" + ], + "value": [ + "$__all" + ] }, "datasource": { "type": "prometheus", @@ -2490,8 +3088,8 @@ spec: }, "timezone": "", "title": "Vault", - "uid": "dso-vault", - "version": 4, + "uid": "{% endraw %}{{ gf_datasource_uid }}{% raw %}", + "version": 2, "weekStart": "" } {% endraw %} \ No newline at end of file diff --git a/roles/grafana-dashboards/vars/main.yaml b/roles/grafana-dashboards/vars/main.yaml index b19ce814..120a1b4b 100644 --- a/roles/grafana-dashboards/vars/main.yaml +++ b/roles/grafana-dashboards/vars/main.yaml @@ -30,8 +30,8 @@ grafana_dashboards: json: https://grafana.com/api/dashboards/12904/revisions/2/download - name: Argo CD dashboard_template: argo-cd-dashboard.yaml.j2 - webpage: https://grafana.com/grafana/dashboards/14584-argocd/ - json: https://grafana.com/api/dashboards/14584/revisions/1/download + webpage: https://github.com/argoproj/argo-cd/blob/master/examples/dashboard.json + json: https://raw.githubusercontent.com/argoproj/argo-cd/master/examples/dashboard.json - name: Harbor dashboard_template: harbor-dashboard.yaml.j2 webpage: https://github.com/goharbor/harbor/blob/main/contrib/grafana-dashboard/metrics-example.json diff --git a/roles/grafana-operator/tasks/main.yaml b/roles/grafana-operator/tasks/main.yaml index 659b7321..2cdf2722 100644 --- a/roles/grafana-operator/tasks/main.yaml +++ b/roles/grafana-operator/tasks/main.yaml @@ -32,7 +32,7 @@ - name: Deploy Grafana Operator helm kubernetes.core.helm: name: grafana-operator - chart_ref: oci://ghcr.io/grafana/helm-charts/grafana-operator + chart_ref: "{{ dsc.grafanaOperator.ociChartUrl }}" chart_version: "{{ dsc.grafanaOperator.chartVersion }}" release_namespace: "{{ dsc.grafanaOperator.namespace }}" create_namespace: true diff --git a/roles/grafana-operator/templates/values.yaml.j2 b/roles/grafana-operator/templates/values.yaml.j2 index e4cb4489..e84ca85e 100644 --- a/roles/grafana-operator/templates/values.yaml.j2 +++ b/roles/grafana-operator/templates/values.yaml.j2 @@ -27,7 +27,12 @@ image: tag: "" # -- image pull secrets +{% if use_image_pull_secrets %} +imagePullSecrets: +- name: dso-config-pull-secret +{% else %} imagePullSecrets: [] +{% endif %} nameOverride: "" fullnameOverride: "" diff --git a/roles/grafana/templates/grafana.yaml.j2 b/roles/grafana/templates/grafana.yaml.j2 index 4cdb35db..af20ea3d 100644 --- a/roles/grafana/templates/grafana.yaml.j2 +++ b/roles/grafana/templates/grafana.yaml.j2 @@ -34,3 +34,16 @@ spec: containers: - image: grafana/grafana:{{ dsc.grafana.imageVersion }} name: grafana +{% if dsc.proxy.enabled %} + env: + - name: HTTP_PROXY + value: "{{ dsc.proxy.http_proxy }}" + - name: HTTPS_PROXY + value: "{{ dsc.proxy.https_proxy }}" + - name: NO_PROXY + value: "{{ dsc.proxy.no_proxy }}" +{% endif %} +{% if use_image_pull_secrets %} + imagePullSecrets: + - name: dso-config-pull-secret +{% endif %} diff --git a/roles/harbor/tasks/main.yaml b/roles/harbor/tasks/main.yaml index 42831fca..b4d096e4 100644 --- a/roles/harbor/tasks/main.yaml +++ b/roles/harbor/tasks/main.yaml @@ -8,20 +8,20 @@ - name: CNPG s3 CA (secret) when: > - dsc.global.backup.cnpg.enabled and + dsc.global.backup.cnpg.enabled and dsc.global.backup.cnpg.endpointCA.namespace is defined and dsc.global.backup.cnpg.endpointCA.name is defined and dsc.global.backup.cnpg.endpointCA.key is defined block: - name: Get secret kubernetes.core.k8s_info: - name: "{{ dsc.global.backup.cnpg.endpointCA.name }}" - namespace: "{{ dsc.global.backup.cnpg.endpointCA.namespace }}" + name: "{{ dsc.global.backup.endpointCa.name }}" + namespace: "{{ dsc.global.backup.endpointCa.namespace }}" kind: Secret register: cnpg_s3_ca_resource - name: Extract key - ansible.builtin.set_fact: + ansible.builtin.set_fact: cnpg_s3_ca_pem: "{{ cnpg_s3_ca_resource.resources[0].data[dsc.global.backup.cnpg.endpointCA.key] }}" - name: Set cnpg bundle-ca secret @@ -36,14 +36,14 @@ - name: Set cnpg backup secret kubernetes.core.k8s: - name: "{{ dsc.global.backup.cnpg.s3Credentials.name }}" + name: "{{ dsc.global.backup.s3Credentials.name }}" namespace: "{{ dsc.harbor.namespace }}" kind: Secret api_version: v1 definition: data: - accessKeyId: "{{ dsc.global.backup.cnpg.s3Credentials.accessKeyId.value | b64encode }}" - secretAccessKey: "{{ dsc.global.backup.cnpg.s3Credentials.secretAccessKey.value | b64encode }}" + accessKeyId: "{{ dsc.global.backup.s3Credentials.accessKeyId.value | b64encode }}" + secretAccessKey: "{{ dsc.global.backup.s3Credentials.secretAccessKey.value | b64encode }}" when: dsc.global.backup.cnpg.enabled - name: Remove cnpg scheduled backup @@ -57,7 +57,11 @@ - name: Create PostgreSQL cluster and harbor database kubernetes.core.k8s: - template: pg-cluster-harbor.yaml.j2 + template: "{{ item }}" + with_items: + - pg-cluster-harbor.yaml.j2 + - pg-cluster-harbor-backup.yaml.j2 + - pg-cluster-harbor-nodeport.yaml.j2 - name: Wait pg-cluster-harbor-rw endpoint kubernetes.core.k8s_info: @@ -115,7 +119,8 @@ - name: Add helm repo kubernetes.core.helm_repository: name: harbor - repo_url: https://helm.goharbor.io + repo_url: "{{ dsc.harbor.helmRepoUrl }}" + force_update: true - name: Set path fact ansible.builtin.set_fact: @@ -271,4 +276,9 @@ loop_control: loop_var: proxy_cache label: "{{ proxy_cache.name }}" - when: dsc.harbor.proxyCache is defined \ No newline at end of file + when: dsc.harbor.proxyCache is defined + +- name: Set alerting rules + when: dsc.global.alerting.enabled + kubernetes.core.k8s: + template: prometheusrule.yml.j2 diff --git a/roles/harbor/templates/ca-cm.yaml b/roles/harbor/templates/ca-cm.yaml.j2 similarity index 100% rename from roles/harbor/templates/ca-cm.yaml rename to roles/harbor/templates/ca-cm.yaml.j2 diff --git a/roles/harbor/templates/pg-cluster-harbor-backup.yaml.j2 b/roles/harbor/templates/pg-cluster-harbor-backup.yaml.j2 new file mode 100644 index 00000000..e2e5d555 --- /dev/null +++ b/roles/harbor/templates/pg-cluster-harbor-backup.yaml.j2 @@ -0,0 +1,13 @@ +--- +{% if dsc.global.backup.cnpg.enabled %} +apiVersion: postgresql.cnpg.io/v1 +kind: ScheduledBackup +metadata: + name: pg-cluster-harbor + namespace: {{ dsc.harbor.namespace }} +spec: + schedule: "{{ dsc.global.backup.cnpg.cron }}" + backupOwnerReference: self + cluster: + name: pg-cluster-harbor +{% endif %} diff --git a/roles/harbor/templates/pg-cluster-harbor-nodeport.yaml.j2 b/roles/harbor/templates/pg-cluster-harbor-nodeport.yaml.j2 new file mode 100644 index 00000000..1e70055d --- /dev/null +++ b/roles/harbor/templates/pg-cluster-harbor-nodeport.yaml.j2 @@ -0,0 +1,20 @@ +--- +{% if dsc.harbor.cnpg.exposed %} +apiVersion: v1 +kind: Service +metadata: + labels: + cnpg.io/cluster: pg-cluster-harbor + name: pg-cluster-harbor-rw-nodeport + namespace: {{ dsc.harbor.namespace }} +spec: + ports: + - name: postgres + port: 5432 + protocol: TCP + nodePort: {{ dsc.harbor.cnpg.nodePort }} + selector: + cnpg.io/cluster: pg-cluster-harbor + role: primary + type: NodePort +{% endif %} diff --git a/roles/harbor/templates/pg-cluster-harbor.yaml.j2 b/roles/harbor/templates/pg-cluster-harbor.yaml.j2 index 0078493c..b29792bf 100644 --- a/roles/harbor/templates/pg-cluster-harbor.yaml.j2 +++ b/roles/harbor/templates/pg-cluster-harbor.yaml.j2 @@ -1,3 +1,4 @@ +--- apiVersion: postgresql.cnpg.io/v1 kind: Cluster metadata: @@ -12,72 +13,100 @@ metadata: {% endif %} spec: instances: 3 - # Parameters and pg_hba configuration will be append # to the default ones to make the cluster work {% if use_private_registry %} imageName: "{{ dsc.global.registry }}/cloudnative-pg/postgresql:16.1" {% endif %} - postgresql: -{% if use_private_registry %} - image: "{{ dsc.global.registry }}/cloudnative-pg/postgresql:16.1" +{% if use_image_pull_secrets %} + imagePullSecrets: + - name: dso-config-pull-secret {% endif %} + postgresql: parameters: max_worker_processes: "60" +{% if dsc.harbor.cnpg.mode == "primary" %} pg_hba: # To access through TCP/IP you will need to get username # and password from the secret pg-cluster-harbor-app - host registry harbor all md5 - + - host registry streaming_replica all md5 +{% endif %} bootstrap: +{% if dsc.harbor.cnpg.mode == "primary" %} initdb: database: registry owner: harbor + recovery: null +{% elif dsc.harbor.cnpg.mode == "replica" or dsc.harbor.cnpg.mode == "restore" %} + recovery: + source: pg-cluster-harbor + database: registry + owner: harbor + initdb: null + externalClusters: + - name: pg-cluster-harbor +{% if dsc.harbor.cnpg.mode == "restore" %} + barmanObjectStore: + destinationPath: "s3://{{ dsc.global.backup.s3.bucketName }}/{{ dsc.global.backup.cnpg.pathPrefix }}" + endpointURL: "{{ dsc.global.backup.s3.endpointUrl }}" +{% if dsc.exposedCA.type != 'none' %} + endpointCA: + name: "bundle-cnpg-s3" + key: "ca.pem" +{% endif %} + s3Credentials: + accessKeyId: + name: "{{ dsc.global.backup.s3.credentials.name }}" + key: "{{ dsc.global.backup.s3.credentials.accessKeyId.key }}" + secretAccessKey: + name: "{{ dsc.global.backup.s3.credentials.name }}" + key: "{{ dsc.global.backup.s3.credentials.secretAccessKey.key }}" +{% endif %} +{% if dsc.harbor.cnpg.mode == "replica" %} +{%- filter indent(width=4) %} +{{ dsc.harbor.cnpg.connectionParameters }} +{%- endfilter %} +{% endif %} +{% endif %} - enableSuperuserAccess: true +{% if dsc.harbor.cnpg.mode == "replica" %} + replica: + enabled: true + source: pg-cluster-harbor +{% endif %} + enableSuperuserAccess: true # Example of rolling update strategy: # - unsupervised: automated update of the primary once all # replicas have been upgraded (default) # - supervised: requires manual supervision to perform # the switchover of the primary primaryUpdateStrategy: unsupervised - # Require 1Gi of space per instance using default storage class storage: size: {{ dsc.harbor.postgresPvcSize }} - monitoring: enablePodMonitor: {{ dsc.global.metrics.enabled }} {% if dsc.global.backup.cnpg.enabled %} backup: barmanObjectStore: - destinationPath: "s3://{{ dsc.global.backup.cnpg.destinationPath }}harbor" - endpointURL: "{{ dsc.global.backup.cnpg.endpointURL }}" + destinationPath: "s3://{{ dsc.global.backup.s3.bucketName }}/{{ dsc.global.backup.cnpg.pathPrefix }}" + endpointURL: "{{ dsc.global.backup.s3.endpointUrl }}" +{% if dsc.exposedCA.type != 'none' %} endpointCA: name: "bundle-cnpg-s3" key: "ca.pem" +{% endif %} s3Credentials: accessKeyId: - name: "{{ dsc.global.backup.cnpg.s3Credentials.name }}" - key: "{{ dsc.global.backup.cnpg.s3Credentials.accessKeyId.key }}" + name: "{{ dsc.global.backup.s3.credentials.name }}" + key: "{{ dsc.global.backup.s3.credentials.accessKeyId.key }}" secretAccessKey: - name: "{{ dsc.global.backup.cnpg.s3Credentials.name }}" - key: "{{ dsc.global.backup.cnpg.s3Credentials.secretAccessKey.key }}" + name: "{{ dsc.global.backup.s3.credentials.name }}" + key: "{{ dsc.global.backup.s3.credentials.secretAccessKey.key }}" retentionPolicy: "{{ dsc.global.backup.cnpg.retentionPolicy }}" - ---- -apiVersion: postgresql.cnpg.io/v1 -kind: ScheduledBackup -metadata: - name: pg-cluster-harbor - namespace: {{ dsc.harbor.namespace }} -spec: - schedule: "{{ dsc.global.backup.cnpg.cron }}" - backupOwnerReference: self - cluster: - name: pg-cluster-harbor {% else %} backup: null {% endif %} diff --git a/roles/harbor/templates/prometheusrule.yml.j2 b/roles/harbor/templates/prometheusrule.yml.j2 new file mode 100644 index 00000000..bc3f6886 --- /dev/null +++ b/roles/harbor/templates/prometheusrule.yml.j2 @@ -0,0 +1,157 @@ +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + labels: + app.kubernetes.io/name: gitlab + name: harbor + namespace: {{ dsc.harbor.namespace }} +spec: + groups: + - name: Harbor + rules: + - alert: Harbor core not available + annotations: + message: Harbor core in namespace {{ dsc.harbor.namespace }} has not been available for the last 5 minutes. + summary: Harbor core down (no ready pod)" + expr: | + sum(kube_pod_status_ready{ + pod=~"harbor-core-.*", + namespace="{{ dsc.harbor.namespace }}", + condition="true"}) == 0 + for: 5m + labels: + severity: critical + - alert: Harbor exporter not available + annotations: + message: Harbor exporter in namespace {{ dsc.harbor.namespace }} has not been available for the last 5 minutes. + summary: Harbor exporter down (no ready pod)" + expr: | + sum(kube_pod_status_ready{ + pod=~"harbor-exporter-.*", + namespace="{{ dsc.harbor.namespace }}", + condition="true"}) == 0 + for: 5m + labels: + severity: critical + - alert: Harbor jobservice not available + annotations: + message: Harbor jobservice in namespace {{ dsc.harbor.namespace }} has not been available for the last 5 minutes. + summary: Harbor jobservice down (no ready pod)" + expr: | + sum(kube_pod_status_ready{ + pod=~"harbor-jobservice-.*", + namespace="{{ dsc.harbor.namespace }}", + condition="true"}) == 0 + for: 5m + labels: + severity: critical + - alert: Harbor portal not available + annotations: + message: Harbor portal in namespace {{ dsc.harbor.namespace }} has not been available for the last 5 minutes. + summary: Harbor portal down (no ready pod)" + expr: | + sum(kube_pod_status_ready{ + pod=~"harbor-portal-.*", + namespace="{{ dsc.harbor.namespace }}", + condition="true"}) == 0 + for: 5m + labels: + severity: critical + - alert: Harbor redis not available + annotations: + message: Harbor redis in namespace {{ dsc.harbor.namespace }} has not been available for the last 5 minutes. + summary: Harbor redis down (no ready pod)" + expr: | + sum(kube_pod_status_ready{ + pod=~"harbor-redis-.*", + namespace="{{ dsc.harbor.namespace }}", + condition="true"}) == 0 + for: 5m + labels: + severity: critical + - alert: Harbor registry not available + annotations: + message: Harbor registry in namespace {{ dsc.harbor.namespace }} has not been available for the last 5 minutes. + summary: Harbor registry down (no ready pod)" + expr: | + sum(kube_pod_status_ready{ + pod=~"harbor-registry-.*", + namespace="{{ dsc.harbor.namespace }}", + condition="true"}) == 0 + for: 5m + labels: + severity: critical + - alert: Harbor trivy not available + annotations: + message: Harbor trivy in namespace {{ dsc.harbor.namespace }} has not been available for the last 5 minutes. + summary: Harbor trivy down (no ready pod)" + expr: | + sum(kube_pod_status_ready{ + pod=~"harbor-trivy-.*", + namespace="{{ dsc.harbor.namespace }}", + condition="true"}) == 0 + for: 5m + labels: + severity: critical + - alert: Harbor Pod not healthy + annotations: + message: Harbor {{"{{"}} $labels.pod {{"}}"}} pod in namespace {{ dsc.harbor.namespace }} has been unavailable for the last 5 minutes. + summary: Harbor {{"{{"}} $labels.pod {{"}}"}} pod not healthy (container {{"{{"}} $labels.container {{"}}"}} is not ready) + expr: | + kube_pod_container_status_ready{ + pod=~"harbor-.*", + namespace="{{ dsc.harbor.namespace }}"} == 0 + for: 5m + labels: + severity: warning + - alert: Harbor DB not available + annotations: + message: All Harbor CNPG pods in namespace {{ dsc.harbor.namespace }} have been unavailable for the last 5 minutes. + summary: Harbor database down (containers not ready) + expr: | + (absent(kube_pod_container_status_ready{ + pod=~"pg-cluster-harbor-\\d+", + container="postgres", namespace="{{ dsc.harbor.namespace }}"}) == 1) + or sum(kube_pod_container_status_ready{ + pod=~"pg-cluster-harbor-\\d+", + container="postgres", namespace="{{ dsc.harbor.namespace }}"}) == 0 + for: 5m + labels: + severity: critical + - alert: Harbor DB Pod not healthy + annotations: + message: Harbor {{"{{"}} $labels.pod {{"}}"}} pod in namespace {{ dsc.harbor.namespace }} has been unavailable for the last 5 minutes. + summary: Harbor database pod not healthy (container is not ready) + expr: | + kube_pod_container_status_ready{ + pod=~"pg-cluster-harbor-\\d+", + container="postgres", namespace="{{ dsc.harbor.namespace }}"} == 0 + for: 5m + labels: + severity: warning + - alert: Harbor PVC almost out of disk space + annotations: + message: PVC {{"{{"}} $labels.persistentvolumeclaim {{"}}"}} in namespace {{ dsc.harbor.namespace }} is almost full (< 10% left). VALUE = {{"{{"}} $value {{"}}"}}% + summary: Harbor PVC almost out of disk space in namespace {{ dsc.harbor.namespace }} + expr: | + round( + kubelet_volume_stats_available_bytes{ + persistentvolumeclaim=~"(.*-)*harbor(-.*)*", + namespace="{{ dsc.harbor.namespace }}"} + / kubelet_volume_stats_capacity_bytes{ + persistentvolumeclaim=~"(.*-)*harbor(-.*)*", + namespace="{{ dsc.harbor.namespace }}"} * 100, 0.01) < 10 > 0 + for: 1m + labels: + severity: warning + - alert: Harbor PVC out of disk space + annotations: + message: PVC {{"{{"}} $labels.persistentvolumeclaim {{"}}"}} in namespace {{ dsc.harbor.namespace }} is full (0% left). + summary: Harbor PVC out of disk space in namespace {{ dsc.harbor.namespace }} + expr: | + kubelet_volume_stats_available_bytes{ + persistentvolumeclaim=~"(.*-)*harbor(-.*)*", + namespace="{{ dsc.harbor.namespace }}"} == 0 + for: 1m + labels: + severity: critical diff --git a/roles/harbor/templates/values/00-main.j2 b/roles/harbor/templates/values/00-main.j2 index 46cec0ca..b1634c10 100644 --- a/roles/harbor/templates/values/00-main.j2 +++ b/roles/harbor/templates/values/00-main.j2 @@ -61,6 +61,8 @@ jobservice: serviceAccountName: harbor-sa image: repository: docker.io/goharbor/harbor-jobservice + jobLoggers: + - stdout registry: replicas: 3 serviceAccountName: harbor-sa diff --git a/roles/harbor/templates/values/10-registry.j2 b/roles/harbor/templates/values/10-registry.j2 index c7ee7827..70cdec93 100644 --- a/roles/harbor/templates/values/10-registry.j2 +++ b/roles/harbor/templates/values/10-registry.j2 @@ -41,3 +41,9 @@ exporter: image: repository: "{{ dsc.global.registry }}/goharbor/harbor-exporter" {% endif %} + + +{% if use_image_pull_secrets %} +imagePullSecrets: + - name: dso-config-pull-secret +{% endif %} \ No newline at end of file diff --git a/roles/keycloak/files/generic-client-scope-protocolMappers.yaml b/roles/keycloak/files/generic-client-scope-protocolMappers.yaml index 7d5b4ecf..6437d71b 100644 --- a/roles/keycloak/files/generic-client-scope-protocolMappers.yaml +++ b/roles/keycloak/files/generic-client-scope-protocolMappers.yaml @@ -140,4 +140,4 @@ id.token.claim: true access.token.claim: true claim.name: email - jsonType.label: String \ No newline at end of file + jsonType.label: String diff --git a/roles/keycloak/tasks/main.yml b/roles/keycloak/tasks/main.yml index 950fd79f..b5bb1bed 100644 --- a/roles/keycloak/tasks/main.yml +++ b/roles/keycloak/tasks/main.yml @@ -8,20 +8,20 @@ - name: CNPG s3 CA (secret) when: > - dsc.global.backup.cnpg.enabled and + dsc.global.backup.cnpg.enabled and dsc.global.backup.cnpg.endpointCA.namespace is defined and dsc.global.backup.cnpg.endpointCA.name is defined and dsc.global.backup.cnpg.endpointCA.key is defined block: - name: Get secret kubernetes.core.k8s_info: - name: "{{ dsc.global.backup.cnpg.endpointCA.name }}" - namespace: "{{ dsc.global.backup.cnpg.endpointCA.namespace }}" + name: "{{ dsc.global.backup.endpointCa.name }}" + namespace: "{{ dsc.global.backup.endpointCa.namespace }}" kind: Secret register: cnpg_s3_ca_resource - name: Extract key - ansible.builtin.set_fact: + ansible.builtin.set_fact: cnpg_s3_ca_pem: "{{ cnpg_s3_ca_resource.resources[0].data[dsc.global.backup.cnpg.endpointCA.key] }}" - name: Set cnpg bundle-ca secret @@ -36,14 +36,14 @@ - name: Set cnpg backup secret kubernetes.core.k8s: - name: "{{ dsc.global.backup.cnpg.s3Credentials.name }}" + name: "{{ dsc.global.backup.s3Credentials.name }}" namespace: "{{ dsc.keycloak.namespace }}" kind: Secret api_version: v1 definition: data: - accessKeyId: "{{ dsc.global.backup.cnpg.s3Credentials.accessKeyId.value | b64encode }}" - secretAccessKey: "{{ dsc.global.backup.cnpg.s3Credentials.secretAccessKey.value | b64encode }}" + accessKeyId: "{{ dsc.global.backup.s3Credentials.accessKeyId.value | b64encode }}" + secretAccessKey: "{{ dsc.global.backup.s3Credentials.secretAccessKey.value | b64encode }}" when: dsc.global.backup.cnpg.enabled - name: Remove cnpg scheduled backup @@ -57,7 +57,11 @@ - name: Create PostgreSQL cluster and keycloak database kubernetes.core.k8s: - template: pg-cluster-keycloak.yaml.j2 + template: "{{ item }}" + with_items: + - pg-cluster-keycloak.yaml.j2 + - pg-cluster-keycloak-backup.yaml.j2 + - pg-cluster-keycloak-nodeport.yaml.j2 - name: Wait pg-cluster-keycloak-rw endpoint kubernetes.core.k8s_info: @@ -177,7 +181,8 @@ - name: Add bitnami helm repo kubernetes.core.helm_repository: name: bitnami - repo_url: https://charts.bitnami.com/bitnami + repo_url: "{{ dsc.keycloak.helmRepoUrl }}" + force_update: true - name: Set path fact ansible.builtin.set_fact: @@ -417,7 +422,7 @@ auth_password: "{{ keycloak_admin_password }}" realm: "{{ item }}" brute_force_protected: true - failure_factor: 10 + failure_factor: 10 with_items: - master - dso diff --git a/roles/keycloak/templates/console-frontend-redirectUris.yaml b/roles/keycloak/templates/console-frontend-redirectUris.yaml.j2 similarity index 89% rename from roles/keycloak/templates/console-frontend-redirectUris.yaml rename to roles/keycloak/templates/console-frontend-redirectUris.yaml.j2 index ad570c7e..b742e595 100644 --- a/roles/keycloak/templates/console-frontend-redirectUris.yaml +++ b/roles/keycloak/templates/console-frontend-redirectUris.yaml.j2 @@ -4,4 +4,5 @@ - "http://console.dso.local/*" - "http://localhost:8080/*" - "http://127.0.0.1:8080/*" +- "https://console.pr-*" {% endif %} \ No newline at end of file diff --git a/roles/keycloak/templates/console-frontend-webOrigins.yaml b/roles/keycloak/templates/console-frontend-webOrigins.yaml.j2 similarity index 88% rename from roles/keycloak/templates/console-frontend-webOrigins.yaml rename to roles/keycloak/templates/console-frontend-webOrigins.yaml.j2 index 7e568356..c1ddd103 100644 --- a/roles/keycloak/templates/console-frontend-webOrigins.yaml +++ b/roles/keycloak/templates/console-frontend-webOrigins.yaml.j2 @@ -4,4 +4,5 @@ - "http://console.dso.local" - "http://localhost:8080" - "http://127.0.0.1:8080/*" +- "https://console.pr-*" {% endif %} \ No newline at end of file diff --git a/roles/keycloak/templates/pg-cluster-keycloak-backup.yaml.j2 b/roles/keycloak/templates/pg-cluster-keycloak-backup.yaml.j2 new file mode 100644 index 00000000..10a982ab --- /dev/null +++ b/roles/keycloak/templates/pg-cluster-keycloak-backup.yaml.j2 @@ -0,0 +1,13 @@ +--- +{% if dsc.global.backup.cnpg.enabled %} +apiVersion: postgresql.cnpg.io/v1 +kind: ScheduledBackup +metadata: + name: pg-cluster-keycloak + namespace: {{ dsc.keycloak.namespace }} +spec: + schedule: "{{ dsc.global.backup.cnpg.cron }}" + backupOwnerReference: self + cluster: + name: pg-cluster-keycloak +{% endif %} diff --git a/roles/keycloak/templates/pg-cluster-keycloak-nodeport.yaml.j2 b/roles/keycloak/templates/pg-cluster-keycloak-nodeport.yaml.j2 new file mode 100644 index 00000000..ab93bbe5 --- /dev/null +++ b/roles/keycloak/templates/pg-cluster-keycloak-nodeport.yaml.j2 @@ -0,0 +1,20 @@ +--- +{% if dsc.keycloak.cnpg.exposed %} +apiVersion: v1 +kind: Service +metadata: + labels: + cnpg.io/cluster: pg-cluster-keycloak + name: pg-cluster-keycloak-rw-nodeport + namespace: {{ dsc.keycloak.namespace }} +spec: + ports: + - name: postgres + port: 5432 + protocol: TCP + nodePort: {{ dsc.keycloak.cnpg.nodePort }} + selector: + cnpg.io/cluster: pg-cluster-keycloak + role: primary + type: NodePort +{% endif %} diff --git a/roles/keycloak/templates/pg-cluster-keycloak.yaml.j2 b/roles/keycloak/templates/pg-cluster-keycloak.yaml.j2 index eb0a1399..135d60f5 100644 --- a/roles/keycloak/templates/pg-cluster-keycloak.yaml.j2 +++ b/roles/keycloak/templates/pg-cluster-keycloak.yaml.j2 @@ -1,3 +1,4 @@ +--- apiVersion: postgresql.cnpg.io/v1 kind: Cluster metadata: @@ -12,72 +13,100 @@ metadata: {% endif %} spec: instances: 3 - # Parameters and pg_hba configuration will be append # to the default ones to make the cluster work {% if use_private_registry %} imageName: "{{ dsc.global.registry }}/cloudnative-pg/postgresql:16.1" {% endif %} - postgresql: -{% if use_private_registry %} - image: "{{ dsc.global.registry }}/cloudnative-pg/postgresql:16.1" +{% if use_image_pull_secrets %} + imagePullSecrets: + - name: dso-config-pull-secret {% endif %} + postgresql: parameters: max_worker_processes: "60" +{% if dsc.keycloak.cnpg.mode == "primary" %} pg_hba: # To access through TCP/IP you will need to get username # and password from the secret pg-cluster-keycloak-app - host keycloak keycloak all md5 - + - host keycloak streaming_replica all md5 +{% endif %} bootstrap: +{% if dsc.keycloak.cnpg.mode == "primary" %} initdb: database: keycloak owner: keycloak + recovery: null +{% elif dsc.keycloak.cnpg.mode == "replica" or dsc.keycloak.cnpg.mode == "restore" %} + recovery: + source: pg-cluster-keycloak + database: keycloak + owner: keycloak + initdb: null + externalClusters: + - name: pg-cluster-keycloak +{% if dsc.keycloak.cnpg.mode == "restore" %} + barmanObjectStore: + destinationPath: "s3://{{ dsc.global.backup.s3.bucketName }}/{{ dsc.global.backup.cnpg.pathPrefix }}" + endpointURL: "{{ dsc.global.backup.s3.endpointUrl }}" +{% if dsc.exposedCA.type != 'none' %} + endpointCA: + name: "bundle-cnpg-s3" + key: "ca.pem" +{% endif %} + s3Credentials: + accessKeyId: + name: "{{ dsc.global.backup.s3.credentials.name }}" + key: "{{ dsc.global.backup.s3.credentials.accessKeyId.key }}" + secretAccessKey: + name: "{{ dsc.global.backup.s3.credentials.name }}" + key: "{{ dsc.global.backup.s3.credentials.secretAccessKey.key }}" +{% endif %} +{% if dsc.keycloak.cnpg.mode == "replica" %} +{%- filter indent(width=4) %} +{{ dsc.keycloak.cnpg.connectionParameters }} +{%- endfilter %} +{% endif %} +{% endif %} - enableSuperuserAccess: true +{% if dsc.keycloak.cnpg.mode == "replica" %} + replica: + enabled: true + source: pg-cluster-keycloak +{% endif %} + enableSuperuserAccess: true # Example of rolling update strategy: # - unsupervised: automated update of the primary once all # replicas have been upgraded (default) # - supervised: requires manual supervision to perform # the switchover of the primary primaryUpdateStrategy: unsupervised - # Require 1Gi of space per instance using default storage class storage: size: {{ dsc.keycloak.postgresPvcSize }} - monitoring: enablePodMonitor: {{ dsc.global.metrics.enabled }} {% if dsc.global.backup.cnpg.enabled %} backup: barmanObjectStore: - destinationPath: "s3://{{ dsc.global.backup.cnpg.destinationPath }}keycloak" - endpointURL: "{{ dsc.global.backup.cnpg.endpointURL }}" + destinationPath: "s3://{{ dsc.global.backup.s3.bucketName }}/{{ dsc.global.backup.cnpg.pathPrefix }}" + endpointURL: "{{ dsc.global.backup.s3.endpointUrl }}" +{% if dsc.exposedCA.type != 'none' %} endpointCA: name: "bundle-cnpg-s3" key: "ca.pem" +{% endif %} s3Credentials: accessKeyId: - name: "{{ dsc.global.backup.cnpg.s3Credentials.name }}" - key: "{{ dsc.global.backup.cnpg.s3Credentials.accessKeyId.key }}" + name: "{{ dsc.global.backup.s3.credentials.name }}" + key: "{{ dsc.global.backup.s3.credentials.accessKeyId.key }}" secretAccessKey: - name: "{{ dsc.global.backup.cnpg.s3Credentials.name }}" - key: "{{ dsc.global.backup.cnpg.s3Credentials.secretAccessKey.key }}" + name: "{{ dsc.global.backup.s3.credentials.name }}" + key: "{{ dsc.global.backup.s3.credentials.secretAccessKey.key }}" retentionPolicy: "{{ dsc.global.backup.cnpg.retentionPolicy }}" - ---- -apiVersion: postgresql.cnpg.io/v1 -kind: ScheduledBackup -metadata: - name: pg-cluster-keycloak - namespace: {{ dsc.keycloak.namespace }} -spec: - schedule: "{{ dsc.global.backup.cnpg.cron }}" - backupOwnerReference: self - cluster: - name: pg-cluster-keycloak {% else %} backup: null {% endif %} diff --git a/roles/keycloak/templates/values/00-main.j2 b/roles/keycloak/templates/values/00-main.j2 index a225bbf5..c0a2afc5 100644 --- a/roles/keycloak/templates/values/00-main.j2 +++ b/roles/keycloak/templates/values/00-main.j2 @@ -151,7 +151,93 @@ metrics: - path: '/realms/master/metrics' - path: '/realms/dso/metrics' prometheusRule: - enabled: false + enabled: {{ dsc.global.alerting.enabled }} + namespace: {{ dsc.keycloak.namespace }} + labels: {} + groups: +{% raw %} + - name: Keycloak + rules: + - alert: Keycloak instance not available + annotations: + message: Keycloak instance in namespace {{ include "common.names.namespace" . }} has not been available for the last 5 minutes. + summary: Keycloak instance down (no ready container) + expr: | + (absent(kube_pod_container_status_ready{ + pod=~"{{ include "common.names.fullname" . }}-\\d+", + container="{{ include "common.names.fullname" . }}", + namespace="{{ include "common.names.namespace" . }}"}) == 1) + or sum(kube_pod_container_status_ready{ + pod=~"{{ include "common.names.fullname" . }}-\\d+", + container="{{ include "common.names.fullname" . }}", + namespace="{{ include "common.names.namespace" . }}"}) == 0 + for: 5m + labels: + severity: critical + - alert: Keycloak Pod not healthy + annotations: + message: Keycloak {{"{{"}} $labels.pod {{"}}"}} pod in namespace {{ include "common.names.namespace" . }} has been unavailable for the last 5 minutes. + summary: Keycloak pod not healthy (container is not ready) + expr: | + kube_pod_container_status_ready{ + pod=~"{{ include "common.names.fullname" . }}-\\d+", + container="{{ include "common.names.fullname" . }}", + namespace="{{ include "common.names.namespace" . }}"} == 0 + for: 5m + labels: + severity: warning + - alert: Keycloak DB not available + annotations: + message: All Keycloak CNPG pods in namespace {{ include "common.names.namespace" . }} have been unavailable for the last 5 minutes. + summary: Keycloak database down (containers not ready) + expr: | + (absent(kube_pod_container_status_ready{ + pod=~"pg-cluster-{{ include "common.names.fullname" . }}-\\d+", + container="postgres", namespace="{{ include "common.names.namespace" . }}"}) == 1) + or sum(kube_pod_container_status_ready{ + pod=~"pg-cluster-{{ include "common.names.fullname" . }}-\\d+", + container="postgres", namespace="{{ include "common.names.namespace" . }}"}) == 0 + for: 5m + labels: + severity: critical + - alert: Keycloak DB Pod not healthy + annotations: + message: Keycloak {{"{{"}} $labels.pod {{"}}"}} pod in namespace {{ include "common.names.namespace" . }} has been unavailable for the last 5 minutes. + summary: Keycloak database pod not healthy (container is not ready) + expr: | + kube_pod_container_status_ready{ + pod=~"pg-cluster-{{ include "common.names.fullname" . }}-\\d+", + container="postgres", namespace="{{ include "common.names.namespace" . }}"} == 0 + for: 5m + labels: + severity: warning + - alert: Keycloak DB PVC almost out of disk space + annotations: + message: PVC {{"{{"}} $labels.persistentvolumeclaim {{"}}"}} in namespace {{ include "common.names.namespace" . }} is almost full (< 10% left). VALUE = {{"{{"}} $value {{"}}"}}% + summary: Keycloak CNPG PVC almost out of disk space in namespace {{ include "common.names.namespace" . }} + expr: | + round( + kubelet_volume_stats_available_bytes{ + persistentvolumeclaim=~"pg-cluster-{{ include "common.names.fullname" . }}-\\d+", + namespace="{{ include "common.names.namespace" . }}"} + / kubelet_volume_stats_capacity_bytes{ + persistentvolumeclaim=~"pg-cluster-{{ include "common.names.fullname" . }}-\\d+", + namespace="{{ include "common.names.namespace" . }}"} * 100, 0.01) < 10 > 0 + for: 1m + labels: + severity: warning + - alert: Keycloak DB PVC out of disk space + annotations: + message: PVC {{"{{"}} $labels.persistentvolumeclaim {{"}}"}} in namespace {{ include "common.names.namespace" . }} is full (0% left). + summary: Keycloak CNPG PVC out of disk space in namespace {{ include "common.names.namespace" . }} + expr: | + kubelet_volume_stats_available_bytes{ + persistentvolumeclaim=~"pg-cluster-{{ include "common.names.fullname" . }}-\\d+", + namespace="{{ include "common.names.namespace" . }}"} == 0 + for: 1m + labels: + severity: critical +{% endraw %} keycloakConfigCli: enabled: false @@ -219,13 +305,17 @@ extraEnvVars: value: cloudpinative-relations@interieur.gouv.fr initContainers: - name: realm-ext-provider +{% if use_private_registry %} + image: "{{ dsc.global.registry }}/curlimages/curl:8.8.0" +{% else %} image: docker.io/curlimages/curl:8.8.0 +{% endif %} imagePullPolicy: IfNotPresent command: - sh args: - -c - - curl -L -f -S -o /extensions/keycloak-theme-dsfr.jar https://github.com/codegouvfr/keycloak-theme-dsfr/releases/download/v1.0.3/retrocompat-keycloak-theme.jar + - curl -k -L -f -S -o /extensions/keycloak-theme-dsfr.jar {{ dsc.keycloak.pluginDownloadUrl }}/retrocompat-keycloak-theme.jar volumeMounts: - name: extensions mountPath: /extensions diff --git a/roles/keycloak/templates/values/10-registry.j2 b/roles/keycloak/templates/values/10-registry.j2 index 1e7d4b9a..e5f3a7aa 100644 --- a/roles/keycloak/templates/values/10-registry.j2 +++ b/roles/keycloak/templates/values/10-registry.j2 @@ -2,3 +2,9 @@ image: registry: "{{ dsc.global.registry }}" {% endif %} + +{% if use_image_pull_secrets %} +global: + imagePullSecrets: + - dso-config-pull-secret +{% endif %} \ No newline at end of file diff --git a/roles/keycloak/vars/main.yaml b/roles/keycloak/vars/main.yaml index 4b0efc50..2156233f 100644 --- a/roles/keycloak/vars/main.yaml +++ b/roles/keycloak/vars/main.yaml @@ -14,8 +14,8 @@ keycloak_clients: - clientId: console-frontend standardFlowEnabled: true directAccessGrantsEnabled: true - redirectUris: "{{ lookup('ansible.builtin.template', 'console-frontend-redirectUris.yaml') | from_yaml }}" - webOrigins: "{{ lookup('ansible.builtin.template', 'console-frontend-webOrigins.yaml') | from_yaml }}" + redirectUris: "{{ lookup('ansible.builtin.template', 'console-frontend-redirectUris.yaml.j2') | from_yaml }}" + webOrigins: "{{ lookup('ansible.builtin.template', 'console-frontend-webOrigins.yaml.j2') | from_yaml }}" defaultClientScopes: - generic publicClient: true diff --git a/roles/kyverno/tasks/main.yaml b/roles/kyverno/tasks/main.yaml index 432b54d1..f878ab42 100644 --- a/roles/kyverno/tasks/main.yaml +++ b/roles/kyverno/tasks/main.yaml @@ -9,7 +9,7 @@ - name: Set path fact ansible.builtin.set_fact: path: "{{ role_path + '/templates/values' }}" - + - name: Compute Kyverno Helm values ansible.builtin.include_role: name: combine @@ -18,12 +18,15 @@ combine_dest_var: "kyverno_values" - name: Install Kyverno - when: kyverno_pods.resources | length == 0 + when: > + kyverno_pods.resources | length == 0 or + dsc.kyverno.forcedInstall block: - name: Add helm repo kubernetes.core.helm_repository: name: kyverno - repo_url: https://kyverno.github.io/kyverno/ + repo_url: "{{ dsc.kyverno.helmRepoUrl }}" + force_update: true - name: Deploy helm kubernetes.core.helm: @@ -34,6 +37,11 @@ create_namespace: true values: "{{ kyverno_values }}" + - name: Set alerting rules + when: dsc.global.alerting.enabled + kubernetes.core.k8s: + template: prometheusrule.yml.j2 + - name: Wait Kyverno service endpoint to be available kubernetes.core.k8s_info: kind: Endpoints @@ -54,6 +62,41 @@ | reject('equalto', dsc.kyverno.namespace) }}" +- name: Check replace-kubed ClusterPolicy + kubernetes.core.k8s_info: + kind: ClusterPolicy + name: replace-kubed + register: replace_kubed_cp + - name: Create replace-kubed ClusterPolicy + when: replace_kubed_cp.resources | length == 0 kubernetes.core.k8s: template: replace-kubed.yml.j2 + +- name: Check security-context ClusterPolicy + kubernetes.core.k8s_info: + kind: ClusterPolicy + name: security-context-dso + register: security_context_cp + +- name: Create security-context ClusterPolicy for cis profile + when: > + dsc.global.profile is defined and + dsc.global.profile == "cis" and + security_context_cp.resources | length == 0 + kubernetes.core.k8s: + template: cis.yml.j2 + +- name: Check exposed-ca ClusterPolicy + kubernetes.core.k8s_info: + kind: ClusterPolicy + name: exposed-ca-dso-gitlab-runner + register: exposed_ca_cp + +- name: Create ClusterPolicy for exposedCA + when: > + exposed_ca_cp.resources | length == 0 and + (dsc.exposedCA.type == "configmap" or + dsc.exposedCA.type == "secret") + kubernetes.core.k8s: + template: exposedCA.yml.j2 diff --git a/roles/kyverno/templates/cis.yml.j2 b/roles/kyverno/templates/cis.yml.j2 new file mode 100644 index 00000000..bc98fe48 --- /dev/null +++ b/roles/kyverno/templates/cis.yml.j2 @@ -0,0 +1,535 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: security-context-dso + annotations: + policies.kyverno.io/title: Enforce cis profile + pod-policies.kyverno.io/autogen-controllers: none + policies.kyverno.io/category: Prod + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Deployment, StatefulSet, Job +spec: + validationFailureAction: Enforce +spec: + rules: + - name: enforce-security-context + match: + resources: + kinds: + - Deployment + - StatefulSet + - Job + namespaces: + - "{{ dsc.nexus.namespace }}" + - "{{ dsc.gitlabOperator.namespace }}" + - "{{ dsc.argocd.namespace }}" + - "{{ dsc.sonarqube.namespace }}" + exclude: + all: + - resources: + kinds: + - Job + namespaces: + - "dso-*" + names: + - "pg-cluster-*" + mutate: + patchStrategicMerge: + spec: + template: + spec: + securityContext: + +(runAsNonRoot): true + +(runAsUser): 65534 + containers: + - name: '*' + securityContext: + +(allowPrivilegeEscalation): false + +(capabilities): + +(drop): + - ALL + +(runAsNonRoot): true + +(runAsUser): 65534 + +(seccompProfile): + type: RuntimeDefault + initContainers: + - name: '*' + securityContext: + +(allowPrivilegeEscalation): false + +(capabilities): + +(drop): + - ALL + +(runAsNonRoot): true + +(runAsUser): 65534 + +(seccompProfile): + type: RuntimeDefault +--- +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: security-context-dso-keycloak + annotations: + policies.kyverno.io/title: Enforce cis profile + pod-policies.kyverno.io/autogen-controllers: none + policies.kyverno.io/category: Prod + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Deployment, StatefulSet, Job +spec: + validationFailureAction: Enforce +spec: + rules: + - name: enforce-security-context + match: + resources: + kinds: + - Deployment + - StatefulSet + - Job + namespaces: + - "{{ dsc.keycloak.namespace }}" + exclude: + all: + - resources: + kinds: + - Job + namespaces: + - "{{ dsc.keycloak.namespace }}" + names: + - "pg-cluster-*" + mutate: + patchStrategicMerge: + spec: + template: + spec: + securityContext: + +(runAsNonRoot): true + +(runAsUser): 1001 + containers: + - name: '*' + securityContext: + +(allowPrivilegeEscalation): false + +(capabilities): + +(drop): + - ALL + +(runAsNonRoot): true + +(runAsUser): 1001 + +(seccompProfile): + type: RuntimeDefault + initContainers: + - name: '*' + securityContext: + +(allowPrivilegeEscalation): false + +(capabilities): + +(drop): + - ALL + +(runAsNonRoot): true + +(runAsUser): 1001 + +(seccompProfile): + type: RuntimeDefault +--- +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: security-context-dso-gitlab-runner + annotations: + policies.kyverno.io/title: Enforce cis profile + pod-policies.kyverno.io/autogen-controllers: none + policies.kyverno.io/category: Prod + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Pod +spec: + validationFailureAction: Enforce +spec: + rules: + - name: enforce-security-context + match: + resources: + kinds: + - Pod + namespaces: + - "{{ dsc.gitlab.namespace }}" + names: + - "runner-*" + mutate: + patchStrategicMerge: + spec: + containers: + - name: helper + env: + - name: HOME + value: "/tmp" + securityContext: + runAsUser: 65534 + runAsNonRoot: true + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + seccompProfile: + type: RuntimeDefault + - name: build + env: + - name: HOME + value: "/tmp" + securityContext: + runAsUser: 999 + runAsNonRoot: true + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + seccompProfile: + type: RuntimeDefault + initContainers: + - (name): "*" + securityContext: + runAsUser: 65534 + runAsNonRoot: true + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + seccompProfile: + type: RuntimeDefault +--- +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: security-context-dso-gitlab + annotations: + policies.kyverno.io/title: Enforce cis profile + pod-policies.kyverno.io/autogen-controllers: none + policies.kyverno.io/category: Prod + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Deployment, StatefulSet, Job +spec: + validationFailureAction: Enforce +spec: + rules: + - name: enforce-security-context + match: + resources: + kinds: + - Deployment + - StatefulSet + - Job + namespaces: + - "{{ dsc.gitlab.namespace }}" + exclude: + all: + - resources: + kinds: + - Job + namespaces: + - "{{ dsc.gitlab.namespace }}" + names: + - "pg-cluster-*" + - "gitlab-shared-secrets-*-selfsign" + mutate: + patchStrategicMerge: + spec: + template: + spec: + securityContext: + +(runAsNonRoot): true + containers: + - name: '*' + securityContext: + +(allowPrivilegeEscalation): false + +(capabilities): + +(drop): + - ALL + +(runAsNonRoot): true + +(seccompProfile): + type: RuntimeDefault + initContainers: + - name: '*' + securityContext: + +(allowPrivilegeEscalation): false + +(capabilities): + +(drop): + - ALL + +(runAsNonRoot): true + +(seccompProfile): + type: RuntimeDefault +--- +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: security-context-dso-gitlab-job + annotations: + policies.kyverno.io/title: Enforce cis profile + pod-policies.kyverno.io/autogen-controllers: none + policies.kyverno.io/category: Prod + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Deployment, StatefulSet, Job +spec: + validationFailureAction: Enforce +spec: + rules: + - name: enforce-security-context + match: + resources: + kinds: + - Job + namespaces: + - "{{ dsc.gitlab.namespace }}" + names: + - "gitlab-shared-secrets-*-selfsign" + mutate: + patchStrategicMerge: + spec: + template: + spec: + securityContext: + +(runAsNonRoot): true + +(runAsUser): 65534 + containers: + - name: '*' + securityContext: + +(allowPrivilegeEscalation): false + +(capabilities): + +(drop): + - ALL + +(runAsNonRoot): true + +(runAsUser): 65534 + +(seccompProfile): + type: RuntimeDefault + initContainers: + - name: '*' + securityContext: + +(allowPrivilegeEscalation): false + +(capabilities): + +(drop): + - ALL + +(runAsNonRoot): true + +(runAsUser): 65534 + +(seccompProfile): + type: RuntimeDefault +--- +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: security-context-dso-vault + annotations: + policies.kyverno.io/title: Enforce cis profile + pod-policies.kyverno.io/autogen-controllers: none + policies.kyverno.io/category: Prod + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Deployment, StatefulSet, Job +spec: + validationFailureAction: Enforce +spec: + rules: + - name: enforce-security-context + match: + resources: + kinds: + - Deployment + - StatefulSet + - Job + namespaces: + - "{{ dsc.vault.namespace }}" + exclude: + all: + - resources: + kinds: + - Job + namespaces: + - "dso-*" + names: + - "pg-cluster-*" + mutate: + patchStrategicMerge: + spec: + template: + spec: + securityContext: + +(runAsNonRoot): true + +(runAsUser): 100 + containers: + - name: '*' + securityContext: + +(allowPrivilegeEscalation): false + +(capabilities): + +(drop): + - ALL + +(runAsNonRoot): true + +(runAsUser): 100 + +(seccompProfile): + type: RuntimeDefault + initContainers: + - name: '*' + securityContext: + +(allowPrivilegeEscalation): false + +(capabilities): + +(drop): + - ALL + +(runAsNonRoot): true + +(runAsUser): 100 + +(seccompProfile): + type: RuntimeDefault +--- +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: security-context-dso-harbor + annotations: + policies.kyverno.io/title: Enforce cis profile + pod-policies.kyverno.io/autogen-controllers: none + policies.kyverno.io/category: Prod + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Deployment, StatefulSet, Job +spec: + validationFailureAction: Enforce +spec: + rules: + - name: enforce-security-context + match: + resources: + kinds: + - Deployment + - StatefulSet + - Job + namespaces: + - "{{ dsc.harbor.namespace }}" + exclude: + all: + - resources: + kinds: + - Job + namespaces: + - "dso-*" + names: + - "pg-cluster-*" + mutate: + patchStrategicMerge: + spec: + template: + spec: + securityContext: + +(runAsNonRoot): true + +(runAsUser): 10000 + containers: + - name: '*' + securityContext: + +(allowPrivilegeEscalation): false + +(capabilities): + +(drop): + - ALL + +(runAsNonRoot): true + +(runAsUser): 10000 + +(seccompProfile): + type: RuntimeDefault + initContainers: + - name: '*' + securityContext: + +(allowPrivilegeEscalation): false + +(capabilities): + +(drop): + - ALL + +(runAsNonRoot): true + +(runAsUser): 10000 + +(seccompProfile): + type: RuntimeDefault +--- +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: non-root-security-context + annotations: + policies.kyverno.io/title: Enforce cis profile + pod-policies.kyverno.io/autogen-controllers: none + policies.kyverno.io/category: Prod + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Deployment, StatefulSet, Job +spec: + validationFailureAction: Enforce +spec: + rules: + - name: enforce-security-context + match: + resources: + kinds: + - Deployment + - StatefulSet + - Job + namespaces: + - "dso-*" + exclude: + all: + - resources: + kinds: + - Job + namespaces: + - "dso-*" + names: + - "pg-cluster-*" + preconditions: + any: + - key: "{% raw %}{{ request.object.spec.template.spec.securityContext.runAsUser || '' }}{% endraw %}" + operator: Equals + value: 0 + mutate: + patchStrategicMerge: + spec: + template: + spec: + securityContext: + runAsNonRoot: true + runAsUser: 1000 + containers: + - (name): "*" + +(securityContext): + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + runAsNonRoot: true + runAsUser: 1000 + seccompProfile: + type: RuntimeDefault + initContainers: + - (name): "*" + +(securityContext): + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + runAsNonRoot: true + runAsUser: 1000 + seccompProfile: + type: RuntimeDefault +--- +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: set-home-env-var + annotations: + policies.kyverno.io/title: Set HOME environment variable + policies.kyverno.io/autogen-controllers: none + policies.kyverno.io/category: Prod + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Job +spec: + validationFailureAction: Enforce + rules: + - name: set-home-env-var + match: + resources: + kinds: + - Job + names: + - "gitlab-minio-create-buckets-*" + namespaces: + - "{{ dsc.gitlab.namespace }}" + mutate: + patchStrategicMerge: + spec: + template: + spec: + containers: + - name: minio-mc + env: + - name: HOME + value: "/tmp" diff --git a/roles/kyverno/templates/exposedCA.yml.j2 b/roles/kyverno/templates/exposedCA.yml.j2 new file mode 100644 index 00000000..fe1cee67 --- /dev/null +++ b/roles/kyverno/templates/exposedCA.yml.j2 @@ -0,0 +1,91 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: exposed-ca-dso-gitlab-runner + annotations: + policies.kyverno.io/title: Mount exposed ca-certificates + pod-policies.kyverno.io/autogen-controllers: none + policies.kyverno.io/category: Prod + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Pod +spec: + validationFailureAction: Enforce +spec: + rules: + - name: enforce-security-context + match: + resources: + kinds: + - Pod + namespaces: + - "{{ dsc.gitlab.namespace }}" + names: + - "runner-*" + mutate: + patchStrategicMerge: + spec: + containers: + - name: build + env: + - name: VAULT_CACERT + value: "/tmp/local/share/ca-certificates/tls.crt" + - name: GIT_SSL_CAINFO + value: "/tmp/local/share/ca-certificates/tls.crt" + volumeMounts: + - name: custom-ca-certificates + mountPath: /tmp/local/share/ca-certificates + readOnly: true + volumes: + - name: custom-ca-certificates + projected: + defaultMode: 292 + sources: + - secret: + name: exposed-ca +--- +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: exposed-ca-dso-vault + annotations: + policies.kyverno.io/title: Mount exposed ca-certificates + pod-policies.kyverno.io/autogen-controllers: none + policies.kyverno.io/category: Prod + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: StatefulSet +spec: + validationFailureAction: Enforce +spec: + rules: + - name: enforce-security-context + match: + resources: + kinds: + - StatefulSet + namespaces: + - "{{ dsc.vault.namespace }}" + names: + - "conf-dso-vault" + mutate: + patchStrategicMerge: + spec: + template: + spec: + containers: + - name: "vault" + env: + - name: VAULT_CACERT + value: "/tmp/local/share/ca-certificates/tls.crt" + - name: SSL_CERT_FILE + value: "/tmp/local/share/ca-certificates/tls.crt" + volumeMounts: + - name: custom-ca-certificates + mountPath: /tmp/local/share/ca-certificates + readOnly: true + volumes: + - name: custom-ca-certificates + projected: + defaultMode: 292 + sources: + - secret: + name: exposed-ca diff --git a/roles/kyverno/templates/prometheusrule.yml.j2 b/roles/kyverno/templates/prometheusrule.yml.j2 new file mode 100644 index 00000000..37cfc7be --- /dev/null +++ b/roles/kyverno/templates/prometheusrule.yml.j2 @@ -0,0 +1,70 @@ +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + labels: + app.kubernetes.io/name: gitlab + name: kyverno + namespace: {{ dsc.kyverno.namespace }} +spec: + groups: + - name: Kyverno + rules: + - alert: Kyverno admission controler not available + annotations: + message: Kyverno admission controler in namespace {{ dsc.kyverno.namespace }} has not been available for the last 5 minutes. + summary: Kyverno admission controler down (no ready pod)" + expr: | + sum(kube_pod_status_ready{ + pod=~"kyverno-admission-controller-.*", + namespace="{{ dsc.kyverno.namespace }}", + condition="true"}) == 0 + for: 1m + labels: + severity: critical + - alert: Kyverno background controler not available + annotations: + message: Kyverno background controler in namespace {{ dsc.kyverno.namespace }} has not been available for the last 5 minutes. + summary: Kyverno background controler down (no ready pod)" + expr: | + sum(kube_pod_status_ready{ + pod=~"kyverno-background-controller-.*", + namespace="{{ dsc.kyverno.namespace }}", + condition="true"}) == 0 + for: 1m + labels: + severity: critical + - alert: Kyverno cleanup controller not available + annotations: + message: Kyverno cleanup controller in namespace {{ dsc.kyverno.namespace }} has not been available for the last 5 minutes. + summary: Kyverno cleanup controller down (no ready pod)" + expr: | + sum(kube_pod_status_ready{ + pod=~"kyverno-cleanup-controller-.*", + namespace="{{ dsc.kyverno.namespace }}", + condition="true"}) == 0 + for: 1m + labels: + severity: critical + - alert: Kyverno reports controller not available + annotations: + message: Kyverno reports controller in namespace {{ dsc.kyverno.namespace }} has not been available for the last 5 minutes. + summary: Kyverno reports controller down (no ready pod)" + expr: | + sum(kube_pod_status_ready{ + pod=~"kyverno-reports-controller-.*", + namespace="{{ dsc.kyverno.namespace }}", + condition="true"}) == 0 + for: 1m + labels: + severity: critical + - alert: Kyverno Pod not healthy + annotations: + message: Kyverno {{"{{"}} $labels.pod {{"}}"}} pod in namespace {{ dsc.kyverno.namespace }} has been unavailable for the last 5 minutes. + summary: Kyverno {{"{{"}} $labels.pod {{"}}"}} pod not healthy (container {{"{{"}} $labels.container {{"}}"}} is not ready) + expr: | + kube_pod_container_status_ready{ + pod!~"(.*-)*admission-reports(-.*)*", + namespace="{{ dsc.kyverno.namespace }}"} == 0 + for: 1m + labels: + severity: warning diff --git a/roles/logs/files/cluster-logging.yaml b/roles/logs/files/cluster-logging.yaml index ecf44b32..de9eaa45 100644 --- a/roles/logs/files/cluster-logging.yaml +++ b/roles/logs/files/cluster-logging.yaml @@ -1,13 +1,13 @@ apiVersion: "logging.openshift.io/v1" kind: "ClusterLogging" metadata: - name: "instance" + name: "instance" namespace: "openshift-logging" spec: - managementState: "Managed" + managementState: "Managed" logStore: - type: "elasticsearch" - retentionPolicy: + type: "elasticsearch" + retentionPolicy: application: maxAge: 1d infra: @@ -15,16 +15,16 @@ spec: audit: maxAge: 7d elasticsearch: - nodeCount: 3 + nodeCount: 3 storage: storageClassName: "ocs-storagecluster-ceph-rbd" size: 50G - resources: + resources: limits: memory: "4Gi" requests: memory: "4Gi" - proxy: + proxy: resources: limits: memory: 256Mi @@ -32,10 +32,10 @@ spec: memory: 256Mi redundancyPolicy: "SingleRedundancy" visualization: - type: "kibana" + type: "kibana" kibana: replicas: 1 collection: logs: - type: "fluentd" + type: "fluentd" fluentd: {} diff --git a/roles/logs/files/operator-subscription.yaml b/roles/logs/files/operator-subscription.yaml index d7091667..d98be745 100644 --- a/roles/logs/files/operator-subscription.yaml +++ b/roles/logs/files/operator-subscription.yaml @@ -52,5 +52,3 @@ spec: source: redhat-operators sourceNamespace: openshift-marketplace # startingCSV: elasticsearch-operator.5.5.4 - - diff --git a/roles/metrics/grafana/datasource.yaml b/roles/metrics/grafana/datasource.yaml index adfce340..e6e98074 100644 --- a/roles/metrics/grafana/datasource.yaml +++ b/roles/metrics/grafana/datasource.yaml @@ -7,7 +7,7 @@ spec: datasources: - access: proxy # jsonData: - # tlsSkipVerify: true + # tlsSkipVerify: true basicAuth: true basicAuthPassword: mysupersecretpasswd basicAuthUser: grafana-user diff --git a/roles/metrics/grafana/grafana-instance.yaml b/roles/metrics/grafana/grafana-instance.yaml index efc8eda3..4b119307 100644 --- a/roles/metrics/grafana/grafana-instance.yaml +++ b/roles/metrics/grafana/grafana-instance.yaml @@ -19,4 +19,3 @@ spec: ingress: enabled: true # previousServiceName: grafana-service - diff --git a/roles/nexus/tasks/main.yaml b/roles/nexus/tasks/main.yaml index bf67bfbe..b1d095f0 100644 --- a/roles/nexus/tasks/main.yaml +++ b/roles/nexus/tasks/main.yaml @@ -416,4 +416,9 @@ - name: Create nexus ServiceMonitor kubernetes.core.k8s: - template: servicemonitor.yml.j2 \ No newline at end of file + template: servicemonitor.yml.j2 + +- name: Set alerting rules + when: dsc.global.alerting.enabled + kubernetes.core.k8s: + template: prometheusrule.yml.j2 diff --git a/roles/nexus/templates/nexus.yml.j2 b/roles/nexus/templates/nexus.yml.j2 index 81d8fb32..36fd75ee 100644 --- a/roles/nexus/templates/nexus.yml.j2 +++ b/roles/nexus/templates/nexus.yml.j2 @@ -16,12 +16,16 @@ spec: labels: app: nexus spec: -{% if dsc.global.platform == "kubernetesVanilla" or dsc.global.platform == "rke2" %} +{% if dsc.global.platform == "kubernetes" %} securityContext: runAsNonRoot: true runAsGroup: 200 runAsUser: 200 fsGroup: 200 +{% endif %} +{% if use_image_pull_secrets %} + imagePullSecrets: + - name: dso-config-pull-secret {% endif %} containers: - name: nexus diff --git a/roles/nexus/templates/prometheusrule.yml.j2 b/roles/nexus/templates/prometheusrule.yml.j2 new file mode 100644 index 00000000..0d9c01c6 --- /dev/null +++ b/roles/nexus/templates/prometheusrule.yml.j2 @@ -0,0 +1,53 @@ +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + labels: + app: nexus + name: nexus + namespace: {{ dsc.nexus.namespace }} +spec: + groups: + - name: Nexus + rules: + - alert: Nexus instance not available + annotations: + message: Nexus instance in namespace {{ dsc.nexus.namespace }} has not been available for the last 5 minutes. + summary: Nexus instance down (no ready container)" + expr: | + (absent(kube_pod_container_status_ready{ + pod=~"nexus-.*", + container="nexus", + namespace="{{ dsc.nexus.namespace }}"}) == 1) + or sum(kube_pod_container_status_ready{ + pod=~"nexus-.*", + container="nexus", + namespace="{{ dsc.nexus.namespace }}"}) == 0 + for: 5m + labels: + severity: critical + - alert: Nexus PVC almost out of disk space + annotations: + message: PVC {{"{{"}} $labels.persistentvolumeclaim {{"}}"}} in namespace {{ dsc.nexus.namespace }} is almost full (< 10% left). VALUE = {{"{{"}} $value {{"}}"}}% + summary: Nexus PVC almost out of disk space in namespace {{ dsc.nexus.namespace }} + expr: | + round( + kubelet_volume_stats_available_bytes{ + persistentvolumeclaim=~"nexus-data-.*", + namespace="{{ dsc.nexus.namespace }}"} + / kubelet_volume_stats_capacity_bytes{ + persistentvolumeclaim=~"nexus-data-.*", + namespace="{{ dsc.nexus.namespace }}"} * 100, 0.01) < 10 > 0 + for: 1m + labels: + severity: warning + - alert: Nexus PVC out of disk space + annotations: + message: PVC {{"{{"}} $labels.persistentvolumeclaim {{"}}"}} in namespace {{ dsc.nexus.namespace }} is full (0% left). + summary: Nexus PVC out of disk space in namespace {{ dsc.nexus.namespace }} + expr: | + kubelet_volume_stats_available_bytes{ + persistentvolumeclaim=~"nexus-data-.*", + namespace="{{ dsc.nexus.namespace }}"} == 0 + for: 1m + labels: + severity: critical diff --git a/roles/prometheus/tasks/main.yaml b/roles/prometheus/tasks/main.yaml index c489fde9..7a53d39b 100644 --- a/roles/prometheus/tasks/main.yaml +++ b/roles/prometheus/tasks/main.yaml @@ -13,4 +13,4 @@ {{ prometheusoperator_crds.content | regex_replace('- =~', "- '=~'") | regex_replace('- =', "- '='") | - from_yaml_all }} \ No newline at end of file + from_yaml_all }} diff --git a/roles/socle-config/files/config.yaml b/roles/socle-config/files/config.yaml index a59705ab..4ccb0f8d 100644 --- a/roles/socle-config/files/config.yaml +++ b/roles/socle-config/files/config.yaml @@ -8,46 +8,83 @@ spec: argocd: namespace: dso-argocd subDomain: argocd + helmRepoUrl: https://argoproj.github.io/argo-helm + certmanager: + helmRepoUrl: https://charts.jetstack.io + forcedInstall: false cloudnativepg: namespace: dso-cloudnativepg + helmRepoUrl: https://cloudnative-pg.github.io/charts + forcedInstall: false console: namespace: dso-console subDomain: console - gitlabOperator: - namespace: dso-gitlab-operator + helmRepoUrl: https://cloud-pi-native.github.io/helm-charts + cnpg: + mode: primary + exposed: false gitlab: namespace: dso-gitlab subDomain: gitlab insecureCI: false pvcGitalySize: 50Gi + cnpg: + mode: primary + exposed: false gitlabCatalog: catalogRepoUrl: https://github.com/cloud-pi-native/gitlab-ci-catalog.git + gitlabCiPipelinesExporter: + helmRepoUrl: https://charts.visonneau.fr + gitlabOperator: + namespace: dso-gitlab-operator + helmRepoUrl: https://gitlab.com/api/v4/projects/18899486/packages/helm/stable + forcedInstall: false + gitlabRunner: + helmRepoUrl: https://charts.gitlab.io global: backup: velero: enabled: false cnpg: enabled: false + vault: + enabled: false + metrics: + enabled: false + alerting: + enabled: false grafana: namespace: dso-grafana subDomain: grafana grafanaPvcSize: 5Gi grafanaOperator: namespace: dso-grafana-operator + ociChartUrl: oci://ghcr.io/grafana/helm-charts/grafana-operator harbor: namespace: dso-harbor subDomain: harbor + helmRepoUrl: https://helm.goharbor.io pvcRegistrySize: 50Gi pvcJobLogSize: 5Gi pvcDatabaseSize: 10Gi pvcRedisSize: 5Gi pvcTrivySize: 10Gi + cnpg: + mode: primary + exposed: false keycloak: namespace: dso-keycloak subDomain: keycloak + helmRepoUrl: https://charts.bitnami.com/bitnami postgresPvcSize: 1Gi + pluginDownloadUrl: https://github.com/codegouvfr/keycloak-theme-dsfr/releases/download/v1.0.3 + cnpg: + mode: primary + exposed: false kyverno: namespace: dso-kyverno + helmRepoUrl: https://kyverno.github.io/kyverno + forcedInstall: false nexus: namespace: dso-nexus subDomain: nexus @@ -56,8 +93,13 @@ spec: sonarqube: namespace: dso-sonarqube subDomain: sonar + helmRepoUrl: https://sonarsource.github.io/helm-chart-sonarqube postgresPvcSize: 5Gi + cnpg: + mode: primary + exposed: false vault: namespace: dso-vault subDomain: vault + helmRepoUrl: https://helm.releases.hashicorp.com pvcSize: 23Gi diff --git a/roles/socle-config/files/cr-conf-dso-default.yaml b/roles/socle-config/files/cr-conf-dso-default.yaml index c22ab5ee..b85a1940 100644 --- a/roles/socle-config/files/cr-conf-dso-default.yaml +++ b/roles/socle-config/files/cr-conf-dso-default.yaml @@ -13,31 +13,56 @@ spec: enabled: false cloudnativepg: {} console: + cnpg: + mode: primary values: {} - gitlab: {} + gitlab: + cnpg: + mode: primary gitlabCiPipelinesExporter: {} gitlabOperator: {} - gitlabRunner: {} + gitlabRunner: + resources: + overwrite: + requests: + memory: "6Gi" + cpu: "2" + limits: + memory: "6Gi" + cpu: "2" global: + platform: openshift + offline: false environment: production projectsRootDir: - forge - rootDomain: - .example.com + rootDomain: .example.com metrics: enabled: false - backup: {} + alerting: + enabled: false + backup: + cnpg: + enabled: false + pathPrefix: cnpg + vault: + enabled: false + pathPrefix: vault grafana: {} grafanaDatasource: {} grafanaOperator: {} harbor: + cnpg: + mode: primary adminPassword: anotherGreatPassword pvcRegistrySize: 20Gi ingress: tls: type: none kubed: {} - keycloak: {} + keycloak: + cnpg: + mode: primary kyverno: {} nexus: storageSize: 25Gi @@ -47,5 +72,7 @@ spec: type: external proxy: enabled: false - sonarqube: {} + sonarqube: + cnpg: + mode: primary vault: {} diff --git a/roles/socle-config/files/crd-conf-dso.yaml b/roles/socle-config/files/crd-conf-dso.yaml index 88852cc5..9671ac1b 100644 --- a/roles/socle-config/files/crd-conf-dso.yaml +++ b/roles/socle-config/files/crd-conf-dso.yaml @@ -63,7 +63,7 @@ spec: name: description: The configmap name type: string - key: + key: description: The configmap key providing the Private CA cert type: string required: @@ -129,6 +129,9 @@ spec: subDomain: description: The subdomain for ArgoCD. type: string + helmRepoUrl: + description: ArgoCD Bitnami helm repository url. + type: string chartVersion: description: ArgoCD Bitnami helm chart version (e.g., "4.7.13"). type: string @@ -148,19 +151,39 @@ spec: certmanager: description: Configuration for Cert Manager. properties: + helmRepoUrl: + description: Cert-manager helm repository url. + type: string chartVersion: description: Cert-manager helm chart version (e.g., "v1.13.1"). type: string + forcedInstall: + description: | + Should we force Cert-manager installation in the desired namespace ? + Default is false, so it won't install (or reinstall) if it's already there. + Set to true for a forced installation. + default: false + type: boolean type: object cloudnativepg: description: Configuration for CloudNativePG. properties: namespace: - description: The namespace for cloudnativepg. + description: The namespace for CloudNativePG. + type: string + helmRepoUrl: + description: CloudNativePG helm repository url. type: string chartVersion: description: CloudNativePG helm chart version (e.g., "0.18.2"). type: string + forcedInstall: + description: | + Should we force CNPG Operator installation in the desired namespace ? + Default is false, so it won't install (or reinstall) if it's already there. + Set to true for a forced installation. + default: false + type: boolean type: object console: description: Configuration for the console. @@ -174,6 +197,9 @@ spec: subDomain: description: The subdomain for console. type: string + helmRepoUrl: + description: Console helm repository url. + type: string values: description: Extra helm values for console type: object @@ -183,10 +209,28 @@ spec: description: Size for postgres' pvc type: string default: 10Gi - consoleRepoUrl: - description: Console repository url. - default: https://cloud-pi-native.github.io/helm-charts - type: string + cnpg: + description: Configuration for cnpg clusters. + type: object + properties: + mode: + description: Determines whether cnpg clusters should be deployed with as a primary cluster (initb from scratch) or replica cluster (initdb from external source). + default: primary + type: string + enum: + - primary + - replica + - restore + exposed: + description: Whether or not the cnpg cluster shoul be exposed via NodePort. + type: boolean + default: false + nodePort: + description: NodePort used to expose the cnpg cluster instance. + type: string + connectionParameters: + description: Connection parameters used for replication, it should contains 'connectionParameters', 'sslKey', 'sslCert', 'sslRootCert' (see. https://cloudnative-pg.io/documentation/1.18/bootstrap/#bootstrap-from-a-live-cluster-pg_basebackup) + type: string type: object gitlab: description: Configuration for GitLab. @@ -245,10 +289,35 @@ spec: description: Size for postgres' pvc type: string default: 10Gi + cnpg: + description: Configuration for cnpg clusters. + type: object + properties: + mode: + description: Determines whether cnpg clusters should be deployed with as a primary cluster (initb from scratch) or replica cluster (initdb from external source). + default: primary + type: string + enum: + - primary + - replica + - restore + exposed: + description: Whether or not the cnpg cluster shoul be exposed via NodePort. + type: boolean + default: false + nodePort: + description: NodePort used to expose the cnpg cluster instance. + type: string + connectionParameters: + description: Connection parameters used for replication, it should contains 'connectionParameters', 'sslKey', 'sslCert', 'sslRootCert' (see. https://cloudnative-pg.io/documentation/1.18/bootstrap/#bootstrap-from-a-live-cluster-pg_basebackup) + type: string type: object gitlabCiPipelinesExporter: description: Configuration for GitLab CI Pipelines Exporter. properties: + helmRepoUrl: + description: GitLab CI Pipelines Exporter helm repository url. + type: string chartVersion: description: GitLab CI Pipelines Exporter chart version (e.g., "0.3.4"). type: string @@ -256,12 +325,22 @@ spec: gitlabOperator: description: Configuration for GitLab Operator. properties: + helmRepoUrl: + description: GitLab Operator helm repository url. + type: string chartVersion: description: GitLab Operator release version (e.g., "0.24.1"). type: string namespace: description: The namespace for GitLab Operator. type: string + forcedInstall: + description: | + Should we force GitLab Operator installation in the desired namespace ? + Default is false, so it won't install (or reinstall) if it's already there. + Set to true for a forced installation. + default: false + type: boolean type: object gitlabCatalog: description: Configuration for GitLab Catalog. @@ -274,9 +353,60 @@ spec: gitlabRunner: description: Configuration for GitLab Runner. properties: + helmRepoUrl: + description: GitLab Runner helm repository url. + type: string chartVersion: description: GitLab Runner chart version (e.g., "0.57.0"). type: string + resources: + description: Resources for GitLab Runner. + type: object + properties: + requests: + description: Resources requests for GitLab Runner. + type: object + properties: + cpu: + description: CPU request for GitLab Runner. + type: string + memory: + description: Memory request for GitLab Runner. + type: string + limits: + description: Resources limits for GitLab Runner. + type: object + properties: + cpu: + description: CPU limit for GitLab Runner. + type: string + memory: + description: Memory limit for GitLab Runner. + type: string + overwrite: + description: Resources overwrite for GitLab Runner. + type: object + properties: + requests: + description: Resources requests max overwrite for GitLab Runner. + type: object + properties: + cpu: + description: CPU request max overwrite for GitLab Runner. + type: string + memory: + description: Memory request max overwrite for GitLab Runner. + type: string + limits: + description: Resources limits max overwrite for GitLab Runner. + type: object + properties: + cpu: + description: CPU limit max overwrite for GitLab Runner. + type: string + memory: + description: Memory limit max overwrite for GitLab Runner. + type: string type: object global: description: Global configuration not specific to one service @@ -315,65 +445,110 @@ spec: required: - enabled type: object + alerting: + description: Configuration for alerting feature. + properties: + enabled: + default: false + description: Specifies whether alerting should be enabled. + type: boolean + required: + - enabled + type: object backup: description: Configuration for backup feature. properties: - velero: + s3: properties: - enabled: - description: Enable Velero backups. - default: false - type: boolean - type: object - cnpg: - properties: - enabled: - description: Enable s3 cnpg backups. - default: false - type: boolean endpointURL: - description: Defines the s3 endpoint for cnpg backups. + description: Defines the s3 endpoint for vault backups. type: string - endpointCA: - properties: - namespace: - description: Defines in which namespace is located the secret containing CA bundle for cnpg backups (it will be copy into each namespace that use cnpg). - type: string - name: - description: Defines the secret name containing s3 CA for cnpg backups. - type: string - key: - description: Defines the secret key containing s3 CA for cnpg backups. - type: string - type: object - destinationPath: - description: Defines the globally shared s3 destination path for cnpg backups (it should be set like `//` with the trailing slash). + bucketName: + description: Defines the globally shared s3 bucket name for backups. type: string default: "" - s3Credentials: + credentials: properties: name: - description: Defines the s3 kuebernetes secret name used for cnpg backups. + description: Defines the s3 kubernetes secret name used for vault backups. type: string accessKeyId: properties: key: - description: Defines the s3 accessKeyId kubernetes secret key used for cnpg backups. + description: Defines the s3 accessKeyId kubernetes secret key used for vault backups. type: string value: - description: Defines the s3 accessKeyId value used for cnpg backups. + description: Defines the s3 accessKeyId value used for vault backups. type: string type: object secretAccessKey: properties: key: - description: Defines the s3 secretAccessKey kubernetes secret key used for cnpg backups. + description: Defines the s3 secretAccessKey kubernetes secret key used for vault backups. type: string value: - description: Defines the s3 secretAccessKey value used for cnpg backups. + description: Defines the s3 secretAccessKey value used for vault backups. type: string type: object type: object + endpointCA: + properties: + namespace: + description: Defines in which namespace is located the secret containing CA bundle for cnpg backups (it will be copy into each namespace that use cnpg). + type: string + name: + description: Defines the secret name containing s3 CA for cnpg backups. + type: string + key: + description: Defines the secret key containing s3 CA for cnpg backups. + type: string + type: object + type: object + velero: + properties: + enabled: + description: Enable Velero backups. + default: false + type: boolean + type: object + vault: + properties: + enabled: + description: Enable s3 vault backups. + default: false + type: boolean + helmRepoUrl: + description: Vault backup-utils helm repository url. + type: string + chartVersion: + description: Vault backup-utils helm chart version (e.g., "1.12.2"). + type: string + pathPrefix: + description: Defines the globally shared s3 destination path for cnpg backups. + type: string + default: "vault" + mcExtraArgs: + description: Extra args to pass to minio cli for the backups. + type: string + cron: + description: Defines the cron rule used for vault backups. By default it runs every 6 hours. + type: string + default: "0 */6 * * *" + retentionPolicy: + description: Defines retention policy for vault backups recurrences. + type: string + default: "30d" + type: object + cnpg: + properties: + enabled: + description: Enable s3 cnpg backups. + default: false + type: boolean + pathPrefix: + description: Defines the globally shared s3 destination path for cnpg backups. + type: string + default: "cnpg" cron: description: Defines the cron rule used for cnpg backups. By default it runs every 6 hours. type: string @@ -386,26 +561,32 @@ spec: type: object platform: default: openshift - description: Cluster platform only openshift, kubernetesVanilla and rke2 - are supported (for now). + description: Cluster platform, either the Openshift family (Openshift, OKD), or the rest + (Kubernetes Vanilla, K3s, RKE2, EKS, GKE...). enum: - openshift - - kubernetesVanilla - - rke2 + - kubernetes type: string offline: default: false - description: Specifies whether the cluster have access to the + description: Specifies whether the cluster have access to the internet or not. type: boolean registry: description: Specifies the internal registry to use. type: string + imagePullSecretsData: + description: Specifies the credentials to use for pulling image, encoded in base64. + type: string + profile: + description: Specifies security profile (e.g. cis). + type: string required: - projectsRootDir - rootDomain - environment - metrics + - alerting - platform - offline type: object @@ -437,6 +618,9 @@ spec: grafanaOperator: description: Configuration for Grafana Operator. properties: + ociChartUrl: + description: Grafana Operator OCI chart url. + type: string chartVersion: description: Grafana Operator release version (e.g., "v5.6.0"). type: string @@ -456,6 +640,9 @@ spec: subDomain: description: The subdomain for Harbor. type: string + helmRepoUrl: + description: Harbor helm repository url. + type: string chartVersion: description: Harbor helm chart version (e.g., "1.12.2"). type: string @@ -488,7 +675,7 @@ spec: type: object properties: provider: - description: ID of the provider + description: ID of the provider type: string default: docker-hub endpointUrl: @@ -527,6 +714,28 @@ spec: description: Size for postgres' pvc type: string default: 10Gi + cnpg: + description: Configuration for cnpg clusters. + type: object + properties: + mode: + description: Determines whether cnpg clusters should be deployed with as a primary cluster (initb from scratch) or replica cluster (initdb from external source). + default: primary + type: string + enum: + - primary + - replica + - restore + exposed: + description: Whether or not the cnpg cluster shoul be exposed via NodePort. + type: boolean + default: false + nodePort: + description: NodePort used to expose the cnpg cluster instance. + type: string + connectionParameters: + description: Connection parameters used for replication, it should contains 'connectionParameters', 'sslKey', 'sslCert', 'sslRootCert' (see. https://cloudnative-pg.io/documentation/1.18/bootstrap/#bootstrap-from-a-live-cluster-pg_basebackup) + type: string required: - adminPassword - pvcRegistrySize @@ -628,13 +837,19 @@ spec: subDomain: description: The subdomain for Keycloak. type: string + helmRepoUrl: + description: Keycloak Bitnami helm repository url. + type: string chartVersion: - description: Keycloak chart version (e.g., "16.0.3"). + description: Keycloak Bitnami chart version (e.g., "16.0.3"). type: string postgresPvcSize: description: Size for postgres' pvc type: string default: 10Gi + pluginDownloadUrl: + description: Plugins download Url. + type: string values: description: | You can merge customs values for keycloak, they will be merged with roles/keycloak/templates/values.j2 @@ -643,6 +858,28 @@ spec: type: object default: {} x-kubernetes-preserve-unknown-fields: true + cnpg: + description: Configuration for cnpg clusters. + type: object + properties: + mode: + description: Determines whether cnpg clusters should be deployed with as a primary cluster (initb from scratch) or replica cluster (initdb from external source). + default: primary + type: string + enum: + - primary + - replica + - restore + exposed: + description: Whether or not the cnpg cluster shoul be exposed via NodePort. + type: boolean + default: false + nodePort: + description: NodePort used to expose the cnpg cluster instance. + type: string + connectionParameters: + description: Connection parameters used for replication, it should contains 'connectionParameters', 'sslKey', 'sslCert', 'sslRootCert' (see. https://cloudnative-pg.io/documentation/1.18/bootstrap/#bootstrap-from-a-live-cluster-pg_basebackup) + type: string type: object kyverno: description: Configuration for Kyverno. @@ -650,6 +887,16 @@ spec: namespace: description: The namespace for Kyverno. type: string + forcedInstall: + description: | + Should we force Kyverno installation in the desired namespace ? + Default is false, so it won't install (or reinstall) if it's already there. + Set to true for a forced installation. + default: false + type: boolean + helmRepoUrl: + description: Kyverno helm repository url. + type: string chartVersion: description: Kyverno helm chart version (e.g., "3.1.4"). type: string @@ -724,6 +971,9 @@ spec: subDomain: description: The subdomain for SonarQube. type: string + helmRepoUrl: + description: SonarQube helm repository url. + type: string chartVersion: description: SonarQube helm chart version (e.g., "10.2.1+800"). type: string @@ -734,7 +984,7 @@ spec: pluginDownloadUrl: description: Plugins download Url. type: string - PrometheusJavaagentVersion: + prometheusJavaagentVersion: description: Prometheus javaagent version. type: string values: @@ -744,6 +994,28 @@ spec: type: object default: {} x-kubernetes-preserve-unknown-fields: true + cnpg: + description: Configuration for cnpg clusters. + type: object + properties: + mode: + description: Determines whether cnpg clusters should be deployed with as a primary cluster (initb from scratch) or replica cluster (initdb from external source). + default: primary + type: string + enum: + - primary + - replica + - restore + exposed: + description: Whether or not the cnpg cluster shoul be exposed via NodePort. + type: boolean + default: false + nodePort: + description: NodePort used to expose the cnpg cluster instance. + type: string + connectionParameters: + description: Connection parameters used for replication, it should contains 'connectionParameters', 'sslKey', 'sslCert', 'sslRootCert' (see. https://cloudnative-pg.io/documentation/1.18/bootstrap/#bootstrap-from-a-live-cluster-pg_basebackup) + type: string type: object vault: description: Configuration for Vault. @@ -754,6 +1026,9 @@ spec: subDomain: description: The subdomain for Vault. type: string + helmRepoUrl: + description: Hashicorp Vault helm repository url. + type: string chartVersion: description: Hashicorp Vault helm chart version (e.g., "0.25.0"). type: string diff --git a/roles/socle-config/files/releases.yaml b/roles/socle-config/files/releases.yaml index f62e0ce0..08207b0b 100644 --- a/roles/socle-config/files/releases.yaml +++ b/roles/socle-config/files/releases.yaml @@ -4,8 +4,8 @@ metadata: name: conf-dso spec: argocd: - # https://artifacthub.io/packages/helm/bitnami/argo-cd - chartVersion: 6.0.10 + # https://artifacthub.io/packages/helm/argo/argo-cd + chartVersion: 7.3.11 certmanager: # https://github.com/cert-manager/cert-manager/releases chartVersion: v1.14.3 @@ -17,22 +17,22 @@ spec: release: "1.*.*" gitlab: # https://artifacthub.io/packages/helm/gitlab/gitlab - chartVersion: "7.9.2" + chartVersion: "8.2.1" gitlabCiPipelinesExporter: # https://github.com/mvisonneau/helm-charts/tree/main/charts/gitlab-ci-pipelines-exporter chartVersion: "0.3.4" gitlabOperator: # https://gitlab.com/gitlab-org/cloud-native/gitlab-operator/-/tags - chartVersion: "0.29.2" + chartVersion: "1.2.1" gitlabRunner: # https://gitlab.com/gitlab-org/charts/gitlab-runner/-/tags - chartVersion: "0.62.0" + chartVersion: "0.67.1" grafana: # https://github.com/grafana/grafana/tags - imageVersion: "9.5.5" + imageVersion: "10.4.3" grafanaOperator: # https://github.com/grafana/grafana-operator/tags - chartVersion: "v5.4.2" + chartVersion: "v5.10.0" harbor: # https://artifacthub.io/packages/helm/harbor/harbor chartVersion: 1.14.1 @@ -47,7 +47,7 @@ spec: imageTag: 3.68.1 sonarqube: # https://artifacthub.io/packages/helm/sonarqube/sonarqube - chartVersion: 10.4.1+2389 + chartVersion: 10.6.1+3163 vault: # https://artifacthub.io/packages/helm/hashicorp/vault chartVersion: 0.25.0 diff --git a/roles/socle-config/tasks/main.yaml b/roles/socle-config/tasks/main.yaml index b5bc8dde..eca1348d 100644 --- a/roles/socle-config/tasks/main.yaml +++ b/roles/socle-config/tasks/main.yaml @@ -112,6 +112,10 @@ ansible.builtin.set_fact: use_private_registry: "{{ dsc.global.registry is defined and dsc.global.registry | length > 0 | bool }}" +- name: use imagePullSecrets + ansible.builtin.set_fact: + use_image_pull_secrets: "{{ dsc.global.imagePullSecretsData is defined and dsc.global.imagePullSecretsData | length > 0 | bool }}" + - name: Set root_domain fact ansible.builtin.set_fact: root_domain: "{{ dsc.global.rootDomain }}" diff --git a/roles/sonarqube/tasks/main.yaml b/roles/sonarqube/tasks/main.yaml index 0bc6434a..81fa8541 100644 --- a/roles/sonarqube/tasks/main.yaml +++ b/roles/sonarqube/tasks/main.yaml @@ -6,20 +6,20 @@ - name: CNPG s3 CA (secret) when: > - dsc.global.backup.cnpg.enabled and + dsc.global.backup.cnpg.enabled and dsc.global.backup.cnpg.endpointCA.namespace is defined and dsc.global.backup.cnpg.endpointCA.name is defined and dsc.global.backup.cnpg.endpointCA.key is defined block: - name: Get secret kubernetes.core.k8s_info: - name: "{{ dsc.global.backup.cnpg.endpointCA.name }}" - namespace: "{{ dsc.global.backup.cnpg.endpointCA.namespace }}" + name: "{{ dsc.global.backup.endpointCa.name }}" + namespace: "{{ dsc.global.backup.endpointCa.namespace }}" kind: Secret register: cnpg_s3_ca_resource - name: Extract key - ansible.builtin.set_fact: + ansible.builtin.set_fact: cnpg_s3_ca_pem: "{{ cnpg_s3_ca_resource.resources[0].data[dsc.global.backup.cnpg.endpointCA.key] }}" - name: Set cnpg bundle-ca secret @@ -34,14 +34,14 @@ - name: Set cnpg backup secret kubernetes.core.k8s: - name: "{{ dsc.global.backup.cnpg.s3Credentials.name }}" + name: "{{ dsc.global.backup.s3Credentials.name }}" namespace: "{{ dsc.sonarqube.namespace }}" kind: Secret api_version: v1 definition: data: - accessKeyId: "{{ dsc.global.backup.cnpg.s3Credentials.accessKeyId.value | b64encode }}" - secretAccessKey: "{{ dsc.global.backup.cnpg.s3Credentials.secretAccessKey.value | b64encode }}" + accessKeyId: "{{ dsc.global.backup.s3Credentials.accessKeyId.value | b64encode }}" + secretAccessKey: "{{ dsc.global.backup.s3Credentials.secretAccessKey.value | b64encode }}" when: dsc.global.backup.cnpg.enabled - name: Remove cnpg scheduled backup @@ -55,7 +55,11 @@ - name: Create PostgreSQL cluster and sonar database kubernetes.core.k8s: - template: pg-cluster-sonar.yaml.j2 + template: "{{ item }}" + with_items: + - pg-cluster-sonar.yaml.j2 + - pg-cluster-sonar-backup.yaml.j2 + - pg-cluster-sonar-nodeport.yaml.j2 - name: Wait pg-cluster-sonar-rw endpoint kubernetes.core.k8s_info: @@ -81,7 +85,8 @@ - name: Add SonarQube helm repo kubernetes.core.helm_repository: name: sonarqube - repo_url: https://SonarSource.github.io/helm-chart-sonarqube + repo_url: "{{ dsc.sonarqube.helmRepoUrl }}" + force_update: true - name: Get admin password secret kubernetes.core.k8s_info: @@ -154,6 +159,31 @@ combine_user_values: "{{ dsc.sonarqube['values'] }}" combine_dest_var: "sonar_values" +- name: Check SonarQube helm release + kubernetes.core.helm_info: + name: sonarqube + namespace: "{{ dsc.sonarqube.namespace }}" + register: sonar_helm_release + +- name: Set upgrading_chart fact + when: sonar_helm_release.status is defined + block: + - name: Retrieve installed SonarQube chart version + ansible.builtin.set_fact: + sonar_installed_chart_version: "{{ sonar_helm_release.status.chart | regex_replace('sonarqube-', '') }}" + + - name: Initialize upgrading_chart fact + ansible.builtin.set_fact: + upgrading_chart: false + + - name: Manage upgrading_chart fact + when: sonar_installed_chart_version is defined + block: + - name: Update upgrading_chart fact + when: dsc.sonarqube.chartVersion is version(sonar_installed_chart_version, operator='gt', version_type='loose') + ansible.builtin.set_fact: + upgrading_chart: true + - name: Deploy helm kubernetes.core.helm: name: sonarqube @@ -162,6 +192,59 @@ release_namespace: "{{ dsc.sonarqube.namespace }}" create_namespace: true values: "{{ sonar_values }}" + ignore_errors: true + register: helm_install + +- name: Manage SonarQube upgrade + when: > + helm_install is failed and + upgrading_chart is defined and + upgrading_chart + block: + - name: Get Sonarqube admin password secret + kubernetes.core.k8s_info: + namespace: "{{ dsc.sonarqube.namespace }}" + kind: Secret + name: "sonarqube" + register: sonarqube_pwd + + - name: Get SonarQube migration status + ansible.builtin.uri: + validate_certs: "{{ dsc.exposedCA.type == 'none' }}" + url: https://{{ sonar_domain }}/api/v2/system/migrations-status + user: "admin" + password: "{{ sonarqube_pwd.resources[0].data.password | b64decode }}" + force_basic_auth: true + method: GET + return_content: true + status_code: 200 + register: sonar_migration_status + + - name: Trigger DB migration + when: "'Database migration is required' in sonar_migration_status.json.message" + ansible.builtin.uri: + validate_certs: "{{ dsc.exposedCA.type == 'none' }}" + url: https://{{ sonar_domain }}/api/system/migrate_db + user: "admin" + password: "{{ sonarqube_pwd.resources[0].data.password | b64decode }}" + force_basic_auth: true + method: POST + status_code: [200, 204] + + - name: Wait SonarQube status to be UP + ansible.builtin.uri: + validate_certs: "{{ dsc.exposedCA.type == 'none' }}" + url: https://{{ sonar_domain }}/api/system/status + user: "admin" + password: "{{ sonarqube_pwd.resources[0].data.password | b64decode }}" + force_basic_auth: true + method: GET + return_content: true + status_code: 200 + register: sonar_check + until: sonar_check.json.status == "UP" + retries: 60 + delay: 5 - name: Wait sonarqube endpoint to initialize kubernetes.core.k8s_info: @@ -243,3 +326,8 @@ - name: Create PodMonitor kubernetes.core.k8s: template: podmonitor.yml.j2 + +- name: Set alerting rules + when: dsc.global.alerting.enabled + kubernetes.core.k8s: + template: prometheusrule.yml.j2 diff --git a/roles/sonarqube/tasks/reset-admin-password.yaml b/roles/sonarqube/tasks/reset-admin-password.yaml index 86cf8d60..7f6acce0 100644 --- a/roles/sonarqube/tasks/reset-admin-password.yaml +++ b/roles/sonarqube/tasks/reset-admin-password.yaml @@ -18,7 +18,7 @@ password: "{{ sonarqube_pwd.resources[0].data.password | b64decode }}" force_basic_auth: true method: post - status_code: [200,204,404] + status_code: [200, 204, 404] register: current_tokens - name: Generate admin token @@ -29,7 +29,7 @@ password: "{{ sonarqube_pwd.resources[0].data.password | b64decode }}" force_basic_auth: true method: post - status_code: [200,204] + status_code: [200, 204] register: token_pass - name: Update inventory diff --git a/roles/sonarqube/templates/pg-cluster-sonar-backup.yaml.j2 b/roles/sonarqube/templates/pg-cluster-sonar-backup.yaml.j2 new file mode 100644 index 00000000..3925c485 --- /dev/null +++ b/roles/sonarqube/templates/pg-cluster-sonar-backup.yaml.j2 @@ -0,0 +1,13 @@ +--- +{% if dsc.global.backup.cnpg.enabled %} +apiVersion: postgresql.cnpg.io/v1 +kind: ScheduledBackup +metadata: + name: pg-cluster-sonar + namespace: {{ dsc.sonarqube.namespace }} +spec: + schedule: "{{ dsc.global.backup.cnpg.cron }}" + backupOwnerReference: self + cluster: + name: pg-cluster-sonar +{% endif %} diff --git a/roles/sonarqube/templates/pg-cluster-sonar-nodeport.yaml.j2 b/roles/sonarqube/templates/pg-cluster-sonar-nodeport.yaml.j2 new file mode 100644 index 00000000..8de8619b --- /dev/null +++ b/roles/sonarqube/templates/pg-cluster-sonar-nodeport.yaml.j2 @@ -0,0 +1,20 @@ +--- +{% if dsc.sonarqube.cnpg.exposed %} +apiVersion: v1 +kind: Service +metadata: + labels: + cnpg.io/cluster: pg-cluster-sonar + name: pg-cluster-sonar-rw-nodeport + namespace: {{ dsc.sonarqube.namespace }} +spec: + ports: + - name: postgres + port: 5432 + protocol: TCP + nodePort: {{ dsc.sonarqube.cnpg.nodePort }} + selector: + cnpg.io/cluster: pg-cluster-sonar + role: primary + type: NodePort +{% endif %} diff --git a/roles/sonarqube/templates/pg-cluster-sonar.yaml.j2 b/roles/sonarqube/templates/pg-cluster-sonar.yaml.j2 index b3d31e4c..511f9f8b 100644 --- a/roles/sonarqube/templates/pg-cluster-sonar.yaml.j2 +++ b/roles/sonarqube/templates/pg-cluster-sonar.yaml.j2 @@ -1,3 +1,4 @@ +--- apiVersion: postgresql.cnpg.io/v1 kind: Cluster metadata: @@ -12,72 +13,100 @@ metadata: {% endif %} spec: instances: 3 - # Parameters and pg_hba configuration will be append # to the default ones to make the cluster work {% if use_private_registry %} imageName: "{{ dsc.global.registry }}/cloudnative-pg/postgresql:16.1" {% endif %} - postgresql: -{% if use_private_registry %} - image: "{{ dsc.global.registry }}/cloudnative-pg/postgresql:16.1" +{% if use_image_pull_secrets %} + imagePullSecrets: + - name: dso-config-pull-secret {% endif %} + postgresql: parameters: max_worker_processes: "60" +{% if dsc.sonarqube.cnpg.mode == "primary" %} pg_hba: # To access through TCP/IP you will need to get username # and password from the secret pg-cluster-sonar-app - host sonardb dso_admin all md5 - + - host sonardb streaming_replica all md5 +{% endif %} bootstrap: +{% if dsc.sonarqube.cnpg.mode == "primary" %} initdb: database: sonardb owner: dso_admin + recovery: null +{% elif dsc.sonarqube.cnpg.mode == "replica" or dsc.sonarqube.cnpg.mode == "restore" %} + recovery: + source: pg-cluster-sonar + database: sonardb + owner: dso_admin + initdb: null + externalClusters: + - name: pg-cluster-sonar +{% if dsc.sonarqube.cnpg.mode == "restore" %} + barmanObjectStore: + destinationPath: "s3://{{ dsc.global.backup.s3.bucketName }}/{{ dsc.global.backup.cnpg.pathPrefix }}" + endpointURL: "{{ dsc.global.backup.s3.endpointUrl }}" +{% if dsc.exposedCA.type != 'none' %} + endpointCA: + name: "bundle-cnpg-s3" + key: "ca.pem" +{% endif %} + s3Credentials: + accessKeyId: + name: "{{ dsc.global.backup.s3.credentials.name }}" + key: "{{ dsc.global.backup.s3.credentials.accessKeyId.key }}" + secretAccessKey: + name: "{{ dsc.global.backup.s3.credentials.name }}" + key: "{{ dsc.global.backup.s3.credentials.secretAccessKey.key }}" +{% endif %} +{% if dsc.sonarqube.cnpg.mode == "replica" %} +{%- filter indent(width=4) %} +{{ dsc.sonarqube.cnpg.connectionParameters }} +{%- endfilter %} +{% endif %} +{% endif %} - enableSuperuserAccess: true +{% if dsc.sonarqube.cnpg.mode == "replica" %} + replica: + enabled: true + source: pg-cluster-sonar +{% endif %} + enableSuperuserAccess: true # Example of rolling update strategy: # - unsupervised: automated update of the primary once all # replicas have been upgraded (default) # - supervised: requires manual supervision to perform # the switchover of the primary primaryUpdateStrategy: unsupervised - # Require 1Gi of space per instance using default storage class storage: size: {{ dsc.sonarqube.postgresPvcSize }} - monitoring: enablePodMonitor: {{ dsc.global.metrics.enabled }} {% if dsc.global.backup.cnpg.enabled %} backup: barmanObjectStore: - destinationPath: "s3://{{ dsc.global.backup.cnpg.destinationPath }}sonar" - endpointURL: "{{ dsc.global.backup.cnpg.endpointURL }}" + destinationPath: "s3://{{ dsc.global.backup.s3.bucketName }}/{{ dsc.global.backup.cnpg.pathPrefix }}" + endpointURL: "{{ dsc.global.backup.s3.endpointUrl }}" +{% if dsc.exposedCA.type != 'none' %} endpointCA: name: "bundle-cnpg-s3" key: "ca.pem" +{% endif %} s3Credentials: accessKeyId: - name: "{{ dsc.global.backup.cnpg.s3Credentials.name }}" - key: "{{ dsc.global.backup.cnpg.s3Credentials.accessKeyId.key }}" + name: "{{ dsc.global.backup.s3.credentials.name }}" + key: "{{ dsc.global.backup.s3.credentials.accessKeyId.key }}" secretAccessKey: - name: "{{ dsc.global.backup.cnpg.s3Credentials.name }}" - key: "{{ dsc.global.backup.cnpg.s3Credentials.secretAccessKey.key }}" + name: "{{ dsc.global.backup.s3.credentials.name }}" + key: "{{ dsc.global.backup.s3.credentials.secretAccessKey.key }}" retentionPolicy: "{{ dsc.global.backup.cnpg.retentionPolicy }}" - ---- -apiVersion: postgresql.cnpg.io/v1 -kind: ScheduledBackup -metadata: - name: pg-cluster-sonar - namespace: {{ dsc.sonarqube.namespace }} -spec: - schedule: "{{ dsc.global.backup.cnpg.cron }}" - backupOwnerReference: self - cluster: - name: pg-cluster-sonar {% else %} backup: null {% endif %} diff --git a/roles/sonarqube/templates/prometheusrule.yml.j2 b/roles/sonarqube/templates/prometheusrule.yml.j2 new file mode 100644 index 00000000..a027d41b --- /dev/null +++ b/roles/sonarqube/templates/prometheusrule.yml.j2 @@ -0,0 +1,78 @@ +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + labels: + app: sonarqube + name: sonarqube + namespace: {{ dsc.sonarqube.namespace }} +spec: + groups: + - name: SonarQube + rules: + - alert: SonarQube instance not available + annotations: + message: SonarQube instance in namespace {{ dsc.sonarqube.namespace }} has not been available for the last 5 minutes. + summary: SonarQube instance down (no ready container)" + expr: | + (absent(kube_pod_container_status_ready{ + pod=~"sonarqube-.*", + container="sonarqube", + namespace="{{ dsc.sonarqube.namespace }}"}) == 1) + or sum(kube_pod_container_status_ready{ + pod=~"sonarqube-.*", + container="sonarqube", + namespace="{{ dsc.sonarqube.namespace }}"}) == 0 + for: 5m + labels: + severity: critical + - alert: SonarQube DB not available + annotations: + message: All SonarQube CNPG pods in namespace {{ dsc.sonarqube.namespace }} have been unavailable for the last 5 minutes. + summary: SonarQube database down (containers not ready) + expr: | + (absent(kube_pod_container_status_ready{ + pod=~"pg-cluster-sonar-\\d+", + container="postgres", namespace="{{ dsc.sonarqube.namespace }}"}) == 1) + or sum(kube_pod_container_status_ready{ + pod=~"pg-cluster-sonar-\\d+", + container="postgres", namespace="{{ dsc.sonarqube.namespace }}"}) == 0 + for: 5m + labels: + severity: critical + - alert: Sonarqube DB Pod not healthy + annotations: + message: SonarQube {{"{{"}} $labels.pod {{"}}"}} pod in namespace {{ dsc.sonarqube.namespace }} has been unavailable for the last 5 minutes. + summary: SonarQube database pod not healthy (container is not ready) + expr: | + kube_pod_container_status_ready{ + pod=~"pg-cluster-sonar-\\d+", + container="postgres", namespace="{{ dsc.sonarqube.namespace }}"} == 0 + for: 5m + labels: + severity: warning + - alert: SonarQube DB PVC almost out of disk space + annotations: + message: PVC {{"{{"}} $labels.persistentvolumeclaim {{"}}"}} in namespace {{ dsc.sonarqube.namespace }} is almost full (< 10% left). VALUE = {{"{{"}} $value {{"}}"}}% + summary: SonarQube CNPG PVC almost out of disk space in namespace {{ dsc.sonarqube.namespace }} + expr: | + round( + kubelet_volume_stats_available_bytes{ + persistentvolumeclaim=~"pg-cluster-sonar-\\d+", + namespace="{{ dsc.sonarqube.namespace }}"} + / kubelet_volume_stats_capacity_bytes{ + persistentvolumeclaim=~"pg-cluster-sonar-\\d+", + namespace="{{ dsc.sonarqube.namespace }}"} * 100, 0.01) < 10 > 0 + for: 1m + labels: + severity: warning + - alert: SonarQube DB PVC out of disk space + annotations: + message: PVC {{"{{"}} $labels.persistentvolumeclaim {{"}}"}} in namespace {{ dsc.sonarqube.namespace }} is full (0% left). + summary: SonarQube CNPG PVC out of disk space in namespace {{ dsc.sonarqube.namespace }} + expr: | + kubelet_volume_stats_available_bytes{ + persistentvolumeclaim=~"pg-cluster-sonar-\\d+", + namespace="{{ dsc.sonarqube.namespace }}"} == 0 + for: 1m + labels: + severity: critical diff --git a/roles/sonarqube/templates/values/00-main.j2 b/roles/sonarqube/templates/values/00-main.j2 index 602b40b7..d2a8d21c 100644 --- a/roles/sonarqube/templates/values/00-main.j2 +++ b/roles/sonarqube/templates/values/00-main.j2 @@ -22,7 +22,7 @@ ingress: labels: app: "sonar" -# Should be kept as false even if dsc.global.platform == "kubernetesVanilla" and it may be best to work with your cluster administrator to either provide specific nodes with the proper kernel settings, or ensure they are set cluster wide : sysctl -a "name=vm.max_map_count value=262144" +# Should be kept as false even if dsc.global.platform == "kubernetes" and it may be best to work with your cluster administrator to either provide specific nodes with the proper kernel settings, or ensure they are set cluster wide : sysctl -a "name=vm.max_map_count value=262144" initSysctl: enabled: false @@ -40,8 +40,8 @@ prometheusMonitoring: podMonitor: enabled: false -jvmOpts: "-javaagent:/opt/sonarqube/extensions/plugins/sonarqube-community-branch-plugin-1.19.0.jar=web" -jvmCeOpts: "-javaagent:/opt/sonarqube/extensions/plugins/sonarqube-community-branch-plugin-1.19.0.jar=ce" +jvmOpts: "-javaagent:/opt/sonarqube/extensions/plugins/sonarqube-community-branch-plugin-1.21.0.jar=web" +jvmCeOpts: "-javaagent:/opt/sonarqube/extensions/plugins/sonarqube-community-branch-plugin-1.21.0.jar=ce" ## a monitoring passcode needs to be defined in order to get reasonable probe results # not setting the monitoring passcode will result in a deployment that will never be ready diff --git a/roles/sonarqube/templates/values/10-offline.j2 b/roles/sonarqube/templates/values/10-offline.j2 index 0d75cf66..e195318d 100644 --- a/roles/sonarqube/templates/values/10-offline.j2 +++ b/roles/sonarqube/templates/values/10-offline.j2 @@ -1,13 +1,13 @@ {% if dsc.global.offline %} prometheusExporter: - version: {{ dsc.sonarqube.PrometheusJavaagentVersion }} + version: {{ dsc.sonarqube.prometheusJavaagentVersion }} noCheckCertificate: true - downloadURL: {{ dsc.sonarqube.pluginDownloadUrl }}/jmx_prometheus_javaagent-{{ dsc.sonarqube.PrometheusJavaagentVersion }}.jar + downloadURL: {{ dsc.sonarqube.pluginDownloadUrl }}/jmx_prometheus_javaagent-{{ dsc.sonarqube.prometheusJavaagentVersion }}.jar plugins: install: - {{ dsc.sonarqube.pluginDownloadUrl }}/sonar-auth-oidc-plugin-2.1.1.jar - - {{ dsc.sonarqube.pluginDownloadUrl }}/sonarqube-community-branch-plugin-1.19.0.jar + - {{ dsc.sonarqube.pluginDownloadUrl }}/sonarqube-community-branch-plugin-1.21.0.jar noCheckCertificate: true {% if use_private_registry %} @@ -18,5 +18,5 @@ curlContainerImage: "{{ dsc.global.registry }}/curlimages/curl:8.2.1" plugins: install: - https://github.com/vaulttec/sonar-auth-oidc/releases/download/v2.1.1/sonar-auth-oidc-plugin-2.1.1.jar - - https://github.com/mc1arke/sonarqube-community-branch-plugin/releases/download/1.19.0/sonarqube-community-branch-plugin-1.19.0.jar + - https://github.com/mc1arke/sonarqube-community-branch-plugin/releases/download/1.21.0/sonarqube-community-branch-plugin-1.21.0.jar {% endif %} diff --git a/roles/sonarqube/templates/values/10-platform.j2 b/roles/sonarqube/templates/values/10-platform.j2 index b59c72c8..93e3b9c5 100644 --- a/roles/sonarqube/templates/values/10-platform.j2 +++ b/roles/sonarqube/templates/values/10-platform.j2 @@ -22,7 +22,7 @@ account: securityContext: {} {% endif %} -{% if dsc.global.platform == "kubernetesVanilla" %} +{% if dsc.global.platform == "kubernetes" %} account: securityContext: runAsUser: 101 diff --git a/roles/sonarqube/templates/values/10-registry.j2 b/roles/sonarqube/templates/values/10-registry.j2 index aba74be0..74d45df9 100644 --- a/roles/sonarqube/templates/values/10-registry.j2 +++ b/roles/sonarqube/templates/values/10-registry.j2 @@ -2,3 +2,9 @@ image: repository: "{{ dsc.global.registry }}/sonarqube" {% endif %} + +{% if use_image_pull_secrets %} +image: + pullSecrets: + - name: dso-config-pull-secret +{% endif %} \ No newline at end of file diff --git a/roles/vault/tasks/check.yml b/roles/vault/tasks/check.yml index cbbc6bbf..f19d5f2e 100644 --- a/roles/vault/tasks/check.yml +++ b/roles/vault/tasks/check.yml @@ -38,4 +38,3 @@ when: (vault_initialized) and (not vault_sealed) ansible.builtin.set_fact: vault_status: "OK" - diff --git a/roles/vault/tasks/main.yml b/roles/vault/tasks/main.yml index 3868f69a..fdf6c3d7 100644 --- a/roles/vault/tasks/main.yml +++ b/roles/vault/tasks/main.yml @@ -9,7 +9,8 @@ - name: Add helm repo kubernetes.core.helm_repository: name: hashicorp - repo_url: https://helm.releases.hashicorp.com + repo_url: "{{ dsc.vault.helmRepoUrl }}" + force_update: true - name: Set path fact ansible.builtin.set_fact: @@ -23,6 +24,16 @@ combine_user_values: "{{ dsc.vault['values'] }}" combine_dest_var: "vault_values" +- name: Create exposed_ca Secret + kubernetes.core.k8s: + kind: Secret + namespace: "{{ dsc.vault.namespace }}" + name: exposed-ca + definition: + data: + tls.crt: "{{ (dsc.exposedCA.type == 'configmap') | ansible.builtin.ternary(exposed_ca_pem | b64encode, exposed_ca_pem) }}" + when: dsc.exposedCA.type == "configmap" or dsc.exposedCA.type == "secret" + - name: Deploy helm kubernetes.core.helm: name: "{{ dsc_name }}-vault" @@ -36,8 +47,40 @@ kubernetes.core.k8s: template: "{{ item }}" with_items: + - role.yaml.j2 - ingress.yaml.j2 # Post install - name: Post install ansible.builtin.include_tasks: post-install.yml + +- name: Add backup utils Helm repo and deploy + when: dsc.global.backup.vault.enabled + block: + - name: Add Helm repo + kubernetes.core.helm_repository: + name: dso + repo_url: "{{ dsc.global.backup.vault.helmRepoUrl }}" + force_update: true + + - name: Deploy Helm chart + kubernetes.core.helm: + name: "{{ dsc_name }}-vault-backup" + chart_ref: dso/cpn-backup-utils + chart_version: "{{ dsc.global.backup.vault.chartVersion }}" + release_namespace: "{{ dsc.vault.namespace }}" + values: + vault: + enabled: true + secrets: + S3_BUCKET_NAME: "{{ dsc.global.backup.s3.bucketName }}" + S3_BUCKET_PREFIX: "{{ dsc.global.backup.vault.pathPrefix }}" + S3_ENDPOINT: "{{ dsc.global.backup.s3.endpointURL }}" + VAULT_ADDR: "{{ vault_domain }}" + VAULT_TOKEN: "{{ vault_token }}" + S3_ACCESS_KEY: "{{ dsc.global.backup.s3.credentials.accessKeyId.value | b64encode }}" + S3_SECRET_KEY: "{{ dsc.global.backup.s3.credentials.secretAccessKey.value | b64encode }}" + RETENTION: "{{ dsc.global.backup.vault.retentionPolicy | b64encode }}" + job: + schedule: "{{ dsc.global.backup.vault.cron }}" + state: "{{ dsc.global.backup.vault.enabled | ternary('present', 'absent') }}" diff --git a/roles/vault/tasks/post-install.yml b/roles/vault/tasks/post-install.yml index bb62a2ee..bf196531 100644 --- a/roles/vault/tasks/post-install.yml +++ b/roles/vault/tasks/post-install.yml @@ -277,8 +277,12 @@ token_explicit_max_ttl: 60 bound_claims_type: glob user_claim: user_email - bound_audiences: + bound_audiences: - https://{{ vault_domain }} + bound_claims: + iss: + - "https://{{ gitlab_domain }}" + - "{{ gitlab_domain }}" claim_mappings: namespace_path: namespace_path project_path: project_path @@ -473,6 +477,30 @@ "canonical_id": "{{ user_group.json.data.id }}" body_format: json +# AppRole +- name: Get auth methods + ansible.builtin.uri: + validate_certs: "{{ dsc.exposedCA.type == 'none' }}" + url: "https://{{ vault_domain }}/v1/sys/auth/approle" + method: GET + status_code: [200, 400] + headers: + "X-Vault-Token": "{{ vault_token }}" + register: get_auth_method + +- name: Enable approle auth method + when: get_auth_method.status == 400 + ansible.builtin.uri: + validate_certs: "{{ dsc.exposedCA.type == 'none' }}" + url: "https://{{ vault_domain }}/v1/sys/auth/approle" + method: POST + status_code: [200, 204] + headers: + "X-Vault-Token": "{{ vault_token }}" + body: + "type": "approle" + body_format: json + # Service monitor - name: Patch ServiceMonitor when: dsc.global.metrics.enabled diff --git a/roles/vault/templates/ingress.yaml.j2 b/roles/vault/templates/ingress.yaml.j2 index 431989f8..4a7d0e7f 100644 --- a/roles/vault/templates/ingress.yaml.j2 +++ b/roles/vault/templates/ingress.yaml.j2 @@ -32,6 +32,6 @@ spec: pathType: Prefix backend: service: - name: {{ dsc_name }}-vault + name: {{ dsc_name }}-vault-active port: number: 8200 diff --git a/roles/vault/templates/role.yaml.j2 b/roles/vault/templates/role.yaml.j2 new file mode 100644 index 00000000..5140c376 --- /dev/null +++ b/roles/vault/templates/role.yaml.j2 @@ -0,0 +1,9 @@ +kind: Role +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: "{{ dsc_name }}-vault" + namespace: {{ dsc.vault.namespace }} +rules: +- apiGroups: [""] + resources: ["pods"] + verbs: ["get", "update", "patch"] diff --git a/roles/vault/templates/values/00-main.j2 b/roles/vault/templates/values/00-main.j2 index 6e1221b4..91bc6530 100644 --- a/roles/vault/templates/values/00-main.j2 +++ b/roles/vault/templates/values/00-main.j2 @@ -1,5 +1,5 @@ -global: {% if dsc.global.metrics.enabled %} +global: serverTelemetry: prometheusOperator: true {% endif %} @@ -24,6 +24,7 @@ server: {% if dsc.global.metrics.enabled %} config: | ui = true + service_registration "kubernetes" {} listener "tcp" { tls_disable = 1 address = "[::]:8200" @@ -79,3 +80,98 @@ serverTelemetry: serviceMonitor: enabled: true {% endif %} +{% if dsc.global.alerting.enabled %} +serverTelemetry: + prometheusRules: + enabled: true + rules: +{% if dsc.global.metrics.enabled %} + - alert: Vault is sealed + annotations: + message: Vault instance in namespace {{ dsc.vault.namespace }} is sealed. + summary: Vault instance sealed + expr: | + max(1 + vault_core_unsealed{namespace="{{ dsc.vault.namespace }}"}) == 1 + for: 5m + labels: + severity: critical +{% endif %} + - alert: Vault instance not healthy + annotations: + message: Vault {{"{{"}} $labels.pod {{"}}"}} pod in namespace {{ dsc.vault.namespace }} is not healthy (sealed?). Check its logs. + summary: Vault instance is not healthy (sealed?) + expr: | + up{job="{{ dsc_name }}-vault-internal",pod=~"(.*-)*vault(-.*)*"} == 0 + for: 5m + labels: + severity: warning + - alert: Vault is not available + annotations: + message: Vault in namespace {{ dsc.vault.namespace }} has not been available for the last 5 minutes. + summary: Vault is down (no ready container) + expr: | + (absent(kube_pod_container_status_ready{ + pod=~"(.*-)*vault(-.*)*", + container="vault", + namespace="{{ dsc.vault.namespace }}"}) == 1) + or sum(kube_pod_container_status_ready{ + pod=~"(.*-)*vault(-.*)*", + container="vault", + namespace="{{ dsc.vault.namespace }}"}) == 0 + for: 5m + labels: + severity: critical + - alert: Vault agent injector is not available + annotations: + message: Vault agent injector in namespace {{ dsc.vault.namespace }} has not been available for the last 5 minutes. + summary: Vault agent injector is down (no ready container) + expr: | + (absent(kube_pod_container_status_ready{ + pod=~"(.*-)*vault(-.*)*", + container="sidecar-injector", + namespace="{{ dsc.vault.namespace }}"}) == 1) + or sum(kube_pod_container_status_ready{ + pod=~"(.*-)*vault(-.*)*", + container="sidecar-injector", + namespace="{{ dsc.vault.namespace }}"}) == 0 + for: 5m + labels: + severity: critical + - alert: Vault Pod not healthy + annotations: + message: Vault {{"{{"}} $labels.pod {{"}}"}} pod in namespace {{ dsc.vault.namespace }} has been unavailable for the last 5 minutes. + summary: Vault pod not healthy (container is not ready) + expr: | + kube_pod_container_status_ready{ + pod!~"backup-utils-vault(-.*)*", + namespace="{{ dsc.vault.namespace }}"} == 0 + for: 5m + labels: + severity: warning + - alert: Vault PVC almost out of disk space + annotations: + message: PVC {{"{{"}} $labels.persistentvolumeclaim {{"}}"}} in namespace {{ dsc.vault.namespace }} is almost full (< 10% left). VALUE = {{"{{"}} $value {{"}}"}}% + summary: Vault PVC almost out of disk space in namespace {{ dsc.vault.namespace }} + expr: | + round( + kubelet_volume_stats_available_bytes{ + persistentvolumeclaim=~"(.*-)*vault(-.*)*", + namespace="{{ dsc.vault.namespace }}"} + / kubelet_volume_stats_capacity_bytes{ + persistentvolumeclaim=~"(.*-)*vault(-.*)*", + namespace="{{ dsc.vault.namespace }}"} * 100, 0.01) < 10 > 0 + for: 1m + labels: + severity: warning + - alert: Vault PVC out of disk space + annotations: + message: PVC {{"{{"}} $labels.persistentvolumeclaim {{"}}"}} in namespace {{ dsc.vault.namespace }} is full (0% left). + summary: Vault PVC out of disk space in namespace {{ dsc.vault.namespace }} + expr: | + kubelet_volume_stats_available_bytes{ + persistentvolumeclaim=~"(.*-)*vault(-.*)*", + namespace="{{ dsc.vault.namespace }}"} == 0 + for: 1m + labels: + severity: critical +{% endif %} \ No newline at end of file diff --git a/roles/vault/templates/values/10-platform.j2 b/roles/vault/templates/values/10-platform.j2 index 6bb386ee..adbcf81b 100644 --- a/roles/vault/templates/values/10-platform.j2 +++ b/roles/vault/templates/values/10-platform.j2 @@ -3,7 +3,7 @@ global: openshift: true {% endif %} -{% if dsc.global.platform == "kubernetesVanilla" %} +{% if dsc.global.platform == "kubernetes" %} injector: securityContext: pod: diff --git a/roles/vault/templates/values/10-registry.j2 b/roles/vault/templates/values/10-registry.j2 index 610d491d..742148f5 100644 --- a/roles/vault/templates/values/10-registry.j2 +++ b/roles/vault/templates/values/10-registry.j2 @@ -16,3 +16,9 @@ csi: image: repository: "{{ dsc.global.registry }}/hashicorp/vault" {% endif %} + +{% if use_image_pull_secrets %} +global: + imagePullSecrets: + - name: dso-config-pull-secret +{% endif %} \ No newline at end of file diff --git a/uninstall.yaml b/uninstall.yaml index 7f2dc43c..f6a0617a 100644 --- a/uninstall.yaml +++ b/uninstall.yaml @@ -312,6 +312,17 @@ tags: - vault + - name: "Suppression de l'intance Argo CD" + kubernetes.core.helm: + name: "{{ dsc_name }}" + release_namespace: "{{ dsc.argocd.namespace }}" + release_state: absent + wait: true + tags: + - argocd + - argo + - gitops + - name: "Suppression du namespace ArgoCD" kubernetes.core.k8s: state: absent @@ -322,6 +333,17 @@ - argo - gitops + - name: "Suppression Argo CD OpenShift scc crb" + kubernetes.core.k8s: + state: absent + kind: ClusterRoleBinding + name: "{{ dsc_name }}-argocd-system:openshift:scc:privileged" + api_version: rbac.authorization.k8s.io/v1 + tags: + - argocd + - argo + - gitops + - name: "Suppression du namespace Harbor" kubernetes.core.k8s: state: absent diff --git a/versions.md b/versions.md index c4866b29..16b2864d 100644 --- a/versions.md +++ b/versions.md @@ -1,18 +1,18 @@ | Outil | Version | Chart version | Source | | ------------------------- | ---------------- | ------------- | --------------------------------------------------------------------------------------- | -| argocd | 2.10.7 | 6.0.10 | [argocd](https://artifacthub.io/packages/helm/bitnami/argo-cd) | +| argocd | 2.11.7 | 7.3.11 | [argocd](https://artifacthub.io/packages/helm/argo/argo-cd) | | certmanager | 1.14.3 | 1.14.3 | [certmanager](https://github.com/cert-manager/cert-manager/releases) | | cloudnativepg | 1.22.1 | 0.20.1 | [cloudnativepg](https://artifacthub.io/packages/helm/cloudnative-pg/cloudnative-pg) | | console | 8.0.2 | 8.0.2 | [console](https://github.com/cloud-pi-native/console/releases) | -| gitlab | 16.9.2 | 7.9.2 | [gitlab](https://artifacthub.io/packages/helm/gitlab/gitlab) | +| gitlab | 17.2.1 | 8.2.1 | [gitlab](https://artifacthub.io/packages/helm/gitlab/gitlab) | | gitlabCiPipelinesExporter | 0.5.8 | 0.3.4 | https://github.com/mvisonneau/helm-charts/tree/main/charts/gitlab-ci-pipelines-exporter | -| gitlabOperator | 0.29.2 | 0.29.2 | [gitlabOperator](https://gitlab.com/gitlab-org/cloud-native/gitlab-operator/-/tags) | -| gitlabRunner | 16.9.0 | 0.62.0 | [gitlabRunner](https://gitlab.com/gitlab-org/charts/gitlab-runner/-/tags) | -| grafana | 9.5.5 | N/A | [grafana](https://github.com/grafana/grafana/tags) | -| grafanaOperator | 5.4.2 | 5.4.2 | [grafanaOperator](https://github.com/grafana/grafana-operator/tags) | +| gitlabOperator | 1.2.1 | 1.2.1 | [gitlabOperator](https://gitlab.com/gitlab-org/cloud-native/gitlab-operator/-/tags) | +| gitlabRunner | 17.2.1 | 0.67.1 | [gitlabRunner](https://gitlab.com/gitlab-org/charts/gitlab-runner/-/tags) | +| grafana | 10.4.3 | N/A | [grafana](https://github.com/grafana/grafana/tags) | +| grafanaOperator | 5.10.0 | 5.4.2 | [grafanaOperator](https://github.com/grafana/grafana-operator/tags) | | harbor | 2.10.1 | 1.14.1 | [harbor](https://artifacthub.io/packages/helm/harbor/harbor) | | keycloak | 23.0.7 | 19.3.4 | [keycloak](https://artifacthub.io/packages/helm/bitnami/keycloak) | | kyverno | v1.11.4 | 3.1.4 | [kyverno](https://artifacthub.io/packages/helm/kyverno/kyverno) | | nexus | 3.68.1 | N/A | [nexus](https://hub.docker.com/r/sonatype/nexus3/) | -| sonarqube | 10.4.1-community | 10.4.1+2389 | [sonarqube](https://artifacthub.io/packages/helm/sonarqube/sonarqube) | +| sonarqube | 10.6.1-community | 10.6.1+3163 | [sonarqube](https://artifacthub.io/packages/helm/sonarqube/sonarqube) | | vault | 1.14.0 | 0.25.0 | [vault](https://artifacthub.io/packages/helm/hashicorp/vault) |