diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4b6e2af..4917744 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,16 +5,59 @@ on: branches: - main paths: - - docs/** + - hexaforge/** + - cloud-pi-native/** workflow_dispatch: jobs: + path-filter: + runs-on: ubuntu-latest + outputs: + hexaforge: ${{ steps.filter.outputs.hexaforge }} + cpin: ${{ steps.filter.outputs.cpin }} + steps: + - name: Check updated files paths + uses: dorny/paths-filter@v3 + id: filter + with: + filters: | + hexaforge: + - 'hexaforge/**' + cpin: + - 'cloud-pi-native/**' + + infos: + name: Get infos + runs-on: ubuntu-latest + needs: + - path-filter + outputs: + matrix: ${{ steps.infos.outputs.MATRIX }} + steps: + - name: Checks-out repository + id: infos + run: | + MATRIX="[]" + HEXAFORGE='[{"name": "hexaforge"}]' + if [ "${{ needs.path-filter.outputs.hexaforge }}" = 'true' ]; then + MATRIX="$( jq -n -c --argjson acc "$MATRIX" '$acc + [{ "name": "hexaforge", "context": ".", "dockerfile": "Dockerfile.hexaforge" }] )" + else if [ "${{ needs.path-filter.outputs.cpin }}" = 'true' ]; then + MATRIX="$( jq -n -c --argjson acc "$MATRIX" '$acc + [{ "name": "cpin", "context": ".", "dockerfile": "Dockerfile.cpin" }] )" + fi + echo "MATRIX=$MATRIX" >> $GITHUB_OUTPUT + build: name: Build application runs-on: ubuntu-latest + needs: + - path-filter + - infos permissions: contents: read packages: write + strategy: + matrix: + images: ${{ fromJSON(needs.infos.outputs.matrix) }} steps: - name: Checks-out repository uses: actions/checkout@v4 @@ -36,9 +79,9 @@ jobs: - name: Build docker image uses: docker/build-push-action@v5 with: - context: . - file: Dockerfile - tags: ghcr.io/${{ github.repository }}:latest + context: ${{ matrix.images.context }} + file: ${{ matrix.images.dockerfile }} + tags: ghcr.io/${{ github.repository }}-${{ matrix.images.name }}:latest target: prod platforms: linux/amd64,linux/arm64 push: true @@ -48,4 +91,4 @@ jobs: curl -X POST https://gitops.fabrique-numerique.fr/api/v1/applications/cloud-pi-native-docs/sync \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${{ secrets.ARGOCD_TOKEN }}" \ - -d '${{ vars.ARGOCD_SYNC_PAYLOAD }}' + -d '${{ vars.ARGOCD_SYNC_PAYLOAD }}' \ No newline at end of file diff --git a/Dockerfile.cpin b/Dockerfile.cpin new file mode 100644 index 0000000..e2d331c --- /dev/null +++ b/Dockerfile.cpin @@ -0,0 +1,25 @@ +# Base stage +FROM docker.io/node:20.14.0-bullseye-slim AS dev + +WORKDIR /app +RUN npm install --location=global pnpm +COPY --chown=node:root package.json pnpm-lock.yaml ./ +RUN pnpm install +COPY --chown=node:root cloud-pi-native ./cloud-pi-native +ENTRYPOINT [ "pnpm", "run", "dev:cpin" ] + + +# Build stage +FROM dev AS build + +RUN pnpm run build:cpin + + +# Prod stage +FROM docker.io/bitnami/nginx:1.26.1 AS prod + +USER 0 +COPY --chown=1001:0 --chmod=770 --from=build /app/cloud-pi-native/.vitepress/dist /opt/bitnami/nginx/html/ +COPY --chown=1001:0 --chmod=660 ./nginx.conf /opt/bitnami/nginx/conf/server_blocks/default.conf +USER 1001 +EXPOSE 8080 diff --git a/Dockerfile b/Dockerfile.hexaforge similarity index 64% rename from Dockerfile rename to Dockerfile.hexaforge index 08de657..c01b978 100644 --- a/Dockerfile +++ b/Dockerfile.hexaforge @@ -5,21 +5,21 @@ WORKDIR /app RUN npm install --location=global pnpm COPY --chown=node:root package.json pnpm-lock.yaml ./ RUN pnpm install -COPY --chown=node:root docs ./docs -ENTRYPOINT [ "pnpm", "run", "dev" ] +COPY --chown=node:root hexaforge ./hexaforge +ENTRYPOINT [ "pnpm", "run", "dev:hexaforge" ] # Build stage FROM dev AS build -RUN pnpm run build +RUN pnpm run build:hexaforge # Prod stage FROM docker.io/bitnami/nginx:1.26.1 AS prod USER 0 -COPY --chown=1001:0 --chmod=770 --from=build /app/docs/.vitepress/dist /opt/bitnami/nginx/html/ +COPY --chown=1001:0 --chmod=770 --from=build /app/hexaforge/.vitepress/dist /opt/bitnami/nginx/html/ COPY --chown=1001:0 --chmod=660 ./nginx.conf /opt/bitnami/nginx/conf/server_blocks/default.conf USER 1001 EXPOSE 8080 diff --git a/README.md b/README.md index 9a41088..f4c4d65 100644 --- a/README.md +++ b/README.md @@ -1,160 +1,56 @@ -# Cloud π Native - -:warning: __*La plateforme est en cours de construction et des évolutions fréquentes sont à prévoir.*__ :warning: +# Documentation Cloud π Native / Hexaforge Ce dépôt est construit et déployé à l'adresse : -## L'offre - -### Présentation - -Avec l’adoption de la doctrine « Cloud au centre », le Gouvernement Français fait du Cloud un prérequis pour tout nouveau projet numérique au sein de l’État ou refonte substantielle de l’architecture applicative existante. - -**Objectif** : accélérer la transformation numérique au bénéfice des usagers et dans le strict respect de la cybersécurité et de la protection des données des citoyens et des entreprises. - -L'offre interministérielle Cloud π Native, offre les services d'une plateforme DevSecOps complète afin de suivre le cycle de vie complet de son projet. - -La philosophie de l'offre est de créer une chaine collaborative étendue entre l'équipe de développement et l'hébergement, qui s'appuient sur : - - un socle d'intégration à la main des développeurs, appellée chaine primaire. - - un service côté infrastructure étatique effectuant la recompilation du code et l'automatisation des déploiement, appellée chaine secondaire. - -La chaine secondaire est également en charge de mesurer la qualité du code et la conduite d'audits automatisés à chaque build/déploiement contribuant à l'homologation en continu de l'application. - -L'usage de standards industriels largement distribués tel que kubernetes et Gitops et la sécabilité de l'offre, permettent un transfert facilité depuis et vers d'autres solutions d'hébergement kubernetes telles que les Clouds Publics. - -Le cadre interministériel d'utilisaton de l'offre est disponible à l'emplacement suivant : - -Lorsque que l'équipe projet est prête avec un première base de code fonctionnelle, il est possible de l'intégrer sur l'offre Cloud π Native. - -La séquence d'accès typique est la suivante : - - - Effectuer une demande d'accès au service via le formulaire suivant : par un correspondant étatique ayant la compétence pour accepter les conditions CGU et fournir les données d'imputation budgétaire (UO). - - Après acceptation du dossier, l'enrollement du projet est effectuté dans la console Cloud pi Native, et l'équipe projet est en charge d'instancier les ressources nécessaires (gitlab, vault, registry, etc...) dans la chaine secondaire et de configurer son projet ; - - Recopie des repository de code et de déploiement; - - Mise en place du pipeline "DevSecOps" au sein de la chaine secondaire. L'application reste maître de son pipeline et de sa surveillance; - - Mise en place du/des namespaces dans le cluster cible ainsi des secrets nécessaires au fonctionnement et du provisionning gitops de l'application (argoCD); - - Provisionning des ressources d'infrastructure additionnelles ( certificats, ouverture de fluxs, bucket S3, etc...). Cette étape nécessite l'intervention des équipes d'infrastructure Miom ( ou de l'hébergeur choisis) & du ministère cible. (automatisation progressive en cours) - - Construction des artefacts sur l'offre Cloud π Native; - - Analyse de qualité et de la sécurité; - - Construction des images de conteneurs; - - Provisionning de l'application dans le cluster (l'application est tirée via GitOps). - -Enfin, le déploiement s'effectue sur différentes cibles d'hébergement possibles : - - - Un socle kubernetes/Openshift jusqu'au niveau DR sur les environnements du ministère; - - Un cluster kubernetes directement gérés par l'équipe client par exemple chez un Cloud Service Provider. - -**Vision d'ensemble de l'offre :** - -![vision](docs/public/img/global-vision.png) - -### Les services proposés - -L'offre Cloud π Native, portée par le Ministère de l'Intérieur et des Outre-Mer est une offre PaaS basée sur [Cloud π](https://www.numerique.gouv.fr/services/cloud/cloud-interne/) sur les infrastructures du ministère de l'intérieur offrant des fonctionnalités DevSecOps à savoir : - - - [Gestionnaire de sources](docs/services/gitlab.md) applicatives - - Outil de gestion de la [qualité](docs/services/sonarqube.md) statique du code (SAST) et dynamique (DAST) - - Orchestrateur de [construction](docs/services/gitlab.md) d'artefacts (Intégration continue) - - [Entrepot d'artefacts](docs/services/artefacts.md) et d'images Docker - - Gestionnaire de [secrets](docs/services/vault.md) des chaines IC/DC - - Gestion des [secrets applicatifs](docs/guide/secrets-management.md) - - Outil de [déploiement automatisé](docs/services/gitops.md) des images Docker sur les infrastructures du ministère ou à l'extérieur du ministère en suivant les principes GitOps (Déploiement continue) - - Hébergement des [environnements](docs/guide/environments-management.md) applicatifs de l'intégration à la production - - Gestion des [équipes](docs/guide/team.md) - - Mise à disposition d'outil d'[observabilité et exploitabilité](docs/agreement/exploitation.md) des applications déployées sur l'offre : accès aux logs, métriques techniques et applicatives, procédures standard d'exploitation - -L'architecture générale de l'offre Cloud π Native est la suivante : - -![](docs/public/img/architecture.png) - -### SLA associés à l'offre Chaine DevSecOps secondaire - -L'offre Cloud π Native s'appuie sur l'hébergement Cloud du ministère. Les grands services ayant des contraintes de SLA différentes : - - - Le Cloud pour assurer le fonctionnement et la sécurisation de l'offre DevSecOps secondaire ( et le fonctionnement en production des application ) - - Outils de construction applicative (Intégration continue) permettant de construire un package applicatif à partir des sources - - Outils de déploiement (Déploiement continue) permettant de déployer / mettre à jour une application sur les différents environnements de l'offre - - Les applications qui sont déployées sur l'offre. Chacune de ces applications peut également avoir un niveau de criticité différent (par exemple l'environnement de production a un besoin de SLA plus fort que l'environnement de recette) - -| Service | DIMA* | PDMA** | -| ------------ | -------- | ------------------------------- | -| Construction | 8 heures | 24h (backup nocturne quotidien) | -| Déploiement | 8 heures | 24h (backup nocturne quotidien) | - -*DIMA : Durée d'interruption maximale autorisée (en heures ouvrés) -**PDMA : Perte de données maximale admissible (en heures ouvrés) - -Note : le SLA du cloud PI pour le fonctionnement en production des applications est de 99,9%, pour plus de détail, se référer aux CGU de l'offre d'hébergement Cloud PI. - -## Accompagnement (WIP) - -Un volet [accompagnement](docs/agreement/support.md) intial des projets directement par les équipes de l'offre Cloud π Native permet d'utiliser l'offre dans des conditions optimales. Cet accompagnement fait partie du parcours technique d'embarquement sur l'offre Cloud π Native. - -Elle s'articule dans une offre à 3 niveaux : - - Démarche autonome ( kit d'autoformation, tutoriels, etc... ) - - Démarche d'accompagnement à l'initialisation ( "Service Team" ) -- Formation et certification d'acteurs externes ( offre en cours d'élaboration ) - -Les ressources d'accompagnement étant limitées, l'embarquement est conditionné à des prérequis techniques et ou organisationnels [prérequis](docs/platform/compatibility.md) pour embarquer sur l'offre Cloud π Native de façon sereine et optimale. +## Contribuer -Typiquement l'équipe doit être dans un parcours de montée en compétence à l'agilité et à la conteneurisation/kubernetes. +L'offre Cloud π Native s'améliore grâce aux retours de nos utilisateurs, n'hésitez pas à contribuer, notamment en nous faisant des retours sur la documentation. Le détail pour contribuer est [ici](CONTRIBUTING.md) -## Embarquement technique +__Pour formater le code, veuillez à lancer la commande `pnpm run format` avant votre commit.__ -Un parcours technique d'apprentissage permettant de valider les prérequis et d'intégrer les bonnes pratiques permet à nos clients d'appréhender l'offre Cloud π Native. +### Documentation de l'offre de service Cloud π Native -![parcours_apprentissage](docs/public/img/learning-process.png) +Le dépôt est construit avec [vitepress](https://vitepress.dev) à l'aide de fichiers markdown positionnés dans les dossiers [cloud-pi-native](./cloud-pi-native/), les assets (images, fichiers additionnels, etc...) sont positionnés dans le dossier [public](./cloud-pi-native/public/). - - Etape 1 : [Matrice de compétences](docs/platform/skills-matrix.md) des technologies à connaitre pour utiliser l'offre Cloud π Native - - Etape 2 : Vérification de l'éligibilité de son application avec le modèle Cloud Native Application [prérequis](docs/platform/compatibility.md) technique liés à l'offre. Les équipes Cloud π Native [accompagnent](docs/agreement/support.md) les équipes projets sur cette étape afin d'apporter conseils et qualification des architectures et maturité technique des équipes. - - Etape 3 : Prise de connaissance des [bonnes pratiques](docs/guilde/best-practices.md) et expérimentation avec une série de tutoriels [tutoriels](docs/guide/tutorials.md) afin de faire ses premiers pas avec l'offre - - Etape 4 : [Embarquement](docs/guide/get-started.md) de l'application sur l'offre - - Etape 5 : Félicitation ! Vous êtes maintenant un utilisateur de la plateforme Cloud π Native et votre application peut passer en production via les principes d'[exploitation et observabilité](docs/agreement/exploitation.md) de vos projets. +Structure de la documentation : -A tout moment, vous pouvez consulter la [documentation détaillée](docs/platform/introduction.md) de la plateforme Cloud π Native, son architecture et les services proposés +```sh +./cloud-pi-native + ├── acceleration/ + ├── guide/ + ├── agreement/ + ├── best-practices/ + ├── certification/ + ├── faq/ + ├── public + │ ├── examples/ + │ ├── img/ + │ ├── favicon.ico + │ └── logo-marianne-gouvernement.png + ├── contribute.md + └── index.md +``` -Enfin notre [FAQ](docs/agreement/faq.md) permet de lister les questions fréquentes de nos clients, et des exemples pour réaliser des bouchons (S3, SMTP, ...) +### Documentation de la plateforme Hexaforge -## Notre roadmap (WIP) +Le dépôt est construit avec [vitepress](https://vitepress.dev) à l'aide de fichiers markdown positionnés dans le dossiers [hexaforge](./hexaforge/), les assets (images, fichiers additionnels, etc...) sont positionnés dans le dossier [public](./hexaforge/public/). -L'offre Cloud π Native est en cours de construction incrémentale. Notre [feuille de route détaillée](docs/platform/roadmap.md) est accessible permettant de donner de la visibilité sur les prochaines fonctionnalités. +Structure de la documentation : -Voici les grandes fonctionnalités prévus dans les prochaines semaines : - - Réduction de la quantité de code / manifest à produire; - - Automatisation des services d'infrastructure; - - et surtout, prise en compte des retours des primo-accédants. +```sh +./hexaforge + ├── administration/ + ├── guide/ + ├── installation/ + ├── platform/ + ├── public + │ ├── examples/ + │ └── img/ + ├── services/ + ├── contribute.md + └── index.md +``` ## Contact -Pour toute information ou demande pour rejoindre la betatest, veuillez nous contacter à l'adresse suivante : . - -Si vous souhaitez devenir primo accédant, beta testeurs ou avez des questions, veuillez nous contacter directement via le serveur Mattermost prévu à cet effet (si vous n'avez pas été ajouté au serveur Mattermost, veuillez contacter l'adresse mail précédente). - -## Contribuer - -L'offre Cloud π Native s'améliore grâce aux retours de nos utilisateurs, n'hésitez pas à contribuer, notamment en nous faisant des retours sur la documentation. Le détail pour contribuer est [ici](CONTRIBUTING.md) - -### Contribuer à la documentation - -Le dépôt est construit avec [vitepress](https://vitepress.dev) à l'aide de fichiers markdown positionné dans le dossier [docs](./docs/). -Les assets (images, fichiers additionnels, etc...) sont positionnés dans le dossier [public](./docs/public/). - -__Pour formater le code, veuillez à lancer la commande `pnpm run format` avant votre commit.__ - -Structure du dépôt : - -```sh -./docs -├── contribution/ -├── guide/ -├── installation/ -├── platform/ -├── public -│ ├── examples/ -│ ├── img/ -│ ├── favicon.ico -│ └── logo-marianne-gouvernement.png -├── agreement/ -├── services/ -└── index.md -``` +Pour toute information, veuillez nous contacter à l'adresse suivante : . diff --git a/cloud-pi-native/.vitepress/config.ts b/cloud-pi-native/.vitepress/config.ts new file mode 100644 index 0000000..dfa7a55 --- /dev/null +++ b/cloud-pi-native/.vitepress/config.ts @@ -0,0 +1,40 @@ +import { defineConfig } from 'vitepress' +import sidebar from './sidebar.json' assert { type: 'json'} + +export default defineConfig({ + base: '/', + lang: 'fr-FR', + title: 'Cloud π Native', + description: 'Documentation de la plateforme Cloud Pi Native', + cleanUrls: true, + themeConfig: { + logo: '/logo-marianne-gouvernement.png', + outline: [2, 3], + sidebar, + socialLinks: [ + { icon: 'github', link: 'https://github.com/cloud-pi-native/documentation' } + ], + search: { + provider: 'local', + options: { + translations: { + button: { + buttonText: 'Rechercher...', + buttonAriaLabel: 'Rechercher' + }, + modal: { + backButtonTitle: 'effacer la recherche', + displayDetails: 'afficher les détails', + noResultsText: 'Aucun résultat pour ', + resetButtonTitle: 'annuler la recherche', + footer: { + selectText: 'aller à ce texte', + navigateText: 'naviguer dans les résultats', + closeText: 'fermer' + } + } + }, + } + }, + }, +}) diff --git a/cloud-pi-native/.vitepress/sidebar.json b/cloud-pi-native/.vitepress/sidebar.json new file mode 100644 index 0000000..86e63a5 --- /dev/null +++ b/cloud-pi-native/.vitepress/sidebar.json @@ -0,0 +1,68 @@ +[ + { + "text": "Offre de services", + "collapsed": true, + "items": [ + { + "text": "Introduction", + "link": "/agreement/introduction" + }, + { + "text": "Accompagnement", + "link": "/agreement/support" + }, + { + "text": "Exploitation", + "link": "/agreement/exploitation" + }, + { + "text": "Observabilité", + "link": "/agreement/observability" + } + ] + }, + { + "text": "Certification", + "collapsed": true, + "items": [ + { + "text": "Introduction", + "link": "/certification/introduction" + } + ] + }, + { + "text": "Acceleration", + "collapsed": true, + "items": [ + { + "text": "Bouchons", + "link": "/acceleration/mocks" + } + ] + }, + { + "text": "Bonnes pratiques", + "collapsed": true, + "items": [ + { + "text": "Règles kyverno", + "link": "/best-practices/kyverno" + }, + { + "text": "Labels kubernetes", + "link": "/best-practices/labels-list" + } + ] + }, + { + "text": "F.A.Q", + "collapsed": true, + "items": [ + { + "text": "Introduction", + "link": "/faq/introduction" + } + ] + } +] diff --git a/cloud-pi-native/.vitepress/theme/index.ts b/cloud-pi-native/.vitepress/theme/index.ts new file mode 100644 index 0000000..c93cb0b --- /dev/null +++ b/cloud-pi-native/.vitepress/theme/index.ts @@ -0,0 +1,5 @@ +// https://vitepress.dev/guide/custom-theme +import DefaultTheme from 'vitepress/theme' +import './style.css' + +export default DefaultTheme diff --git a/cloud-pi-native/.vitepress/theme/style.css b/cloud-pi-native/.vitepress/theme/style.css new file mode 100644 index 0000000..de4f5dd --- /dev/null +++ b/cloud-pi-native/.vitepress/theme/style.css @@ -0,0 +1,100 @@ +/** + * Customize default theme styling by overriding CSS variables: + * https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/vars.css + */ + +/** + * Colors + * -------------------------------------------------------------------------- */ + +:root { + --blue-france-sun-113: #000091; + --red-marianne-main-472: #e1000f; + + --vp-c-brand: var(--blue-france-sun-113); + --vp-c-brand-light: #6a6af4; + --vp-c-brand-lighter: #8585f6; + --vp-c-brand-lightest: #cacafb; + --vp-c-brand-dark: #313178; + --vp-c-brand-darker: #272747; + --vp-c-brand-dimm: rgba(33, 33, 63, 0.08); + +} + +/** + * Component: Button + * -------------------------------------------------------------------------- */ + +:root { + --vp-button-brand-border: var(--vp-c-brand-light); + --vp-button-brand-text: var(--vp-c-white); + --vp-button-brand-bg: var(--vp-c-brand); + --vp-button-brand-hover-border: var(--vp-c-brand-light); + --vp-button-brand-hover-text: var(--vp-c-white); + --vp-button-brand-hover-bg: var(--vp-c-brand-light); + --vp-button-brand-active-border: var(--vp-c-brand-light); + --vp-button-brand-active-text: var(--vp-c-white); + --vp-button-brand-active-bg: var(--vp-button-brand-bg); +} + +/** + * Component: Home + * -------------------------------------------------------------------------- */ + +:root { + --vp-home-hero-name-color: transparent; + --vp-home-hero-name-background: -webkit-linear-gradient( + 120deg, + var(--vp-c-brand) 30%, + var(--red-marianne-main-472) + ); + + --vp-home-hero-image-background-image: linear-gradient( + -45deg, + var(--vp-c-brand) 50%, + var(--red-marianne-main-472) + ); + --vp-home-hero-image-filter: blur(40px); +} + +@media (min-width: 640px) { + :root { + --vp-home-hero-image-filter: blur(56px); + } +} + +@media (min-width: 960px) { + :root { + --vp-home-hero-image-filter: blur(72px); + } +} + +/** + * Component: Custom Block + * -------------------------------------------------------------------------- */ + +:root { + --vp-custom-block-tip-border: var(--vp-c-brand); + --vp-custom-block-tip-text: var(--vp-c-brand-darker); + --vp-custom-block-tip-bg: var(--vp-c-brand-dimm); +} + +.dark { + --vp-c-brand: #6a6af4; + --vp-custom-block-tip-border: var(--vp-c-brand); + --vp-custom-block-tip-text: var(--vp-c-brand-lightest); + --vp-custom-block-tip-bg: var(--vp-c-brand-dimm); + --vp-home-hero-name-background: -webkit-linear-gradient( + 120deg, + var(--vp-c-brand-light) 30%, + var(--red-marianne-main-472) + ); +} + +/** + * Component: Algolia + * -------------------------------------------------------------------------- */ + +.DocSearch { + --docsearch-primary-color: var(--vp-c-brand) !important; +} diff --git a/cloud-pi-native/acceleration/mocks.md b/cloud-pi-native/acceleration/mocks.md new file mode 100644 index 0000000..e353201 --- /dev/null +++ b/cloud-pi-native/acceleration/mocks.md @@ -0,0 +1,223 @@ +# Bouchons + +Un chart Helm a été créé afin de permettre aux projets clients de l'offre Cloud Pi Native de simuler ou remplacer les éléments fournis par l'infrastructure du MI à savoir : + +- Un serveur SMTP pour les envois de mails +- La création d'un bucket S3 +- Le SSO *Passage2* + +Le chart Helm est disponible sur le [repo github public](https://github.com/cloud-pi-native/helm-projects-mocks). + +## Utilisation + +Ces éléments sont à utiliser uniquement sur les environnements **Hors ministère de l'intérieur**, ainsi il est préférable de ne pas les ajouter dans le repo d'infra de l'application à déployer mais *à côté*. + +Ainsi, pour utiliser ce chart HELM, il faut, depuis la console DSO, ajouter un nouveau Dépôt sur un projet existant, choisir comme nom de repo "bouchon" et comme URL : et cocher la *case Dépôt d'infrastructure* : + +![Ajout du repo bouchon](/img/mocks/add-repo.png) + +Une fois le projet ajouté, il est présent sur gitlab et une nouvelle application est créée sur ArgoCD : + +![Ajout du repo bouchon](/img/mocks/mocks-argo.png) + +Aller dans App Details : +![Ajout du repo bouchon](/img/mocks/mocks-argo-app-details.png) +Modifier le cluster de destination (comme pour l'application) + +Puis aller sur l'onglet PARAMETERS: +![Ajout du repo bouchon](/img/mocks/mocks-argo-parameters.png) + +Cliquez en haut à droite sur le bouton EDIT et adapter le paramétrage en fonction de ses besoins. Voir le détail dans la description des bouchons dans les chapitres suivants. + +Le chart helm sur github contient un fichier *values.yaml* contenant l'ensemble des valeurs paramétrables et un second fichier *custom-values.yaml* contenant uniquement les valeurs importantes comme l'activation du S3 et du SMTP. Une fois le projet importé via la console, il est possible, en tant que projet de modifier le fichier custom-values.yaml directement depuis le gitlab DSO et éviter de modifier les paramètres depuis ArgoCD. Dans ce cas, il faut déclarer le fichier custom-values.yaml dans les paramètres ArgoCD. + +## Description des bouchons + +### Serveur SMTP + +Le chart Helm installe un serveur mailhog sur les ports 8025 (IHM Web) et 1025 (port SMTP). +La configuration s'effectue dans le fichier values.yaml dans la sous l'entrée racine "smtp" + +Voici la configuration par defaut présente dans le fichier values.yaml du chart +```yaml +smtp: + # Active ou non l'installation du serveur SMTP + enabled: true + # Référence vers l'image mailhog sur docker.io + image: + repository: docker.io/mailhog/mailhog + tag: v1.0.1 + pullPolicy: IfNotPresent + + nameOverride: "" + fullnameOverride: "" + + containerPort: + http: + name: http + port: 8025 + smtp: + name: tcp-smtp + port: 1025 + + service: + annotations: {} + # Named target ports are not supported by GCE health checks, so when deploying on GKE + # and exposing it via GCE ingress, the health checks fail and the load balancer returns a 502. + namedTargetPort: true + port: + http: 8025 + smtp: 1025 + + ingress: + enabled: true + # ingressClassName: nginx + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + labels: {} + # hostOverride: mailhog.example.com + + auth: + enabled: true + existingSecret: "" + fileName: auth.txt + fileContents: Ym9iOiQyYSQwNCRRN1VwdmQvWUlwck5DcExsUHpFQ2VlRnZrVlI1RVhKbG1uZjZ4S050ZHlXSnJoeW1hNUhlaQ== # format user:password (où password est bcrypted) le tout en base64 + + # JSON file defining outgoing SMTP servers + outgoingSMTP: + enabled: false + existingSecret: "" + fileName: outgoing-smtp.json + fileContents: {} + # See https://github.com/mailhog/MailHog/blob/master/docs/CONFIG#outgoing-smtp-configuration + # Only name, host and port are required. + # + # server_name1: + # name: "server_name1" + # host: "mail.example.com" + # port: "25" # NOTE: go requires this port number to be a string... otherwise the container won't start + # email: "" + # username: "" + # password: "" + # mechanism: "PLAIN|CRAM-MD5" + # server_name2: + # name: "server_name2" + # host: "mail2.example.com" + # port: "587" # NOTE: go requires this port number to be a string... otherwise the container won't start + + podReplicas: 1 + + podAnnotations: {} + + podLabels: + app: bouchon-smtp + env: ovh + tier: bouchon + criticality: low + component: smtp + + extraEnv: [] + + # ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#configure-probes + livenessProbe: + initialDelaySeconds: 10 + timeoutSeconds: 1 + + resources: + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + limits: + cpu: 100m + memory: 64Mi + requests: + cpu: 100m + memory: 64Mi +``` + +### Bucket S3 + +Le chart permet également de créer un bucket de stockage objet S3 via MinIO. + +```yaml +minio: + enabled: true # Activation de minIO + ingress: + enabled: true # Activation de l'ingress pour l'IHM + hostname: minio-st.dso.numerique-interieur.com # Hostname de l'IHM à adapter par projet + defaultBuckets: "my-bucket-app, my-second-bucket" # Nom de bucket par defaut +``` + +Le chart dans cette configuration va créer sur le namespace : + - 2 buckets S3 nommés my-bucket-app et my-second-bucket + - Un secret contenant 2 clés **root-password** et **root-user** pour se connecter à l'IHM permettant d'administrer minIO (création de bucket de 'AK/SK). + +Pour utiliser MinIO sur un pod, il faut créer et injecter la configuration via configMap ou Secret : + +```yaml +# [...] +containers: + # [...] + envFrom: + - configMapRef: + name: cm-name + - secretRef: + name: secret-name +# [...] +``` + +### Passage2 + +Le chart permet d'activer un bouchon Passage2 permettant de simulé le mécanisme d'authentification SSO du ministère de l'intérieur. + +Le mécanisme du bouchon d'authentification repose sur un **Reverse proxy** authentifiant et d'un keycloak en SAML ajoutant au requete entrante des headers contenant les roles/groups de l'utilisateur authentifié. + +**Le reverse proxy authentificant devra intercepter l'ensemble des requetes necessitant une authentifiation** + +Le chart permet d'ajouter les composants nécessaire à la mise en place de ce bouchon. + +```yaml +passage2: + # Active ou non le bouchon + enabled: true + reverseproxy: + # Url de l'ingress du reverse proxy authentifiant + hostname: mellon.example.com + proxy: + # Valeur des headers ajouté par MELLON + headers: |- + #Ajout de header Mellon-NameID avec le nom de l'utilisateur connecté + RequestHeader set Mellon-NameID %{MELLON_NAME_ID}e + Header set Mellon-NameID %{MELLON_NAME_ID}e + + #Ajout de header Mellon-Groups avec les groupes de l'utilisateur connecté + RequestHeader set Mellon-Groups %{MELLON_groups}e + Header set Mellon-Groups %{MELLON_groups}e + + #Ajout de header Mellon-Role avec les roles de l'utilisateur connecté + RequestHeader set Mellon-Role %{MELLON_Role}e + Header set Mellon-Role %{MELLON_Role}e + + rules: |- + # Exemple de redirection vers différents services applicatifs base sur le suffix, il est possible d'utiliser les différentes directive apache + ProxyPassMatch "^/(.*)" "http://whoami-svc:8080/$1" + ProxyPassReverse "^/(.*)" "http://whoami-svc:8080/$1" + # il est possible d'avoir plusieur service de redirection + ProxyPass /my-service2 "http://whoami3-svc:80" + ProxyPassReverse /my-service2 "http://whoami3-svc:80" + + mockpassage2: + # Url d'accès au keycloak pour la gestion des utilisateurs/droits + hostname: passage2.example.com + # Login du user admin + adminLogin: admin + # Password du user admin + adminPassword: OZJFejfrejijIZJijfeij +``` + +Il faudra configuré le RPA pour renvoyer vers vos service applicatifs en modifiant le bloc **rules** afin que celui-ci rajoute les headers. +Une fois les composants déployé, l'authentification se fera par keycloak, un compte utilisateur d'exemple est crée test/test, avec aucun roles ou groupes. + +Dans le cas ou l'utilisateur possède plusieurs roles/groupes ceux-ci seront sépéraré par une **,** diff --git a/cloud-pi-native/agreement/exploitation.md b/cloud-pi-native/agreement/exploitation.md new file mode 100644 index 0000000..fef281e --- /dev/null +++ b/cloud-pi-native/agreement/exploitation.md @@ -0,0 +1,42 @@ +# Exploitation de l'offre + +L'offre Cloud π Native permet *in fine* de déployer des applications. Le volet observabilité et exploitabilité est présent dans l'offre et regroupe les éléments tels que : + - Accès aux logs applicatives + - Accès aux métriques de consommation de ressources des applications + - Ajout de métriques d'observabilité + - Procédures standards pour les opérations usuelles comme la sauvegarde et restauration, PRA, chargement des données. + +## SLA de la plateforme + +L'offre Cloud π Native s'appuie sur l'hébergement Cloud du ministère. Les grands services ayant des contraintes de SLA différentes : + + - Le Cloud pour assurer le fonctionnement et la sécurisation de l'offre DevSecOps secondaire ( et le fonctionnement en production des application ) + - Outils de construction applicative (Intégration continue) permettant de construire un package applicatif à partir des sources + - Outils de déploiement (Déploiement continue) permettant de déployer / mettre à jour une application sur les différents environnements de l'offre + - Les applications qui sont déployées sur l'offre. Chacune de ces applications peut également avoir un niveau de criticité différent (par exemple l'environnement de production a un besoin de SLA plus fort que l'environnement de recette) + +| Service | DIMA* | PDMA** | +| ------------ | -------- | ------------------------------- | +| Construction | 8 heures | 24h (backup nocturne quotidien) | +| Déploiement | 8 heures | 24h (backup nocturne quotidien) | + +*DIMA : Durée d'interruption maximale autorisée (en heures ouvrés) +**PDMA : Perte de données maximale admissible (en heures ouvrés) + +Note : le SLA du cloud PI pour le fonctionnement en production des applications est de 99,9%, pour plus de détail, se référer aux CGU de l'offre d'hébergement Cloud PI. + +## Exploitabilité + +:construction: *Disponible prochainement* :construction: + +### Accès aux logs + +:construction: *Disponible prochainement* :construction: + +### Accès aux métriques + +:construction: *Disponible prochainement* :construction: + +### Sauvegarde et restauration + +:construction: *Disponible prochainement* :construction: diff --git a/cloud-pi-native/agreement/introduction.md b/cloud-pi-native/agreement/introduction.md new file mode 100644 index 0000000..dfcf599 --- /dev/null +++ b/cloud-pi-native/agreement/introduction.md @@ -0,0 +1,83 @@ +# L'offre Cloud Pi Native + +La direction de la transformation numérique du ministère de l'Intérieur et des outre-mer propose une offre de services autour de deux instances de la plateforme *(OVH SecNumCloud / Cloud π)* à destination des *administrations* ou des *entreprises de services numériques* travaillant pour leur compte. +Cette offre de services est une implémentation du produit *Hexaforge* pour le ministère de l'intérieur ainsi qu'un accompagnement dédié aux spécificités des infrastructures ministérielles. + +> __:warning: Attention, les seuls bénéficiaires de cette offre managée sont les administrations ou leurs ESN partenaires. + +Vous pouvez consulter [la documentation détaillée](https://github.com/cloud-pi-native/embarquement-autoformation) du processus d'embarquement sur cette offre. + +**Votre point de contact** : dtnum-brm-contacts@interieur.gouv.fr + +## Introduction + +Avec l’adoption de la doctrine « Cloud au centre », le gouvernement français fait du Cloud un prérequis pour tout nouveau projet numérique au sein de l’État ou refonte substantielle de l’architecture applicative existante. + +**Objectif** : Accélérer la transformation numérique au bénéfice des usagers et dans le strict respect de la cybersécurité et de la protection des données des citoyens et des entreprises. + +L'offre *interministérielle* Cloud π Native, offre les services d'une plateforme *DevSecOps* complète afin de suivre le cycle de vie complet de son projet. +La philosophie de l'offre est de créer une chaîne collaborative étendue entre l'équipe de développement et l'hébergement, qui s'appuient sur : +* Un socle d'intégration à la main des développeurs, appelé chaine primaire. +* Un service côté infrastructure étatique effectuant la recompilation du code et l'automatisation des déploiement, appelé chaîne secondaire. + +La chaîne secondaire a également la charge de mesurer la qualité du code et la conduite d'audits automatisés à chaque build/déploiement contribuant à l'homologation en continu de l'application. + +L'usage de standards industriels largement distribués tel que kubernetes, Gitops et la sécabilité de l'offre, permettent un transfert facilité depuis et vers d'autres solutions d'hébergement kubernetes telles que les Clouds Publics. + +Lorsque que l'équipe projet est prête avec une première base de code fonctionnelle, il est possible de l'intégrer sur l'offre Cloud π Native. + +Vous trouverez le détail de cette offre [ici](https://cloud-pi-native.fr/platform/introduction.html) + +Le cadre interministériel d'utilisaton de l'offre est disponible à l'emplacement suivant : + +Dés que les [prérequis](https://cloud-pi-native.fr/agreement/support.html) sont présents, la souscription à l'offre Cloud π Native est possible en suivant les étapes suivantes : + - Contacter l’adresse suivante pour faire une demande: dtnum-brm-contacts@interieur.gouv.fr + - Après acceptation de la demande, l'équipe [Accompagnement](https://cloud-pi-native.fr/agreement/introduction.html#accompagnement) prendra contact avec vous pour la phase d'accompagnement. + +Enfin, le déploiement s'effectue sur différentes cibles d'hébergement possibles : + +**Vision d'ensemble de l'offre de services:** + +![vision](/img/global-vision.png) + +Comme mentionné dans le schèma, l'offre de services comprend si vous le souhaitez l'infrastructure hébergeant vos applicatifs. +Cette infrastructure peut-être : + - Un socle Kubernetes/Openshift mutualisé dans la zone "Non Protégé" (NP) du ministère de l'Intérieur. + - Un socle Kubernetes/Openshift dédié dans la zone "Non Protégé" (NP) ou la zone "Diffusion Restreinte (DR) du ministère de l'intérieur. + - Un socle Kubernetes directement gérés par l'équipe projet. + +Le choix de la cible est au cas par cas et fait lors des premières phases d'échange. + +## Accompagnement + +Comme mentionné plus haut, à la souscription de l'offre Cloud π Native, une équipe accompagnement sera le vis-à-vis du projet et assurera : +- Un [accompagnement](/agreement/support) rapproché aux projets pour que l'utilisation de l'offre se réalise dans des conditions optimales. +- Le parcours technique d'embarquement sur l'offre Cloud π Native qui s'articule sur trois niveaux : + * Démarche autonome (Kit d'autoformation, tutoriels, etc. ) + * Démarche d'accompagnement à l'initialisation ( "Service Team" ) + * Formation et certification d'acteurs externes + +Les ressources d'accompagnement étant limitées, l'embarquement est conditionné à des prérequis techniques et ou organisationnels [prérequis](/platform/compatibility) pour embarquer sur l'offre Cloud π Native de façon sereine et optimale. + +Typiquement, l'équipe doit être dans un parcours de montée en compétences à l'agilité et à la conteneurisation/Kubernetes. + +## Embarquement technique + +Un parcours technique d'apprentissage permettant de valider les prérequis et d'intégrer les bonnes pratiques permet à nos clients d'appréhender l'offre Cloud π Native. + +![parcours_apprentissage](/img/learning-process.png) + +- Étape 1 : [Matrice de compétences](/platform/skills-matrix) Des technologies à connaître pour utiliser l'offre Cloud π Native +- Étape 2 : vérification de l'éligibilité de son application avec le modèle Cloud Native Application [prérequis](/platform/compatibility) technique liée à l'offre. Les équipes Cloud π Native [accompagnent](/agreement/support) les équipes projets sur cette étape afin d'apporter conseils et qualification des architectures et maturité technique des équipes. +- Étape 3 : prise de connaissance des [bonnes pratiques](/guide/best-practices) et expérimentation avec une série de tutoriels [tutoriels](/guide/tutorials) afin de faire ses premiers pas avec l'offre +- Étape 4 : [Embarquement](/guide/get-started) de l'application sur l'offre +- Étape 5 : félicitations ! Vous êtes maintenant un utilisateur de la plateforme Cloud π Native et votre application peut passer en production via les principes d'[exploitation et observabilité](/agreement/exploitation) de vos projets. + +À tout moment, vous pouvez consulter la [documentation détaillée](/platform/introduction) de la plateforme Cloud π Native, son architecture et les services proposés. + +Enfin notre [FAQ](/agreement/faq) permet de lister les questions fréquentes de nos clients, et des exemples pour réaliser des bouchons (S3, SMTP, ...). + +## Contact + +Pour toute information ou demande, veuillez nous contacter à l'adresse suivante : . Nous vous recontacterons au plus vite dès la réception du mail. +Si vous faites déjà parti des beta testeurs et que vous souhaitez poser des questions ou avoir de l'accompagnement, veuillez nous contacter directement via le serveur Mattermost prévu à cet effet (si vous n'avez pas été ajouté au serveur Mattermost, veuillez contacter l'adresse mail précédente). diff --git a/cloud-pi-native/agreement/observability.md b/cloud-pi-native/agreement/observability.md new file mode 100644 index 0000000..1b621eb --- /dev/null +++ b/cloud-pi-native/agreement/observability.md @@ -0,0 +1,41 @@ +# Observabilité + +> __:warning: L'observabilité n'est pas en place sur les environnements OVH.__ + +Dans le cadre de l'offre Cloud-Pi Native, l'observabilité est disponible via plusieurs composants: +- Prometheus/Grafana pour les métriques +- AlertManager/Grafana pour l'alerting +- ElasticSearch/Kibana pour les logs + +Ces différents services sont accessibles via la console `Cloud Pi Native > Projet > Mes Projets > Sélectionner un projet > Mes Services` + +![observabilité](/img/agreement/acces_services_observabilité.png) + +## Métrique +[Prometheus](https://grafana.com/products/cloud/metrics/) est utilisé pour récupérer, stocker et visualiser (via [Grafana](https://grafana.com/grafana/)) les métriques d'infrastructure ainsi qu'applicative. + +> __:warning: Les métriques sont disponibles pendant un an sur les environnements de production et quelques mois pour les environnements hors production.__ + +Pour apprendre à utiliser ce service, [cliquer ici](/guide/metrics) + +## Alerting +[AlertManager](https://grafana.com/docs/grafana/latest/alerting/fundamentals/alertmanager/) est utilisé pour gérer les différentes alertes de vos projets. + +Par défaut, aucune alerte n'est mise en place. + +Pour apprendre à créer une alerte, [cliquer ici](/guide/alerting.md) + +## Logs +Le couple Elastisearch/Kibana est utilisé pour vous donner accès à vos logs. + +> __:warning: Les logs ne sont conservés que sur une durée de 7 jours.__ + +Pour les besoins de conservation au delà de 7 jours, le projet doit mettre en place un collecteur de logs (rsyslog, fluentbit, fluentd, vector, kafka, ...) dans le périmètre de son application afin de récupérer le flux de logs et les stockés sur un autre support (S3 par exemple) + +Les logs peuvent être transmises via le protocol HTTP, syslog ou vers un kafka. + +Pour bénéficier de ce service, merci de créer un ticket auprès de la ServiceTeam. + +Pour apprendre à utiliser kibana, [cliquer ici](/guide/logs-kibana.md) + +Un exemple de mise en place d'un collecteur de log avec le produit [vector](https://vector.dev/) vers un bucket AWS S3 est disponible [ici](/guide/archive-logs.md) diff --git a/cloud-pi-native/agreement/support.md b/cloud-pi-native/agreement/support.md new file mode 100644 index 0000000..352eb4f --- /dev/null +++ b/cloud-pi-native/agreement/support.md @@ -0,0 +1,77 @@ +# Processus accompagnement Service Team + +## Introduction + +La Service Team est l'équipe qui vous accompagne pour embarquer sur l'offre Cloud π native. Cet accompagnement a pour objectif d'__aider les projets, les faire monter en compétences mais de ne pas faire à leur place__. En effet, une fois que les projets sont déployés sur l'offre Cloud π native, l'exploitation, le MCO/MCS reste de la responsabilité du projet qui doit comprendre l'esprit de la plateforme, les technologies sous jacentes et les paradigmes de déploiement. L'offre Cloud π native favorise le modéle DevSecOps ** ou Build it, You Run it** + +L'accompagnement technique se fera sur 2 plateformes : + +- Plateforme d'accélération OVH; plateforme non liée aux réseaux interministères et a pour objectif de fournir aux projets un accès plus rapide à la console et aux services Cloud π native. Ainsi les projets peuvent anticiper en effectuant leurs premiers tests. + +- Cluster Cloud π native sur les infrastructures du ministère de l'intérieur + +## Prérequis organisationnels + +Avant d'utiliser l'offre Cloud π native, il est nécessaire : +- De suivre le processus d'accompagnement [haut niveau](https://github.com/cloud-pi-native/embarquement-autoformation) + +## Prérequis techniques + +En plus de ces prérequis, les éléments suivants sont à fournir par le projet : +- Vérifier que les [prérequis techniques](/platform/compatibility) ainsi que [les bonnes pratiques](/guide/best-practices) sont bien en place +- Vérifier que la [matrice de compétences](/platform/skills-matrix) est connue +- Exigences du [Cadre de Cohérence Technique](https://github.com/cloud-pi-native/cct-cloud-native) +- Vérifier les contraintes de nom DNS : les applications doivent-elles obligatoirement être en *.gouv.fr ou *.interieur.gouv.fr ? +- Dossier d'architecture ou à minima schéma d'architecture technique : nombre de composants, technologies, maturité sur les technologies DSO, notamment docker / kubernetes / openshift / déploiement ArgoCD (gitops), backend de stockage (postgres, S3, etc.) +- Elements de volumétrie en termes de données et d'utilisateurs +- Si une reprise de données est à prévoir et la volumétrie associée +- Processus de sauvegarde et restauration demandé et/ou prévues par l'application +- Procédure de création de la base de données (portée par l'application / manuel) +- Liste des composants externes au projet et appelés par l'application pour évaluer les ouvertures de flux: + - Internes MI / RIE + - Sur Internet +- Exposition de l'application (Internet/Intranet/RIE/DR/NP) +- Nombre d'environnements prévus +- Nom de domaine et certificats à fournir par environnement +- Estimation des ressources nécessaires CPU/RAM +- Calendrier du projet et échéances importantes et état d'avancement du projet (déjà en production, nouvelle application, etc.) + +## Accompagnement sur OVH + +- Création de compte pour l'accès à la console et aux services +- Accostage entre la chaine primaire et la chaine secondaire (github action) +- Contruction des images Docker +- Prise en main de la console : + - Intégration des projets applicatifs et construction de la chaine de construction sur DSO (gitlab-ci-dso) + - Intégration des repos d'infra et intégation sur ArgoCD + - Accès aux éléments de monitoring + +## Accompagnement sur Cloud π + +Identique à l'accompagnement sur OVH plus : +- Ouverture de flux +- Adaptation des triggers de déploiement sur l'environnement Cloud π native + +## Outils de communication + +Pour contacter la Service Team, plusieurs moyens sont mis en place : +- Un outil de ticketing (moyen privilégié car permet de tracer les demandes) +- Un outil de discussion en ligne: Mattermost + +## Ticketing + +Pour une meilleure traçabilité des échanges, nous avons mis en place un outil de ticketing permettant aux projets de faire des demandes ou de remonter des incidents à la Service Team. + +- Voici le lien pour s'y rendre: . + +## Mattermost + +Pour une meilleure fluidité des échanges, nous avons également mis en place un tchat dont voici l'[URL](https://mattermost.fabrique-numerique.fr/) + +## Le processus d'embarquement + +Le processus d'embarquement classique d'un projet est présenté ci-dessous : + +![processus embarquement](/img/onboarding-process.png) + +> A chaque étape, la vérification des prérequis est un point d'étape *obligatoire* permettant de valider la compatibilité du projet avec l'offre DSO. diff --git a/cloud-pi-native/best-practices/kyverno.md b/cloud-pi-native/best-practices/kyverno.md new file mode 100644 index 0000000..bca636c --- /dev/null +++ b/cloud-pi-native/best-practices/kyverno.md @@ -0,0 +1,34 @@ +# Règles Kyverno appliquées aux clusters + +Kyverno est un moteur de politiques conçu pour Kubernetes. + +Ces politiques peuvent valider, muter, générer et nettoyer les ressources Kubernetes, ainsi que vérifier les signatures d'images et les artefacts pour aider à sécuriser la chaîne d'approvisionnement des logiciels. + +Dans le cadre de l'offre de services du MIOM, les règles suivantes sont appliquées sur les clusters que nous opérons : + +| Kyverno Rules | ValidationFailure Action (Dev, preprod) | ValidationFailure Action (Prod) | Information importantes | Severité | Type | description | +| -------------------------- | --------------------------------------- | ------------------------------- | ----------------------------------------------------------------------------------------------- | ------------------------- | -------- |------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| add-velero-label | | | |low | Backup | Ajoute une étiquette sur le namespace pour être sauvegardé par Velero | +| add-netpol-allowsame-ns | | | | low | Multi-Tenancy, NetworkPolicy | Autorise le pod à communiquer dans le même namespace | +| add-netpol-deny | | | | low | Multi-Tenancy, NetworkPolicy | Refuse toute communication entrante vers les pods dans un namespace | +| add-netpol-ingress | | | | low | Multi-Tenancy, NetworkPolicy | Autorise la communication entrante depuis le namespace openshift-ingress vers tous les pods dans un nouveau namespace créé | +| add-netpol-logging | | | | low | Multi-Tenancy, NetworkPolicy | Autorise la communication entrante depuis le namespace openshift-logging vers tous les pods dans un nouveau namespace créé | +| add-ttl | | | | medium | Best Practices | Ajoute un time to live (TTL) aux JOB dans le cluster, ce qui les conduit à être automatiquement nettoyés après une certaine période de temps | +| check-labels | AUDIT | ENFORCE | Labels requis : app, env, tier | low | Best Practices | Cette règle garantit que toutes les ressources ont les étiquettes nécessaires appliquées aux pod | +| cm-no-credentials | AUDIT | ENFORCE | data non autorisée : password, passwd, secret_key | medium | Pod Security Standards (Baseline) | Empêche le stockage des informations d'identification dans les ConfigMaps, ce qui est une mauvaise pratique d'un point de vue sécurité | +| disallow-exec | ENFORCE | ENFORCE | | high | Pod Security Standards (Baseline) | Empêche l'utilisation de la commande "exec" sur le namespace openshift-etcd pour des raisons de sécurité | +| disallow-latest | AUDIT | ENFORCE | | medium | Pod Security Standards (Baseline) | Les Pods n'utilisent pas la balise 'latest' pour leurs images, encourageant l'utilisation de balises versionnées spécifiques | +| disallow-hostpath | AUDIT | ENFORCE | | high | Pod Security Standards (Baseline) | Empêche l'utilisation des volumes hostPath, qui peuvent être un risque de sécurité s'ils ne sont pas correctement contrôlés | +| disallow-selfprovisionning | AUDIT | ENFORCE | | high | Pod Security Standards (Baseline) | Empêche la liaison au rôle de self-provisionners pour un contrôle strict de la création de projet OpenShift | +| etcd | ENFORCE | ENFORCE | | high | Pod Security Standards (Baseline) | Assure que le chiffrement est activé pour etcd dans les clusters OpenShift | +| limit-size-pvc | AUDIT | ENFORCE | pvc < 1Ti | low | Best Practices | Limite la taille des revendications de volume persistant (PVC) pour éviter l'utilisation excessive des ressources de stockage | +| need-containers-ressources | AUDIT | ENFORCE | limits.memory, limits.cpu, request.memory et request.cpu | medium | Best Practices | Assure que les demandes de ressources et les limites sont définies pour tous les Pods, pour assurer une utilisation équitable des ressources | +| restrict-image-registry | AUDIT | ENFORCE | registres autorisés : docker.io/, harbor.io/, registry.redhat.io/, quay.io/, bitnami/, ghcr.io/ | medium | Pod Security Standards (Baseline) | Restreint les registres d'images à partir desquels les conteneurs peuvent tirer des images, comme mesure de sécurité pour assurer l'utilisation d'images de confiance uniquement | +| restrict-nodeport | AUDIT | ENFORCE | | medium | Pod Security Standards (Baseline) | Restreint l'utilisation des services NodePort, qui peuvent exposer des services à l'extérieur du cluster et représenter un risque de sécurité potentiel | <<>> | +| need-liveness-readiness | AUDIT | ENFORCE | | medium | Best Practices | Assure que tous les conteneurs ont l'une des trois sondes (Liveness, Readiness ou Startup), pour s'assurer qu'ils signalent correctement leur statut à Openshift | +| job-history | AUDIT | ENFORCE | | low | Best Practices | Cronjob: ajoute les propriétés `successfulJobsHistoryLimit: 5` et `failedJobsHistoryLimit: 5` | + +Explication de la difference entre ENFORCE et AUDIT : +- Enforce : Kyverno bloquera l'action (par exemple, la création, la mise à jour ou la suppression d'une ressource) si la politique n'est pas respectée. Cela garantit que toutes les ressources du cluster respectent les politiques mises en place. + +- Audit: Une action d'Audit ne bloquera pas une action si la politique n'est pas respectée, mais elle enregistrera l'infraction dans les résultats d'audit de Kyverno. C'est utile pour observer les infractions aux politiques sans bloquer les actions, ce qui peut être particulièrement utile dans les environnements de développement ou de test. diff --git a/cloud-pi-native/best-practices/labels-list.md b/cloud-pi-native/best-practices/labels-list.md new file mode 100644 index 0000000..cae4463 --- /dev/null +++ b/cloud-pi-native/best-practices/labels-list.md @@ -0,0 +1,77 @@ +# Labélisation des ressources kubernetes + +Dans le cadre de l'offre de services du MIOM, il sera demandé d'ajouter les labels suivants sur vos ressources kubernetes : + +## Type d'environnement + +Ajouter un label `env: ` où `element` est un élément de la liste suivante : + +- dev +- formation +- qualif +- test +- preprod +- prod + +## Tiers + +Ajouter un label `tier: ` où `element` est un élément de la liste suivante : + +- frontend +- backend +- db +- cache +- auth + +## Criticité + +Ajouter un label `criticality: ` où `element` est un élément de la liste suivante : + +- high +- medium +- low + +## Composant + +Ajouter un label `component: ` où `element` est un élément de la liste suivante : + +- web : + - nginx + - apache + - caddy + - tomcat + +- defaults : + - python + - node + - openjdk + - golang + - php + - ruby + - perl + - drupal + - java + +- database : + - postgres + - mariadb + - mysql + - mongo + - cassandra + - cockroach + - influx + - etcd + +- caching : + - varnish + - redis + - memcached + +- broker : + - rabbitmq + - kafka + - apachemq + - kubemq + +- others : + - busybox diff --git a/cloud-pi-native/certification/introduction.md b/cloud-pi-native/certification/introduction.md new file mode 100644 index 0000000..bde4ca0 --- /dev/null +++ b/cloud-pi-native/certification/introduction.md @@ -0,0 +1,114 @@ +# Certification Cloud Pi Native (work-in-progress) + +L'effet recherché de Cloud Pi Native est de : produire des applications de qualité qui répondent au besoin, en soutenant l'agilité, la culture et les principes visant l'autonomie et centrés sur l'usage. + +Plusieurs populations sont visées par le produit Cloud Pi Native et la doctrine Cloud au Centre : + * les **équipes intégrées** qui utilisent le produit Cloud Pi Native au quotidien + * comprendre le cadre d'autonomie, les opportunités et contraintes de Cloud Pi Native, apportés par l'utilisation de Cloud Pi Native & le Cadre de Cohérence Technique Intermistériel + * être sensibilisé aux références du Software CraftSmanship + * connaitre l'éco-systeme kubernetes + * les **"DevSecOps/SRE/Champions/enabling team"** (terme à définir) au service de ou des équipes intégrées, qui accompagnent, coachent, supervisent leurs pratiques DevSecOps et Cloud Native + * Mettre les équipes intégrées dans un cycle d'amélioration continue des projets + * Être orienté sur le partage et la montée en compétence collective + * mettre en place la culture de l'excellence et les pratiques DevSecOps au sein des équipes intégrées + * assurer le provisionnement des infrastructures et pipeline, le flux et la stabilité de la solution + * démontrer sa maitrise sur des prérequis techniques d'intégration et d'exploitabilité d'application + * les **concepteurs d'application** cloud native (opportunité k8s, vs organique qui le maintiendra) +Ce programme de certification soutient l'effet recherché et s'adresse aux experts en charge d'accompagner, de coacher et de superviser les pratiques DevSecOps et Cloud Native ("DevSecOps/SRE/Champions/enabling team") au service des équipes intégrées en charge de la réalisation de produits numériques. + +**Les compétences et savoir-faires attendus** +Pour les équipes intégrées + * comprendre le cadre d'autonomie, les opportunités et contraintes de Cloud Pi Native, apportés par l'utilisation de Cloud Pi Native & le Cadre de Cohérence Technique Intermistériel + * être sensibiliser aux références du Software CraftSmanship + * connaitre l'éco-systeme kubernetes + +Pour les "DevSecOps/SRE/Champions/enabling team" +* Mettre les équipes intégrées dans une cycle d'amélioration continue des projets +* Être orienté sur le partage et la montée en compétence collective +* s'assurer de la +* mettre en place la culture de l'excellence et les pratiques DevSecOps au sein des équipes intégrées +* assurer le provisionnement des infrastructures et pipeline, le flux et la stabilité de la solution +* démontrer sa maitrise sur des prérequis techniques d'intégration et d'exploitabilité d'application + +**Les modalités de certification** +Prérequis : +* la certification est soumise à un prérequis d'obtention de la Certified Kubernetes Application Developer de la Linux Foundation, permettant de garantir la bonne maitrise de kubernetes en tant que développeur + +Promotion : +* Des promotions de 20 personnes sont organisées 2 à 3 fois par an par Cloud Pi Native. Veuillez contacter cloudpinative-relations@interieur.gouv.fr pour enregistrer votre candidature. + +Type d'examen : +* l'examen est réalisé en présentiel sur Paris, à ce jour. +* La durée de l'examen varie entre 2 & 4 heures +* Le passage d'examen et la certification sont individuels, sous la supervision d'un représentant Cloud Pi Native +* L'examen est composé de 2 volets : + * technique : des mises en situation et lab seront soumis. + * culture générale & process : un questionnaire sera soumis, permettant de vérifier votre bonne compréhension des processus clés et des normes à prendre en compte lors du cycle de vie du projet et de l'application + Chaque lab réalisé avec succès et réponse exacte octroient des points. + +Condition d'obtention : +* un score minumum de 80% est nécessaire pour l'obtention de la certification Cloud Pi Native - "DevSecOps/SRE/Champions/enabling team" (nom à définir) + +------------- + +Le matériel pédagogique proposé en open-source permet simultanément de former les experts et également ainsi que leurs fournir des outils permettant d'aider à définir le plan d'accompagnement et de formation des équipes *enabling*. + +L'évaluation prend en charge la compétence nécessaire à soutenir l'usage de l'offre Cloud native et l'agilité mais ne couvre pas le cadre méthodologique ou les certifications techniques tel que kubernetes, helm, argoCG, etc... ce sont de. + +La certification "Cloud Pi Native" est remise par le ministère de l'Intérieur ou via les entités qui ont reçus l'acréditation pour le faire. La certification est remise sous la forme d'un mail et d'un badge numérique. +Elle est pour l'instant valable pour un an. + +Si vous êtes intéressé, avez des questions et/ou suggestion, contactez-nous à: + + +**Dans ce repository vous trouverez un article qui présente l'ensemble des compétences requises:** + +- Les fondamentaux à connaitre pour mettre en oeuvre et maintenir dans le temps des applications de qualité qui répondent aux besoins; +- mettre en place l'amélioration continue et le refactoring; +- softskill et approche pour accompagner les les équipes de développement; +- connaissance du CCT Cloud Pi native et des exigences applicables; +- compréhension de l'offre de service Cloud Pi Native et le parcours de contractualisation; +- compréhension et utilisation de la chaine de construction applicative; +- comment contribuer à l'offre pull request et faire un feedback. + +Ce repository référence les capacités et messages clés à transmettre mais ne référence par les contenus détaillés. +Les experts se forment avec les programmes de leur choix, ils doivent juste être connaissant ou compétent sur les thèmes cités. + +A toutes fin utiles : une base de connaissance et d'embarquement en open-source "Cloud Native" est disponible sur : . C'est également une aide pour monter des parcours. + +**Les messages clés, le contexte et la vision:** + +Cloud Pi Native est un programme d'ensemble du ministère de l'Intérieur et des Outres-mer pour produire un numérique de qualité, soutenable dans la durée au coup de possession optimisé et qui répond au besoin. +L'objectif visé est de soutenir la production de produits logiciels de qualité, en réduisant la xharge de travail de l'équipe pour le construire, facilement évolutif et maintenable dans le temps avec un coût de possession optimisé tout en répondant au besoin en ce centrant sur l'usager. + +Ce qui est structurant : l'utilisation exclusive de Kubernetes pour l'orchestration de conteuneurs,le modèle opérationnel "you built it, you run it" et la mise en disposition en open-source de l'ensemble des ressources sauf portion sensible. + +L'hébergement du service peut-être effectué soit via l'offre interministériel Cloud Pi, soit sur un cloud public si le niveau de sensbilité des données le permet ainsi que l'absence de conflit de normes juridiques entre les CGU de l'hébergeur avec les réglementations française et européennes. + +**Le programme d'ensemble Cloud Pi Native inclus :** + +- une architecture applicative de référence facilitant la construction et l'homologation des applications +- un pipeline DevSecOps à 2 étapes permettant à un développeur de construire et déployer en continue une application sur les environnements ministériel ou vers un cloud public depuis son environnement de travail pouvant être situé sur internet +- une console et une infrastructure automatisée permettant une mise à disposition rapide des ressources d'insfrastructures au profil d'un hébergement sur le cloud Pi du ministère. +- un cadre de cohérence technique dédié à cette offre, comprenant un référentiel d'exigences à respecter +- un programme de formation d'ensemble du ministère, au cloud, à l'agilité, au mode produit, dont une valise de fomation et de référencement de ressources majoritairement gratuite permettant la montée en connaissance des acteurs +- un programme de certification, l'objet de ce repository permettant de valider les acquis de compétence dans l'objectif de répartir la connaissance auprès des développeurs et des entreprise de service numérique. + +**Dans le cadre de la certification nous recrutons des volontaires pour:** +- la production et/ou la critique des éléments de contenu pédagogique +- le cadre d'évaluation et le tutorat des coachs +- élaborer un test d'auto-évaluation qui sera accessible à tous. + +Le rythme de production de la certification est réalisée en incrément de planning tout les 2,5 mois environ. +Synchronisé avec la production de l'offre elle-même. + Signalez-vous par les fonctions collaboratives de GitHub. + +Nous sommes à votre écoute pour toute suggestion, critique et apport de contenu. + +Bien à vous, l'équipe Cloud Pi Native ;) + +Définitions : + +*Enabling team* est défini au sein du livre *Team Topologies* cf. : +Selon les organisation, ces équipes peuvent parfois s'appeler équipes DevOps ou par abus de langage *SRE*, si inclusion d'une activité SysAdmin. +Le terme SRE est un terme spécifique à l'organisation Google cf diff --git a/cloud-pi-native/contribute.md b/cloud-pi-native/contribute.md new file mode 100644 index 0000000..331a954 --- /dev/null +++ b/cloud-pi-native/contribute.md @@ -0,0 +1,32 @@ +# Contribution au projet Cloud π Native + +Merci de nous aider à améliorer la plateforme de services Cloud π Native. L'ensemble des composants est publié en licence ouverte et le projet dans son ensemble est ouvert à contribution. + +## Notre engagement + +Dans l'intérêt de favoriser un environnement ouvert et accueillant, nous, en tant que contributeurs et mainteneurs, nous engageons à faire de la participation à notre projet et à notre communauté une expérience sans harcèlement pour tous, quels que soient l'âge, la taille, le handicap, l'origine ethnique, l'identité et l'expression de genre, niveau d'expérience, nationalité, apparence personnelle, race, religion ou identité et orientation sexuelles. + +## Liste des ressources + +Le projet Cloud π Native est constitué d'un ensemble de repos github suivant : + + - Applicatifs : + - Console de la plateforme : + - Installation de la plateforme : + - Documentation: + - Cadre de cohérence technique Cloud native du ministère de l'intérieur + - Présentation fonctionnelle de l'offre Cloud π Native + - Documentation utilisateur de l'offre Cloud π Native + - tutoriels: + - Application de démo Java à construire sur l'offre Cloud π Native + - Application de démo de contenu statique à construire sur l'offre Cloud π Native + - Déploiement par helm chart de l'application de démo Java + - Déploiement par fichiers de manifests de l'application de démo Java + - Déploiement par helm chart de l'application de démo de contenu statique + - Déploiement par fichiers de manifests de l'application de démo de contenu statique + - Déploiement par helm chart dans un context de monorepo (code + helm dans le même repo) + - Tutorial GitOps + +## Contribution + +Pour contribuer au projet, vous pouvez, sur chacune des ressources ci-dessous créer une *issue* github, par exemple pour le projet de [documentation](https://github.com/cloud-pi-native/documentation/issues) diff --git a/cloud-pi-native/faq/introduction.md b/cloud-pi-native/faq/introduction.md new file mode 100644 index 0000000..f5a8feb --- /dev/null +++ b/cloud-pi-native/faq/introduction.md @@ -0,0 +1,219 @@ +# Foire aux questions + +Cette section regroupe les questions fréquentes de nos clients. + +## Construction + +### Comment simuler les services S3, SSO, SMTP, etc sur les environnements OVH ? + +Des bouchons sont proposés afin de simuler un serveur SMTP, création d'un bucket S3, SSO, etc. + +La description de l'utilisation de ces bouchons est détaillée [ici](/agreement/mocks) + +### Comment puis-je lancer la pipeline de synchronisation de mes repos depuis mes repos externes ? + +Pour synchroniser le code tu peux suivre la procédure suivante. +Sur GitLab: + +- Aller sur ton projet +- Aller sur le dépôt mirror +- Dans la barre latérale gauche Build > Pipelines +- Cliquer en haut à droite de l'écran sur Run pipeline +- Ajouter comme valeur pour la variable PROJECT_NAME le nom du dépôt (dans le GitLab) que tu souhaites synchroniser +- Ajouter la variable GIT_BRANCH_DEPLOY avec comme valeur la branche que tu souhaites synchroniser +- Cliquer sur Run pipeline + +Sur argocd, dans App Details: +- il faut que tu changes le cluster de destination pour app1-integ (Selectionnez name pour voir le nom du cluster plutôt que URL). +- Vérifier la valeur de la la clé Path (path des manifests k8s). + +### Comment puis-je déployer une image personnalisée ? + +Toutes les images déployées sur la plateforme Cloud π Native doivent : + - Etre construite par l'offre + - Faire partie des repo publics autorisés par exemple Bitnami (règle non encore mise en place) + +Afin de construire une image personnalisée, il est nécessaire de créer un Dockerfile dans son repo de sources applicative et d'intégrer la construction de cette image dans l'étape de construction de l'application. + +Extrait du gitlab-ci-dso.yml +```yaml +build_docker_custom: + variables: + WORKING_DIR: images + IMAGE_NAME: image_custom_to_build + DOCKERFILE: Dockerfile-custom + stage: build-docker + extends: + - .kaniko:build +``` + +Fichier images/Dockerfile-custom dans le répertoire +```dockerfile +FROM alpine:edge + +WORKDIR /tmp +RUN apk upgrade --update-cache --available +[...] +CMD [ "command_to_execute"] +``` + +### Puis-je pousser directement un binaire non construit par l'offre Cloud π Native ? + +Toutes les images et librairies utilisées sur la plateforme doivent être construites par la chaine DSO ou être disponibles sur les repos publics dont l'auteur est reconnu et autorisé (par exemple bitnami). + +Il n'est pas possible d'uploader un binaire directement sur le gestionnaire d'artefacts (Nexus) en dehors de la chaine de construction DSO. + +Ainsi, il est possible d'utiliser une image non construite sur DSO, par exemple, bitnami/postgresql, en revanche il est interdit d'utiliser my-nickname/postgresql ni de faire un docker push d'une image construite sur son poste. + +### Quelles sont les contraintes génériques d'Openshift par rapport à Kubernetes ? + +- Les images doivent être rootless +- Le root filesystem des images doit être en lecture seule à l'exception et seul les répertoire /tmp et /var/tmp sont en écriture +- Les ports d'écoute des PODs doivent être supérieurs à 1024 + +### J'ai une erreur de récupération des dépendances Java via Maven à cause d'un problème de certificat SSL: + +Cette erreur apparait lors des appels internes au cluster qui ne reconnait pas les certificats présentés: + +Message d'erreur : +``` +proxy: ProxyInfo{host='192.168.xx.xx', userName='null', port=3128, type='http', nonProxyHosts='null'} @ line 82, column 25: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target -> [Help 2] +``` +Solution : +Ajouter dans le fichier .gitlab-ci.dso.yml la variable MAVEN_CLI_OPTS pour ignorer les erreurs de certificats + +```yaml +package-app: + variables: + BUILD_IMAGE_NAME: maven:3.8-openjdk-17 + WORKING_DIR: . + ARTEFACT_DIR: target + MAVEN_OPTS: -Dmaven.repo.local=$CI_PROJECT_DIR/.m2/repository + MAVEN_CLI_OPTS: " -Dmaven.wagon.http.ssl.insecure=true " + MVN_CONFIG_FILE: $MVN_CONFIG + stage: package-app + extends: + - .java:build +``` + +## Déploiement + +### Comment déployer une base postgreSQL via manifests ? + +Le fichier manifest suivant présente le déploiement d'un service [PostgreSQL](/examples/postgres.yaml) à partir d'une image bitnami. Il peut servir de base pour un déploiement manuel d'une instance PostgreSQL. Pour un déploiement plus complexe, par exemple avec une gestion du clustering, il est préférable d'utiliser un déploiement par chart Helm pour par opérateur. + +### Comment déployer une base postgreSQL via un chart Helm ? + +L'utilisation de chart Helm est une autre solution pour déployer une base de données PostgreSQL pour son application. Helm permet de déclarer des dépendances vers d'autres charts Helm existants. Ainsi, il est possible de packager son application sous la forme d'un chart Helm et de déclarer une dépendances vers un chart de base de données postgreSQL. + +Voici un exemple de déclaration de dépendances vers le chart Helm de PostgreSQL de Bitnami : +```yaml +dependencies: + - name: postgresql + version: 12.2.2 + repository: "https://charts.bitnami.com/bitnami" +``` + +la configuration de chart Helm se fait + +Un exemple complet est présent sur le tutoriel de déploiement [dso-tuto-java-helm](https://github.com/cloud-pi-native/tuto-java-infra-helm.git) + +### Comment déployer une base postgreSQL via un opérateur ? + +## Exploitation + +Questions concernant l'exploitabilité et l'observabilité des applications + +### Comment puis-je déployer un backup postgreSQL à façon ? + +Pour créer un backup "fonctionnel" sur une base postgres en plus des backup proposés par l'offre DSO, il est possible de procéder comme suit : +Création d'un CronJob avec 2 pods partageant le même volume : + - Un container (initContainer) à partir d'une image postgres se connectant au service de base de données et réalisant le dump + - Un container récupérant le dump et l'envoyant sur un stockage S3. + +Création d'un script d'upload de backup vers un stockage S3 (monté comme configMap) +```sh +#!/bin/sh + +now=`date +"%Y_%m_%d_%H%M%S"` +year=`date +"%Y"` +day=`date +"%d"` +month=`date +"%m"` + +for f in /backup/*.pgdump; do + if test -f "$f"; then + echo "upload file $f to s3://$BUCKET_NAME/${f}-${now}" + + aws --no-verify-ssl s3 cp $f s3://$BUCKET_NAME/${f}-${now} --endpoint-url https://${BUCKET_HOST}:${BUCKET_PORT} + + fi +done +``` + +Exemple de CronJob +```yaml +apiVersion: batch/v1 +kind: CronJob +metadata: + name: postgres-backup + namespace: my-namespace +spec: + schedule: "0 6 * * *" # Tous les jours à 6h00 du matin + # [..] + jobTemplate: + spec: + # [..] + template: + spec: + initContainers: + - name: dump + image: postgres:12.1-alpine + volumeMounts: + - name: data + mountPath: /backup + args: [pg_dump, -Fc, -f, /backup/backup.pgdump, -h, postgresql-svc] + env: + - name: PGPASSWORD + valueFrom: + secretKeyRef: + name: db-secret + key: POSTGRES_PASSWORD + containers: + - name: s3 + image: mesosphere/aws-cli + volumeMounts: + - name: data + mountPath: /backup + - name: config-volume + mountPath: /backup-script + envFrom: + - configMapRef: + name: env-backup-S3 + command: [/backup-script/backup-s3.sh] + restartPolicy: Never + volumes: + - name: config-volume + configMap: + name: backup-s3.sh + - name: data + emptyDir: {} +``` + +### Comment tester mon container en lecture seul ? + +Afin de simuler la contraite de lecture seul d'openshift sur le container, il est possible de lancer le container en mode **read_only** via la commande docker suivantes: +```sh +docker run — read-only [image-name] +``` + +ou via docker compose avec le yaml suivant : +```yaml +version: "3.9" +services: + example: + image: [image-name] + read_only: true +``` +### Comment puis-je accéder aux logs de mon application ? + +### Comment puis-je accéder aux métriques de mon application ? diff --git a/cloud-pi-native/index.md b/cloud-pi-native/index.md new file mode 100644 index 0000000..088c423 --- /dev/null +++ b/cloud-pi-native/index.md @@ -0,0 +1,29 @@ +--- +layout: home +hero: + name: Cloud π Native + text: Ministère de l'Intérieur et des Outre-mer + tagline: L'offre de service Cloud π Native permet aux administrations françaises de gérer le cycle de vie de leurs applications tout en bénéficiant d'un hébergement sur le Cloud π. + actions: + - theme: brand + text: Documentation de la plateforme Hexaforge + link: http://localhost:8081 + - theme: alt + text: Voir sur GitHub + link: https://github.com/cloud-pi-native +features: + - title: L'offre de services + details: Convention de services à destinations des administrations ou leurs partenaires numériques + link: /agreement/introduction + - title: Certification + details: Tout savoir sur la certification Cloud π Native + link: /certification/introduction + - title: La plateforme d'accélération + details: Découvrez comment utiliser la plateforme d'accélération exposée sur internet + link: /acceleration/introduction + - title: Les bonnes pratiques + details: Liste des bonnes pratiques à appliquer lors de l'utilisation de l'offre + link: /best-practices/kyverno + - title: F.A.Q + details: Des questions ? Voici des réponses aux questions les plus courantes + link: /faq/introduction diff --git a/cloud-pi-native/public/examples/postgres.yaml b/cloud-pi-native/public/examples/postgres.yaml new file mode 100644 index 0000000..fcf45ad --- /dev/null +++ b/cloud-pi-native/public/examples/postgres.yaml @@ -0,0 +1,71 @@ +--- +apiVersion: v1 +kind: PersistentVolumeClaim # Create PVC +metadata: + namespace: mynamespace + name: postgresql-data-claim # Sets name of PV +spec: + accessModes: + - ReadWriteOnce # Sets read and write access + resources: + requests: + storage: 1Gi # Sets volume size +--- +apiVersion: v1 +kind: Service +metadata: + namespace: mynamespace + name: postgres # Sets service name + labels: + app: postgres # Labels and Selectors +spec: + type: ClusterIP # Sets service type + ports: + - port: 5432 # Sets port to run the postgres application + selector: + app: postgres +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: mynamespace + name: postgres-demo # Sets Deployment name +spec: + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + app: postgres + template: + metadata: + labels: + app: postgres + spec: + containers: + - name: postgres + image: bitnami/postgresql:14.9.0 + imagePullPolicy: IfNotPresent + ports: + - containerPort: 5432 # Exposes container port + env: + - name: POSTGRES_USER + value: demo_user + - name: POSTGRES_PASSWORD + value: "My$ecrETPAss0rd*" + - name: POSTGRES_DB + value: demo + - name: POSTGRESQL_DATABASE + value: demo + volumeMounts: + - mountPath: /bitnami/postgresql + name: postgredb + resources: + limits: + memory: 512Mi + cpu: 500m + restartPolicy: Always + volumes: + - name: postgredb + persistentVolumeClaim: + claimName: postgresql-data-claim diff --git a/cloud-pi-native/public/favicon.ico b/cloud-pi-native/public/favicon.ico new file mode 100644 index 0000000..d5b9b0f Binary files /dev/null and b/cloud-pi-native/public/favicon.ico differ diff --git "a/cloud-pi-native/public/img/agreement/acces_services_observabilit\303\251.png" "b/cloud-pi-native/public/img/agreement/acces_services_observabilit\303\251.png" new file mode 100644 index 0000000..cbc7e77 Binary files /dev/null and "b/cloud-pi-native/public/img/agreement/acces_services_observabilit\303\251.png" differ diff --git a/cloud-pi-native/public/img/architecture.png b/cloud-pi-native/public/img/architecture.png new file mode 100644 index 0000000..932f597 Binary files /dev/null and b/cloud-pi-native/public/img/architecture.png differ diff --git a/cloud-pi-native/public/img/argocd-example.png b/cloud-pi-native/public/img/argocd-example.png new file mode 100644 index 0000000..5f3e6c8 Binary files /dev/null and b/cloud-pi-native/public/img/argocd-example.png differ diff --git a/cloud-pi-native/public/img/argocd.png b/cloud-pi-native/public/img/argocd.png new file mode 100644 index 0000000..e078eb3 Binary files /dev/null and b/cloud-pi-native/public/img/argocd.png differ diff --git a/cloud-pi-native/public/img/console_admin/cluster_ajout.png b/cloud-pi-native/public/img/console_admin/cluster_ajout.png new file mode 100644 index 0000000..45b5242 Binary files /dev/null and b/cloud-pi-native/public/img/console_admin/cluster_ajout.png differ diff --git a/cloud-pi-native/public/img/console_admin/cluster_details_env.png b/cloud-pi-native/public/img/console_admin/cluster_details_env.png new file mode 100644 index 0000000..7d08c61 Binary files /dev/null and b/cloud-pi-native/public/img/console_admin/cluster_details_env.png differ diff --git a/cloud-pi-native/public/img/console_admin/cluster_liste.png b/cloud-pi-native/public/img/console_admin/cluster_liste.png new file mode 100644 index 0000000..d8db5b1 Binary files /dev/null and b/cloud-pi-native/public/img/console_admin/cluster_liste.png differ diff --git a/cloud-pi-native/public/img/console_admin/cluster_suppression.png b/cloud-pi-native/public/img/console_admin/cluster_suppression.png new file mode 100644 index 0000000..3881090 Binary files /dev/null and b/cloud-pi-native/public/img/console_admin/cluster_suppression.png differ diff --git a/cloud-pi-native/public/img/console_admin/create_org.png b/cloud-pi-native/public/img/console_admin/create_org.png new file mode 100644 index 0000000..1df05a5 Binary files /dev/null and b/cloud-pi-native/public/img/console_admin/create_org.png differ diff --git a/cloud-pi-native/public/img/console_admin/environnement_creation.png b/cloud-pi-native/public/img/console_admin/environnement_creation.png new file mode 100644 index 0000000..dcfd3c8 Binary files /dev/null and b/cloud-pi-native/public/img/console_admin/environnement_creation.png differ diff --git a/cloud-pi-native/public/img/console_admin/journaux_erreur.png b/cloud-pi-native/public/img/console_admin/journaux_erreur.png new file mode 100644 index 0000000..223ace1 Binary files /dev/null and b/cloud-pi-native/public/img/console_admin/journaux_erreur.png differ diff --git a/cloud-pi-native/public/img/console_admin/menu_admin.png b/cloud-pi-native/public/img/console_admin/menu_admin.png new file mode 100644 index 0000000..e092cfe Binary files /dev/null and b/cloud-pi-native/public/img/console_admin/menu_admin.png differ diff --git a/cloud-pi-native/public/img/console_admin/plugin_configuration.png b/cloud-pi-native/public/img/console_admin/plugin_configuration.png new file mode 100644 index 0000000..8f30681 Binary files /dev/null and b/cloud-pi-native/public/img/console_admin/plugin_configuration.png differ diff --git a/cloud-pi-native/public/img/console_admin/projet_detail.png b/cloud-pi-native/public/img/console_admin/projet_detail.png new file mode 100644 index 0000000..13ef6e2 Binary files /dev/null and b/cloud-pi-native/public/img/console_admin/projet_detail.png differ diff --git a/cloud-pi-native/public/img/console_admin/quota_creation.png b/cloud-pi-native/public/img/console_admin/quota_creation.png new file mode 100644 index 0000000..5ae568a Binary files /dev/null and b/cloud-pi-native/public/img/console_admin/quota_creation.png differ diff --git a/cloud-pi-native/public/img/console_admin/recherche_projet.png b/cloud-pi-native/public/img/console_admin/recherche_projet.png new file mode 100644 index 0000000..d794163 Binary files /dev/null and b/cloud-pi-native/public/img/console_admin/recherche_projet.png differ diff --git a/cloud-pi-native/public/img/console_admin/recherche_utilisateurs.png b/cloud-pi-native/public/img/console_admin/recherche_utilisateurs.png new file mode 100644 index 0000000..dac8c48 Binary files /dev/null and b/cloud-pi-native/public/img/console_admin/recherche_utilisateurs.png differ diff --git a/cloud-pi-native/public/img/console_admin/zone_creation.png b/cloud-pi-native/public/img/console_admin/zone_creation.png new file mode 100644 index 0000000..86d9627 Binary files /dev/null and b/cloud-pi-native/public/img/console_admin/zone_creation.png differ diff --git a/cloud-pi-native/public/img/creation.png b/cloud-pi-native/public/img/creation.png new file mode 100644 index 0000000..fc74f50 Binary files /dev/null and b/cloud-pi-native/public/img/creation.png differ diff --git a/cloud-pi-native/public/img/environnement/cluster-env.png b/cloud-pi-native/public/img/environnement/cluster-env.png new file mode 100644 index 0000000..66b491f Binary files /dev/null and b/cloud-pi-native/public/img/environnement/cluster-env.png differ diff --git a/cloud-pi-native/public/img/environnement/create-env.png b/cloud-pi-native/public/img/environnement/create-env.png new file mode 100644 index 0000000..3dab74e Binary files /dev/null and b/cloud-pi-native/public/img/environnement/create-env.png differ diff --git a/cloud-pi-native/public/img/environnement/menu.png b/cloud-pi-native/public/img/environnement/menu.png new file mode 100644 index 0000000..891dfb3 Binary files /dev/null and b/cloud-pi-native/public/img/environnement/menu.png differ diff --git a/cloud-pi-native/public/img/environnement/quota-env.png b/cloud-pi-native/public/img/environnement/quota-env.png new file mode 100644 index 0000000..3ad96f7 Binary files /dev/null and b/cloud-pi-native/public/img/environnement/quota-env.png differ diff --git a/cloud-pi-native/public/img/environnement/type-env.png b/cloud-pi-native/public/img/environnement/type-env.png new file mode 100644 index 0000000..2192230 Binary files /dev/null and b/cloud-pi-native/public/img/environnement/type-env.png differ diff --git a/cloud-pi-native/public/img/gitlab-ci-read-secrets.png b/cloud-pi-native/public/img/gitlab-ci-read-secrets.png new file mode 100644 index 0000000..8e5d15c Binary files /dev/null and b/cloud-pi-native/public/img/gitlab-ci-read-secrets.png differ diff --git a/cloud-pi-native/public/img/gitlab-ci-vault.png b/cloud-pi-native/public/img/gitlab-ci-vault.png new file mode 100644 index 0000000..b230970 Binary files /dev/null and b/cloud-pi-native/public/img/gitlab-ci-vault.png differ diff --git a/cloud-pi-native/public/img/gitlab.png b/cloud-pi-native/public/img/gitlab.png new file mode 100644 index 0000000..dfa91c2 Binary files /dev/null and b/cloud-pi-native/public/img/gitlab.png differ diff --git a/cloud-pi-native/public/img/gitlab.svg b/cloud-pi-native/public/img/gitlab.svg new file mode 100644 index 0000000..602ffcc --- /dev/null +++ b/cloud-pi-native/public/img/gitlab.svg @@ -0,0 +1 @@ +GitLab home page \ No newline at end of file diff --git a/cloud-pi-native/public/img/gitops.png b/cloud-pi-native/public/img/gitops.png new file mode 100644 index 0000000..8c310d8 Binary files /dev/null and b/cloud-pi-native/public/img/gitops.png differ diff --git a/cloud-pi-native/public/img/global-vision.png b/cloud-pi-native/public/img/global-vision.png new file mode 100644 index 0000000..63bdaae Binary files /dev/null and b/cloud-pi-native/public/img/global-vision.png differ diff --git a/cloud-pi-native/public/img/guide/alerting/alert_firing.png b/cloud-pi-native/public/img/guide/alerting/alert_firing.png new file mode 100644 index 0000000..7b31a53 Binary files /dev/null and b/cloud-pi-native/public/img/guide/alerting/alert_firing.png differ diff --git a/cloud-pi-native/public/img/guide/alerting/alert_ns_group.png b/cloud-pi-native/public/img/guide/alerting/alert_ns_group.png new file mode 100644 index 0000000..e3a8d42 Binary files /dev/null and b/cloud-pi-native/public/img/guide/alerting/alert_ns_group.png differ diff --git a/cloud-pi-native/public/img/guide/alerting/contact_point_create.png b/cloud-pi-native/public/img/guide/alerting/contact_point_create.png new file mode 100644 index 0000000..c63224c Binary files /dev/null and b/cloud-pi-native/public/img/guide/alerting/contact_point_create.png differ diff --git a/cloud-pi-native/public/img/guide/alerting/contact_point_manager.png b/cloud-pi-native/public/img/guide/alerting/contact_point_manager.png new file mode 100644 index 0000000..6238e28 Binary files /dev/null and b/cloud-pi-native/public/img/guide/alerting/contact_point_manager.png differ diff --git a/cloud-pi-native/public/img/guide/alerting/create_alert_step_1.png b/cloud-pi-native/public/img/guide/alerting/create_alert_step_1.png new file mode 100644 index 0000000..5540ec4 Binary files /dev/null and b/cloud-pi-native/public/img/guide/alerting/create_alert_step_1.png differ diff --git a/cloud-pi-native/public/img/guide/alerting/create_alert_step_2.png b/cloud-pi-native/public/img/guide/alerting/create_alert_step_2.png new file mode 100644 index 0000000..fb34276 Binary files /dev/null and b/cloud-pi-native/public/img/guide/alerting/create_alert_step_2.png differ diff --git a/cloud-pi-native/public/img/guide/alerting/create_alert_step_3.png b/cloud-pi-native/public/img/guide/alerting/create_alert_step_3.png new file mode 100644 index 0000000..b6aad0c Binary files /dev/null and b/cloud-pi-native/public/img/guide/alerting/create_alert_step_3.png differ diff --git a/cloud-pi-native/public/img/guide/alerting/create_alert_step_4.png b/cloud-pi-native/public/img/guide/alerting/create_alert_step_4.png new file mode 100644 index 0000000..9667ca8 Binary files /dev/null and b/cloud-pi-native/public/img/guide/alerting/create_alert_step_4.png differ diff --git a/cloud-pi-native/public/img/guide/alerting/create_alert_step_5.png b/cloud-pi-native/public/img/guide/alerting/create_alert_step_5.png new file mode 100644 index 0000000..39e8787 Binary files /dev/null and b/cloud-pi-native/public/img/guide/alerting/create_alert_step_5.png differ diff --git a/cloud-pi-native/public/img/guide/alerting/notification_policies.png b/cloud-pi-native/public/img/guide/alerting/notification_policies.png new file mode 100644 index 0000000..42e3dfe Binary files /dev/null and b/cloud-pi-native/public/img/guide/alerting/notification_policies.png differ diff --git a/cloud-pi-native/public/img/guide/alerting/notification_policy_nested_create.png b/cloud-pi-native/public/img/guide/alerting/notification_policy_nested_create.png new file mode 100644 index 0000000..85043c6 Binary files /dev/null and b/cloud-pi-native/public/img/guide/alerting/notification_policy_nested_create.png differ diff --git a/cloud-pi-native/public/img/guide/alerting/policy_default.png b/cloud-pi-native/public/img/guide/alerting/policy_default.png new file mode 100644 index 0000000..6e425f5 Binary files /dev/null and b/cloud-pi-native/public/img/guide/alerting/policy_default.png differ diff --git a/cloud-pi-native/public/img/guide/dashboard_infra.png b/cloud-pi-native/public/img/guide/dashboard_infra.png new file mode 100644 index 0000000..0701e41 Binary files /dev/null and b/cloud-pi-native/public/img/guide/dashboard_infra.png differ diff --git a/cloud-pi-native/public/img/guide/grafana-sign-in.png b/cloud-pi-native/public/img/guide/grafana-sign-in.png new file mode 100644 index 0000000..0ddfb82 Binary files /dev/null and b/cloud-pi-native/public/img/guide/grafana-sign-in.png differ diff --git a/cloud-pi-native/public/img/guide/grafana_add_visualization.png b/cloud-pi-native/public/img/guide/grafana_add_visualization.png new file mode 100644 index 0000000..963e6b1 Binary files /dev/null and b/cloud-pi-native/public/img/guide/grafana_add_visualization.png differ diff --git a/cloud-pi-native/public/img/guide/grafana_create_alert.png b/cloud-pi-native/public/img/guide/grafana_create_alert.png new file mode 100644 index 0000000..ed892f4 Binary files /dev/null and b/cloud-pi-native/public/img/guide/grafana_create_alert.png differ diff --git a/cloud-pi-native/public/img/guide/grafana_dashboard_save.png b/cloud-pi-native/public/img/guide/grafana_dashboard_save.png new file mode 100644 index 0000000..ec481b0 Binary files /dev/null and b/cloud-pi-native/public/img/guide/grafana_dashboard_save.png differ diff --git a/cloud-pi-native/public/img/guide/grafana_dashboard_submenu.png b/cloud-pi-native/public/img/guide/grafana_dashboard_submenu.png new file mode 100644 index 0000000..ae2c9bb Binary files /dev/null and b/cloud-pi-native/public/img/guide/grafana_dashboard_submenu.png differ diff --git a/cloud-pi-native/public/img/guide/grafana_first_dashboard.png b/cloud-pi-native/public/img/guide/grafana_first_dashboard.png new file mode 100644 index 0000000..a462335 Binary files /dev/null and b/cloud-pi-native/public/img/guide/grafana_first_dashboard.png differ diff --git a/cloud-pi-native/public/img/guide/grafana_first_visualization.png b/cloud-pi-native/public/img/guide/grafana_first_visualization.png new file mode 100644 index 0000000..4e1be9a Binary files /dev/null and b/cloud-pi-native/public/img/guide/grafana_first_visualization.png differ diff --git a/cloud-pi-native/public/img/guide/grafana_first_visualization_metrics.png b/cloud-pi-native/public/img/guide/grafana_first_visualization_metrics.png new file mode 100644 index 0000000..614edf1 Binary files /dev/null and b/cloud-pi-native/public/img/guide/grafana_first_visualization_metrics.png differ diff --git a/cloud-pi-native/public/img/guide/grafana_first_visualization_option.png b/cloud-pi-native/public/img/guide/grafana_first_visualization_option.png new file mode 100644 index 0000000..2c5898d Binary files /dev/null and b/cloud-pi-native/public/img/guide/grafana_first_visualization_option.png differ diff --git a/cloud-pi-native/public/img/guide/grafana_first_visualization_time_window.png b/cloud-pi-native/public/img/guide/grafana_first_visualization_time_window.png new file mode 100644 index 0000000..a3b5f03 Binary files /dev/null and b/cloud-pi-native/public/img/guide/grafana_first_visualization_time_window.png differ diff --git a/cloud-pi-native/public/img/guide/grafana_list_dashboard_final.png b/cloud-pi-native/public/img/guide/grafana_list_dashboard_final.png new file mode 100644 index 0000000..6c1f975 Binary files /dev/null and b/cloud-pi-native/public/img/guide/grafana_list_dashboard_final.png differ diff --git a/cloud-pi-native/public/img/guide/grafana_menu.png b/cloud-pi-native/public/img/guide/grafana_menu.png new file mode 100644 index 0000000..b32644c Binary files /dev/null and b/cloud-pi-native/public/img/guide/grafana_menu.png differ diff --git a/cloud-pi-native/public/img/guide/grafana_menu_alerting.png b/cloud-pi-native/public/img/guide/grafana_menu_alerting.png new file mode 100644 index 0000000..35a8cd0 Binary files /dev/null and b/cloud-pi-native/public/img/guide/grafana_menu_alerting.png differ diff --git a/cloud-pi-native/public/img/guide/grafana_menu_dashboard.png b/cloud-pi-native/public/img/guide/grafana_menu_dashboard.png new file mode 100644 index 0000000..bafe7f7 Binary files /dev/null and b/cloud-pi-native/public/img/guide/grafana_menu_dashboard.png differ diff --git a/cloud-pi-native/public/img/guide/grafana_new_dashboard.png b/cloud-pi-native/public/img/guide/grafana_new_dashboard.png new file mode 100644 index 0000000..aed97f5 Binary files /dev/null and b/cloud-pi-native/public/img/guide/grafana_new_dashboard.png differ diff --git a/cloud-pi-native/public/img/guide/grafana_visualization_save.png b/cloud-pi-native/public/img/guide/grafana_visualization_save.png new file mode 100644 index 0000000..acaa886 Binary files /dev/null and b/cloud-pi-native/public/img/guide/grafana_visualization_save.png differ diff --git a/cloud-pi-native/public/img/guide/kibana/authorize.png b/cloud-pi-native/public/img/guide/kibana/authorize.png new file mode 100644 index 0000000..8e5b6d0 Binary files /dev/null and b/cloud-pi-native/public/img/guide/kibana/authorize.png differ diff --git a/cloud-pi-native/public/img/guide/kibana/create_index_pattern.png b/cloud-pi-native/public/img/guide/kibana/create_index_pattern.png new file mode 100644 index 0000000..87f1a3b Binary files /dev/null and b/cloud-pi-native/public/img/guide/kibana/create_index_pattern.png differ diff --git a/cloud-pi-native/public/img/guide/kibana/create_index_timestamp.png b/cloud-pi-native/public/img/guide/kibana/create_index_timestamp.png new file mode 100644 index 0000000..ad29366 Binary files /dev/null and b/cloud-pi-native/public/img/guide/kibana/create_index_timestamp.png differ diff --git a/cloud-pi-native/public/img/guide/kibana/create_index_valid.png b/cloud-pi-native/public/img/guide/kibana/create_index_valid.png new file mode 100644 index 0000000..2a48b98 Binary files /dev/null and b/cloud-pi-native/public/img/guide/kibana/create_index_valid.png differ diff --git a/cloud-pi-native/public/img/guide/kibana/discover.png b/cloud-pi-native/public/img/guide/kibana/discover.png new file mode 100644 index 0000000..3633ad5 Binary files /dev/null and b/cloud-pi-native/public/img/guide/kibana/discover.png differ diff --git a/cloud-pi-native/public/img/guide/kibana/discover_available_fields.png b/cloud-pi-native/public/img/guide/kibana/discover_available_fields.png new file mode 100644 index 0000000..d2a2615 Binary files /dev/null and b/cloud-pi-native/public/img/guide/kibana/discover_available_fields.png differ diff --git a/cloud-pi-native/public/img/guide/kibana/discover_query.png b/cloud-pi-native/public/img/guide/kibana/discover_query.png new file mode 100644 index 0000000..9f3afe5 Binary files /dev/null and b/cloud-pi-native/public/img/guide/kibana/discover_query.png differ diff --git a/cloud-pi-native/public/img/guide/kibana/discover_results.png b/cloud-pi-native/public/img/guide/kibana/discover_results.png new file mode 100644 index 0000000..8439338 Binary files /dev/null and b/cloud-pi-native/public/img/guide/kibana/discover_results.png differ diff --git a/cloud-pi-native/public/img/guide/kibana/discover_time.png b/cloud-pi-native/public/img/guide/kibana/discover_time.png new file mode 100644 index 0000000..f025d1c Binary files /dev/null and b/cloud-pi-native/public/img/guide/kibana/discover_time.png differ diff --git a/cloud-pi-native/public/img/guide/kibana/log-in.png b/cloud-pi-native/public/img/guide/kibana/log-in.png new file mode 100644 index 0000000..6c31310 Binary files /dev/null and b/cloud-pi-native/public/img/guide/kibana/log-in.png differ diff --git a/cloud-pi-native/public/img/guide/kibana_authorize_access.png b/cloud-pi-native/public/img/guide/kibana_authorize_access.png new file mode 100644 index 0000000..439b36a Binary files /dev/null and b/cloud-pi-native/public/img/guide/kibana_authorize_access.png differ diff --git a/cloud-pi-native/public/img/guide/kibana_login_openshift.png b/cloud-pi-native/public/img/guide/kibana_login_openshift.png new file mode 100644 index 0000000..2400de3 Binary files /dev/null and b/cloud-pi-native/public/img/guide/kibana_login_openshift.png differ diff --git a/cloud-pi-native/public/img/guide/project/create_project.png b/cloud-pi-native/public/img/guide/project/create_project.png new file mode 100644 index 0000000..ef20265 Binary files /dev/null and b/cloud-pi-native/public/img/guide/project/create_project.png differ diff --git a/cloud-pi-native/public/img/guide/project/monprojet_secrets.png b/cloud-pi-native/public/img/guide/project/monprojet_secrets.png new file mode 100644 index 0000000..c49b541 Binary files /dev/null and b/cloud-pi-native/public/img/guide/project/monprojet_secrets.png differ diff --git a/cloud-pi-native/public/img/guide/project/monprojet_tableaudebord.png b/cloud-pi-native/public/img/guide/project/monprojet_tableaudebord.png new file mode 100644 index 0000000..71fd76a Binary files /dev/null and b/cloud-pi-native/public/img/guide/project/monprojet_tableaudebord.png differ diff --git a/cloud-pi-native/public/img/guide/project/monprojettuile.png b/cloud-pi-native/public/img/guide/project/monprojettuile.png new file mode 100644 index 0000000..15f5f13 Binary files /dev/null and b/cloud-pi-native/public/img/guide/project/monprojettuile.png differ diff --git a/cloud-pi-native/public/img/guide/repository_synchro.png b/cloud-pi-native/public/img/guide/repository_synchro.png new file mode 100644 index 0000000..1030ab9 Binary files /dev/null and b/cloud-pi-native/public/img/guide/repository_synchro.png differ diff --git a/cloud-pi-native/public/img/learning-process.png b/cloud-pi-native/public/img/learning-process.png new file mode 100644 index 0000000..774ef75 Binary files /dev/null and b/cloud-pi-native/public/img/learning-process.png differ diff --git a/cloud-pi-native/public/img/mocks/add-repo.png b/cloud-pi-native/public/img/mocks/add-repo.png new file mode 100644 index 0000000..9308fb6 Binary files /dev/null and b/cloud-pi-native/public/img/mocks/add-repo.png differ diff --git a/cloud-pi-native/public/img/mocks/mocks-argo-app-details.png b/cloud-pi-native/public/img/mocks/mocks-argo-app-details.png new file mode 100644 index 0000000..fe7efe4 Binary files /dev/null and b/cloud-pi-native/public/img/mocks/mocks-argo-app-details.png differ diff --git a/cloud-pi-native/public/img/mocks/mocks-argo-parameters.png b/cloud-pi-native/public/img/mocks/mocks-argo-parameters.png new file mode 100644 index 0000000..5c1ce1a Binary files /dev/null and b/cloud-pi-native/public/img/mocks/mocks-argo-parameters.png differ diff --git a/cloud-pi-native/public/img/mocks/mocks-argo.png b/cloud-pi-native/public/img/mocks/mocks-argo.png new file mode 100644 index 0000000..f585db6 Binary files /dev/null and b/cloud-pi-native/public/img/mocks/mocks-argo.png differ diff --git a/cloud-pi-native/public/img/nexus.png b/cloud-pi-native/public/img/nexus.png new file mode 100644 index 0000000..809e5fb Binary files /dev/null and b/cloud-pi-native/public/img/nexus.png differ diff --git a/cloud-pi-native/public/img/onboarding-process.png b/cloud-pi-native/public/img/onboarding-process.png new file mode 100644 index 0000000..a1ff773 Binary files /dev/null and b/cloud-pi-native/public/img/onboarding-process.png differ diff --git a/cloud-pi-native/public/img/repo-sync-01.png b/cloud-pi-native/public/img/repo-sync-01.png new file mode 100644 index 0000000..2209920 Binary files /dev/null and b/cloud-pi-native/public/img/repo-sync-01.png differ diff --git a/cloud-pi-native/public/img/repo-sync-02.png b/cloud-pi-native/public/img/repo-sync-02.png new file mode 100644 index 0000000..f2a8f2b Binary files /dev/null and b/cloud-pi-native/public/img/repo-sync-02.png differ diff --git a/cloud-pi-native/public/img/sonarqube.svg b/cloud-pi-native/public/img/sonarqube.svg new file mode 100644 index 0000000..cee213d --- /dev/null +++ b/cloud-pi-native/public/img/sonarqube.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/cloud-pi-native/public/img/team/add.png b/cloud-pi-native/public/img/team/add.png new file mode 100644 index 0000000..11876ef Binary files /dev/null and b/cloud-pi-native/public/img/team/add.png differ diff --git a/cloud-pi-native/public/img/team/members.png b/cloud-pi-native/public/img/team/members.png new file mode 100644 index 0000000..1ff5cd0 Binary files /dev/null and b/cloud-pi-native/public/img/team/members.png differ diff --git a/cloud-pi-native/public/img/team/menu.png b/cloud-pi-native/public/img/team/menu.png new file mode 100644 index 0000000..6867b7e Binary files /dev/null and b/cloud-pi-native/public/img/team/menu.png differ diff --git a/cloud-pi-native/public/img/team/permission-environnement.png b/cloud-pi-native/public/img/team/permission-environnement.png new file mode 100644 index 0000000..c8aac8a Binary files /dev/null and b/cloud-pi-native/public/img/team/permission-environnement.png differ diff --git a/cloud-pi-native/public/img/tuto/1tuto-connexion.png b/cloud-pi-native/public/img/tuto/1tuto-connexion.png new file mode 100644 index 0000000..a57fb5b Binary files /dev/null and b/cloud-pi-native/public/img/tuto/1tuto-connexion.png differ diff --git a/cloud-pi-native/public/img/tuto/2tuto-acces-services.png b/cloud-pi-native/public/img/tuto/2tuto-acces-services.png new file mode 100644 index 0000000..7985660 Binary files /dev/null and b/cloud-pi-native/public/img/tuto/2tuto-acces-services.png differ diff --git a/cloud-pi-native/public/img/tuto/2tuto-commander-projet.png b/cloud-pi-native/public/img/tuto/2tuto-commander-projet.png new file mode 100644 index 0000000..bbe1f4f Binary files /dev/null and b/cloud-pi-native/public/img/tuto/2tuto-commander-projet.png differ diff --git a/cloud-pi-native/public/img/tuto/2tuto-creer-projet-termine.png b/cloud-pi-native/public/img/tuto/2tuto-creer-projet-termine.png new file mode 100644 index 0000000..ab3e77e Binary files /dev/null and b/cloud-pi-native/public/img/tuto/2tuto-creer-projet-termine.png differ diff --git a/cloud-pi-native/public/img/tuto/2tuto-creer-projet.png b/cloud-pi-native/public/img/tuto/2tuto-creer-projet.png new file mode 100644 index 0000000..19ec9a0 Binary files /dev/null and b/cloud-pi-native/public/img/tuto/2tuto-creer-projet.png differ diff --git a/cloud-pi-native/public/img/tuto/2tuto-mes-projets.png b/cloud-pi-native/public/img/tuto/2tuto-mes-projets.png new file mode 100644 index 0000000..4f55c27 Binary files /dev/null and b/cloud-pi-native/public/img/tuto/2tuto-mes-projets.png differ diff --git a/cloud-pi-native/public/img/tuto/3tuto-depots-ajouter-gitlab-ci.png b/cloud-pi-native/public/img/tuto/3tuto-depots-ajouter-gitlab-ci.png new file mode 100644 index 0000000..46cfcb8 Binary files /dev/null and b/cloud-pi-native/public/img/tuto/3tuto-depots-ajouter-gitlab-ci.png differ diff --git a/cloud-pi-native/public/img/tuto/3tuto-depots-ajouter-ok.png b/cloud-pi-native/public/img/tuto/3tuto-depots-ajouter-ok.png new file mode 100644 index 0000000..60a72f8 Binary files /dev/null and b/cloud-pi-native/public/img/tuto/3tuto-depots-ajouter-ok.png differ diff --git a/cloud-pi-native/public/img/tuto/3tuto-depots-ajouter.png b/cloud-pi-native/public/img/tuto/3tuto-depots-ajouter.png new file mode 100644 index 0000000..c22b745 Binary files /dev/null and b/cloud-pi-native/public/img/tuto/3tuto-depots-ajouter.png differ diff --git a/cloud-pi-native/public/img/tuto/3tuto-depots.png b/cloud-pi-native/public/img/tuto/3tuto-depots.png new file mode 100644 index 0000000..50a6405 Binary files /dev/null and b/cloud-pi-native/public/img/tuto/3tuto-depots.png differ diff --git a/cloud-pi-native/public/img/tuto/3tuto-environnement.png b/cloud-pi-native/public/img/tuto/3tuto-environnement.png new file mode 100644 index 0000000..2fbe27d Binary files /dev/null and b/cloud-pi-native/public/img/tuto/3tuto-environnement.png differ diff --git a/cloud-pi-native/public/img/tuto/4argocd-app-details.png b/cloud-pi-native/public/img/tuto/4argocd-app-details.png new file mode 100644 index 0000000..2c3bef3 Binary files /dev/null and b/cloud-pi-native/public/img/tuto/4argocd-app-details.png differ diff --git a/cloud-pi-native/public/img/tuto/4argocd-menus-bouton.png b/cloud-pi-native/public/img/tuto/4argocd-menus-bouton.png new file mode 100644 index 0000000..5498d0f Binary files /dev/null and b/cloud-pi-native/public/img/tuto/4argocd-menus-bouton.png differ diff --git a/cloud-pi-native/public/img/tuto/4argocd-menus.png b/cloud-pi-native/public/img/tuto/4argocd-menus.png new file mode 100644 index 0000000..bde2b41 Binary files /dev/null and b/cloud-pi-native/public/img/tuto/4argocd-menus.png differ diff --git a/cloud-pi-native/public/img/tuto/4argocd.png b/cloud-pi-native/public/img/tuto/4argocd.png new file mode 100644 index 0000000..58c47f7 Binary files /dev/null and b/cloud-pi-native/public/img/tuto/4argocd.png differ diff --git a/cloud-pi-native/public/img/tuto/etat-services.png b/cloud-pi-native/public/img/tuto/etat-services.png new file mode 100644 index 0000000..e0d0ac6 Binary files /dev/null and b/cloud-pi-native/public/img/tuto/etat-services.png differ diff --git a/cloud-pi-native/public/img/vault.svg b/cloud-pi-native/public/img/vault.svg new file mode 100644 index 0000000..0eeb10f --- /dev/null +++ b/cloud-pi-native/public/img/vault.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/cloud-pi-native/public/img/vision.png b/cloud-pi-native/public/img/vision.png new file mode 100644 index 0000000..da0ca55 Binary files /dev/null and b/cloud-pi-native/public/img/vision.png differ diff --git a/cloud-pi-native/public/logo-marianne-gouvernement.png b/cloud-pi-native/public/logo-marianne-gouvernement.png new file mode 100644 index 0000000..786e3d6 Binary files /dev/null and b/cloud-pi-native/public/logo-marianne-gouvernement.png differ diff --git a/hexaforge/.vitepress/config.ts b/hexaforge/.vitepress/config.ts new file mode 100644 index 0000000..8dedb79 --- /dev/null +++ b/hexaforge/.vitepress/config.ts @@ -0,0 +1,42 @@ +import { defineConfig } from 'vitepress' +import sidebar from './sidebar.json' assert { type: 'json'} + +export default defineConfig({ + base: '/', + lang: 'fr-FR', + title: 'Hexaforge', + description: 'Documentation de la plateforme Hexaforge', + cleanUrls: true, + themeConfig: { + nav: [ + { text: 'Contribuer', link: '/contribute' }, + ], + outline: [2, 3], + sidebar, + socialLinks: [ + { icon: 'github', link: 'https://github.com/cloud-pi-native/documentation' } + ], + search: { + provider: 'local', + options: { + translations: { + button: { + buttonText: 'Rechercher...', + buttonAriaLabel: 'Rechercher' + }, + modal: { + backButtonTitle: 'effacer la recherche', + displayDetails: 'afficher les détails', + noResultsText: 'Aucun résultat pour ', + resetButtonTitle: 'annuler la recherche', + footer: { + selectText: 'aller à ce texte', + navigateText: 'naviguer dans les résultats', + closeText: 'fermer' + } + } + }, + } + }, + }, +}) diff --git a/hexaforge/.vitepress/sidebar.json b/hexaforge/.vitepress/sidebar.json new file mode 100644 index 0000000..9f3f7af --- /dev/null +++ b/hexaforge/.vitepress/sidebar.json @@ -0,0 +1,196 @@ +[ + { + "text": "La plateforme", + "collapsed": true, + "items": [ + { + "text": "Introduction", + "link": "/platform/introduction" + }, + { + "text": "Compatibilité", + "link": "/platform/compatibility" + }, + { + "text": "Matrice de compétences", + "link": "/platform/skills-matrix" + }, + { + "text": "Les services", + "collapsed": true, + "items": [ + { + "text": "Gestion des sources", + "link": "/services/gitlab" + }, + { + "text": "Gestion des artefacts", + "link": "/services/artefacts" + }, + { + "text": "Analyse qualité", + "link": "/services/sonarqube" + }, + { + "text": "Gestion des secrets", + "link": "/services/vault" + }, + { + "text": "Gestion du déploiement", + "link": "/services/gitops" + } + ] + }, + { + "text": "Feuille de route", + "link": "/platform/roadmap" + }, + { + "text": "Glossaire", + "link": "/platform/glossary" + } + ] + }, + { + "text": "Guide d'installation", + "collapsed": true, + "items": [ + { + "text": "Introduction", + "link": "/installation/introduction" + }, + { + "text": "Prérequis", + "link": "/installation/prerequisites" + }, + { + "text": "Configuration", + "link": "/installation/configuration" + }, + { + "text": "Installation", + "link": "/installation/installation" + }, + { + "text": "Secrets", + "link": "/installation/secrets" + }, + { + "text": "Debug", + "link": "/installation/debug" + }, + { + "text": "Désinstallation", + "link": "/installation/uninstallation" + }, + { + "text": "Gel des versions", + "link": "/installation/versions" + } + ] + }, + { + "text": "Guide d'utilisation", + "collapsed": true, + "items": [ + { + "text": "Démarrer", + "link": "/guide/get-started" + }, + { + "text": "Gestion des projets", + "link": "/guide/projects-management" + }, + { + "text": "Gestion des équipes", + "link": "/guide/team" + }, + { + "text": "Gestion des dépôts", + "link": "/guide/repositories-management" + }, + { + "text": "Gestion des environnements", + "link": "/guide/environments-management" + }, + { + "text": "Gestion des secrets", + "link": "/guide/secrets-management" + }, + { + "text": "Déploiement de votre application", + "link": "/guide/deployment-with-argo" + }, + { + "text": "Bonnes pratiques", + "link": "/guide/best-practices" + }, + { + "text": "Métriques", + "link": "/guide/metrics" + }, + { + "text": "Alerting", + "link": "/guide/alerting" + }, + { + "text": "Logs (Kibana)", + "link": "/guide/logs-kibana" + }, + { + "text": "Archivage des logs", + "link": "/guide/archive-logs" + }, + { + "text": "Tutoriels", + "link": "/guide/tutorials" + } + ] + }, + { + "text": "Administration de la console", + "collapsed": true, + "items": [ + { + "text": "Démarrer", + "link": "/administration/introduction" + }, + { + "text": "Utilisateurs", + "link": "/administration/utilisateurs" + }, + { + "text": "Organisations", + "link": "/administration/organisations" + }, + { + "text": "Projets", + "link": "/administration/projets" + }, + { + "text": "Jounaux", + "link": "/administration/journaux" + }, + { + "text": "Clusters", + "link": "/administration/clusters" + }, + { + "text": "Quotas", + "link": "/administration/quotas" + }, + { + "text": "Types d'environnement", + "link": "/administration/environnements" + }, + { + "text": "Zones", + "link": "/administration/zones" + }, + { + "text": "Plugins", + "link": "/administration/plugins" + } + ] + } +] diff --git a/hexaforge/.vitepress/theme/index.ts b/hexaforge/.vitepress/theme/index.ts new file mode 100644 index 0000000..914a7d8 --- /dev/null +++ b/hexaforge/.vitepress/theme/index.ts @@ -0,0 +1,5 @@ +// https://vitepress.dev/guide/custom-theme +import DefaultTheme from 'vitepress/theme' +// import './style.css' + +export default DefaultTheme diff --git a/hexaforge/.vitepress/theme/style.css b/hexaforge/.vitepress/theme/style.css new file mode 100644 index 0000000..de4f5dd --- /dev/null +++ b/hexaforge/.vitepress/theme/style.css @@ -0,0 +1,100 @@ +/** + * Customize default theme styling by overriding CSS variables: + * https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/vars.css + */ + +/** + * Colors + * -------------------------------------------------------------------------- */ + +:root { + --blue-france-sun-113: #000091; + --red-marianne-main-472: #e1000f; + + --vp-c-brand: var(--blue-france-sun-113); + --vp-c-brand-light: #6a6af4; + --vp-c-brand-lighter: #8585f6; + --vp-c-brand-lightest: #cacafb; + --vp-c-brand-dark: #313178; + --vp-c-brand-darker: #272747; + --vp-c-brand-dimm: rgba(33, 33, 63, 0.08); + +} + +/** + * Component: Button + * -------------------------------------------------------------------------- */ + +:root { + --vp-button-brand-border: var(--vp-c-brand-light); + --vp-button-brand-text: var(--vp-c-white); + --vp-button-brand-bg: var(--vp-c-brand); + --vp-button-brand-hover-border: var(--vp-c-brand-light); + --vp-button-brand-hover-text: var(--vp-c-white); + --vp-button-brand-hover-bg: var(--vp-c-brand-light); + --vp-button-brand-active-border: var(--vp-c-brand-light); + --vp-button-brand-active-text: var(--vp-c-white); + --vp-button-brand-active-bg: var(--vp-button-brand-bg); +} + +/** + * Component: Home + * -------------------------------------------------------------------------- */ + +:root { + --vp-home-hero-name-color: transparent; + --vp-home-hero-name-background: -webkit-linear-gradient( + 120deg, + var(--vp-c-brand) 30%, + var(--red-marianne-main-472) + ); + + --vp-home-hero-image-background-image: linear-gradient( + -45deg, + var(--vp-c-brand) 50%, + var(--red-marianne-main-472) + ); + --vp-home-hero-image-filter: blur(40px); +} + +@media (min-width: 640px) { + :root { + --vp-home-hero-image-filter: blur(56px); + } +} + +@media (min-width: 960px) { + :root { + --vp-home-hero-image-filter: blur(72px); + } +} + +/** + * Component: Custom Block + * -------------------------------------------------------------------------- */ + +:root { + --vp-custom-block-tip-border: var(--vp-c-brand); + --vp-custom-block-tip-text: var(--vp-c-brand-darker); + --vp-custom-block-tip-bg: var(--vp-c-brand-dimm); +} + +.dark { + --vp-c-brand: #6a6af4; + --vp-custom-block-tip-border: var(--vp-c-brand); + --vp-custom-block-tip-text: var(--vp-c-brand-lightest); + --vp-custom-block-tip-bg: var(--vp-c-brand-dimm); + --vp-home-hero-name-background: -webkit-linear-gradient( + 120deg, + var(--vp-c-brand-light) 30%, + var(--red-marianne-main-472) + ); +} + +/** + * Component: Algolia + * -------------------------------------------------------------------------- */ + +.DocSearch { + --docsearch-primary-color: var(--vp-c-brand) !important; +} diff --git a/hexaforge/administration/clusters.md b/hexaforge/administration/clusters.md new file mode 100644 index 0000000..142577e --- /dev/null +++ b/hexaforge/administration/clusters.md @@ -0,0 +1,39 @@ +# Clusters + +Un cluster est, au même titre qu'un cluster kubernetes, un ensemble de noeuds pilotés, par une solution d'orchestration (kubernetes vanille, OpenShift, Rancher, etc...) + +La console n'installe pas de cluster kubernetes à proprement parlé mais permet de piloter des projets sur différents clusters. + +## Création d'un cluster + +En appuyant sur le bouton **+ Ajouter un nouveau cluster**, une nouvelle page s'ouvre pour faire l'action idoine. + +Un exemple de remplissage des différents champs de configuration, une explication se trouvant après: +![cluster ajout](/img/console_admin/cluster_ajout.png) + +1. **Kubeconfig**: Fournir un kubeconfig sous forme de fichier texte +2. **Nom du serveur Transport Layer Security (TLS)**: information extraite du fichier kubeconfig +3. **Nom du cluster applicatif**: Nom que le cluster aura dans l'interface de la console par les utilisateurs. +4. **Informations supplémentaires sur le cluster**: Informations supplémentaires qui seront visibles par les utilisateurs, typiquement l'adresse IP des FIP +5. **Ignorer le certificat TLS du server (risques potentiels de sécurité !)**: à cocher pour désactiver la vérification du certificat TLS dans le kubeconfig +6. **Ressources cluster**: Cochez la case si des ressources de type cluster peuvent être déployées par Argocd, à réserver pour les clusters dédiés +7. **Zone associée**: Zone associée au cluster +8. **Confidentialité du cluster**: choix si le cluster est public (partagé et visible par tout le monde) ou dédié (pour un projet ou une équipe projet). En cas de cluster dédié, il sera demander de choisir les projets associés qui peuvent être déployé sur ce cluster. +9. **Nom des types d'environnement**: un cluster est lié à un certain nombre d'environnement, typiquement les environnements hors production sur un cluster et l'environnement concernant la production sur un cluster dédié +10. Cliquer sur le bouton **Ajouter le cluster** + +## Détail d'un cluster + +En cliquant sur la tuile d'un cluster, il est possible d'avoir une page détaillée concernant ce dernier. + +Les mêmes informations que lors de la création apparaissent ainsi qu'une liste des projets (environnements) associés + +![cluster détail environnement](/img/console_admin/cluster_details_env.png) + +## Suppresion d'un cluster + +Pour pouvoir supprimer un cluster, il faut se rendre sur la page de [détail d'un cluster](#detail-d-un-cluster). + +Le cluster ne doit avoir aucun projet actuellement déployé dessus. + +![cluster suppression](/img/console_admin/cluster_suppression.png) diff --git a/hexaforge/administration/environnements.md b/hexaforge/administration/environnements.md new file mode 100644 index 0000000..85a94bb --- /dev/null +++ b/hexaforge/administration/environnements.md @@ -0,0 +1,24 @@ +# Type d'environnement + +Un environnement est désigne une phase de développement du projet. Chaque environnement est lié à des quotas ainsi qu'à des clusters. + +## Création d'un environnement + +Cliquer sur le bouton **+ Ajouter un nouveau type d'environnement**. + +Un exemple de création de type d'environnement, les explication se trouvant après: +![environnement création](/img/console_admin/environnement_creation.png) + +1. **Nom du type d'environnement**: Nom de l'environnement que les utilisateurs verront dans la console (*dev dans l'exemple*) +2. **Quotas associés**: Tous les quotas possibles une fois que ce type d'environnement sera sélectionné par les utilisateurs (*small et medium dans l'exemple*) + 1. Le bouton **Ajouter tout* ajoute tous les quotas dans le type d'environnement + 2. Le bouton **Ajouter visible** ajoute tous les quotas visible par les utilisateurs (quota privé décoché) +3. **Clusters associés**: Tous les clusters disponible une fois que ce type d'environnement sera sélectionné par les utilisateurs (*formation-ovh dans l'exemple*) + +## Mise à jour et Suppression + +Pour mettre à jour un type d'evironnement, il faut sélectionner sa tuile dans la liste. + +Il est possible de modifier les quotas associés ainsi que les clusters mais pas le nom. + +Tout en bas il est possible de retrouver la liste des projets associés à ce type d'environnement. Un type d'environnement doit être libre de toute utilisation avant de pouvoir être supprimé. diff --git a/hexaforge/administration/introduction.md b/hexaforge/administration/introduction.md new file mode 100644 index 0000000..9a6a9b6 --- /dev/null +++ b/hexaforge/administration/introduction.md @@ -0,0 +1,19 @@ +# Démarrer + +Les administrateurs de la console DSO ont accès à un menu supplémentaire: + +![menu_admin](/img/console_admin/menu_admin.png) + +Ce menu d'administration permet de gérer les différents aspects de la console (utilisateurs, organisations, projets, ...), voir les journaux de la console ainsi que gérer les différents plugins installés. + +La console permet d'administrer les items suivants: + +- Utilisateurs: gestion simple des utilisateurs (la création d'un utilisateur est à faire directement sur keycloak) +- Organisations: liste des organisations, création d'une nouvelle organisation, synchronisation +- Projets: liste des projets, détail de chaque projet, verrouillage et archivage des projets +- Jounaux: liste des journaux de la console DSO pour débugger en cas de problème +- Clusters: liste des clusters, détail de chaque cluster, ajout de nouveau cluster +- Quotas: liste des quotas, détail des quotas et ajout de quota +- Types d'environnement: +- Zones +- Plugins: configuration des différents plugins utilisés par la console diff --git a/hexaforge/administration/journaux.md b/hexaforge/administration/journaux.md new file mode 100644 index 0000000..4276ef5 --- /dev/null +++ b/hexaforge/administration/journaux.md @@ -0,0 +1,29 @@ +# Journaux + +Les journaux sont essentiels pour comprendre la vie de la plateforme et apporter une réponse en cas de problème. + +Ce menu permet de voir tous les actions que la console effectue suite aux saisies utilisateurs. + +Dès qu'un problème apparait, l'entrée du journal est entourée en rouge (vert si l'action s'est correctement effectuée) avec les clés suivantes: + +```json +{ + "args": { + }, + "config": { + }, + "failed": [ + ], + "results": { + } +} +``` + +La clé args regroupe toutes les données que la console a pu récupérer sur le projet (id, nom, membres, environnements, etc). + +La clé failed contient le plugin en erreur (pour faciliter la vie de l'administrateur) + +La clé results contient les logs des différents plugins joués et donne un 1er aperçu du problème rencontré. + +Dans l'exemple suivant, le projet a un soucis d'authenfication concernant GitLab. D'expérience, il s'agit très certainement d'un clonage de dépôt privé dont les informations d'identification ont été mal renseignées. +![journaux erreur](/img/console_admin/journaux_erreur.png) diff --git a/hexaforge/administration/organisations.md b/hexaforge/administration/organisations.md new file mode 100644 index 0000000..2105b89 --- /dev/null +++ b/hexaforge/administration/organisations.md @@ -0,0 +1,29 @@ +# Organisations + +Une organisation est un moyen de regrouper plusieurs projets dans un groupement cohérent. Chaque projet appartient à une seule organisation, ainsi il est possible d'avoir plusieurs projets avec le même nom mais appartenants à des organisations différentes. + +Dans le cadre de Cloud Pi Native, les organisations sont en fait les ministères. + +Chaque organisation est identifiée par un label (ex: Ministère de l'intérieur et des outre-mer) ainsi que par un nom technique (ex: mi). + +Dans le menu Administration > Organisations, il est possible de retrouver la liste des organisations déjà créées ainsi que leur status (activée ou non). + +## Création d'une organisation + +Un formulaire est disponible en bas de page permettant de créer d'autres organisations. + +![création organisation](/img/console_admin/create_org.png) + +Le nom technique de l'organisation doit remplir les critères suivants: + +- en minuscule +- moins de 10 caractères +- sans caractère spéciaux + +Cliquer sur le bouton **Ajouter l'organisation** + +## Synchronisation des organisations + +Au lieu d'ajouter manuellement les organisations une par une, il est possible de définir une url permettant de charger les organisations depuis une source extérieure. + +Le bouton **Synchroniser les organisations** sert à synchroniser une liste d'organisations depuis une source extérieure. L'endpoint est défini directement dans le code de la console diff --git a/hexaforge/administration/plugins.md b/hexaforge/administration/plugins.md new file mode 100644 index 0000000..31e5153 --- /dev/null +++ b/hexaforge/administration/plugins.md @@ -0,0 +1,27 @@ +# Plugins + +La console DSO fonctionne via des plugins pour toutes ses fonctionnalités: + +- keycloak +- vault +- harbor +- argocd +- ... + +Il est possible d'écrire son propre plugin, un dépôt d'exemple si trouve [ici](https://github.com/cloud-pi-native/console-plugin-helloworld) + +Pour les plugins rendant service à d'autres plugins (plugin de type API - typiquement le cas du plugin vault qui sert à stocker les secrets des autres plugins), un exemple se trouve [ici](https://github.com/cloud-pi-native/console-plugin-helloworld-api) + +Chaque plugin peut exposer sa configuration à différents niveaux: + +- projet: la configuration se trouvera sur la page **Mes services** du projet en question +- global: la configuration se trouvera sur la page **Administration/Plugins** + +## Configuration globale + +Pour changer la configuration globale d'un plugin, cliquer sur le plugin en question pour ouvrir son menu de paramètres et changer celui voulu. + +Dans l'exemple suivant, le quota par défaut de harbor est mis à 1GB: +![plugin configuration](/img/console_admin/plugin_configuration.png) + +Cliquer sur le bouton **Enregistrer** pour sauvegarder la nouvelle configuration. diff --git a/hexaforge/administration/projets.md b/hexaforge/administration/projets.md new file mode 100644 index 0000000..f3a06f5 --- /dev/null +++ b/hexaforge/administration/projets.md @@ -0,0 +1,20 @@ +# Projets + +Le menu Administration > Projets permet de voir la liste de tous les projets, que ce soit les projets non archivés, archivés, verrouillés, échoués. + +Une zone de texte permet de filtrer rapidement sur les éléments suivants: + +- Nom +- Description +- Souscripteur + +![recherche projet](/img/console_admin/recherche_projet.png) + +En cliquant sur le projet concerné, une autre page s'ouvre sur laquelle les informations suivantes sont disponibles: + +- Les environnements associés au projet ainsi que leur quota +- Les dépôts (ainsi que leur type) synchronisés +- Les membres du projet et leur statut +- La configuration des plugins pour ce projet en particulier + +![projet détail](/img/console_admin/projet_detail.png) diff --git a/hexaforge/administration/quotas.md b/hexaforge/administration/quotas.md new file mode 100644 index 0000000..70cb57b --- /dev/null +++ b/hexaforge/administration/quotas.md @@ -0,0 +1,26 @@ +# Quotas + +Un quota est une limite dure (en terme de CPU et de RAM) de ce qu'un projet peut déployer sur un environnement donné. + +Dans le monde kubernetes, cela se traduit par un objet de type ResourceQuota dans le namespace. + +## Création d'un nouveau quota + +Cliquer sur le bouton **+ Ajouter un nouveau quota**, une nouvelle page s'ouvre demandant un certain nombre détail. + +Un exemple ci-dessous pour la création d'un quota, l'explication des champs se trouvant après: +![quota création](/img/console_admin/quota_creation.png) + +1. **Nom du quota**: Nom que le quota aura sur la partie cliente de la console +2. **Mémoire allouée**: Mémoire maximum que le projet pourra allouer s'il choisit ce quota +3. **CPU alloué(s)**: Nombre de CPU maximum que le projet pourra allouer s'il choisit ce quota +4. **Quota privé**: Si le quota est uniquement accessible aux administrateurs de la console +5. **Nom des types d'environnement**: A quels environnement ce quota est associé + +## Mise à jour du quota et suppression + +Pour mettre à jour un quota, il suffit de cliquer sur sa tuile dans la page principal des quotas. + +Si le quota est utilisé par des projets, la liste des projets et environnement est affichée. + +Un quota ne peut être supprimé que s'il n'a pas de projet lié. diff --git a/hexaforge/administration/utilisateurs.md b/hexaforge/administration/utilisateurs.md new file mode 100644 index 0000000..58a4b0b --- /dev/null +++ b/hexaforge/administration/utilisateurs.md @@ -0,0 +1,20 @@ +# Utilisateurs + +Dans le menu Administration > Utilisateurs il est possible de retrouver tous les utilisateurs inscrits sur la plateforme, ainsi que leur statut (utilisateur simple ou administrateur). + +> La création et la suppresion des utilisateurs est à faire directement dans keycloak. + +## Recherche + +Une fonction de recherche est disponible sur les champs suivants: + +- Identifiant +- Prénom +- Nom +- Courriel + +![recherche utilisateur](/img/console_admin/recherche_utilisateurs.png) + +## Devenir administrateur + +En cochant la case **Administrateur**, la personne choisie devient administrateur de la console DSO. diff --git a/hexaforge/administration/zones.md b/hexaforge/administration/zones.md new file mode 100644 index 0000000..8b05bf0 --- /dev/null +++ b/hexaforge/administration/zones.md @@ -0,0 +1,27 @@ +# Zones + +Une zone désigne un datacenter particulier. Dans le cadre de Cloud Pi Native, il existe 2 zones: + +- Zone Usuelle: zone pour les projets présentant une sensibilité moindre. +- Zone Restreinte: zone pour les projets sensibles, plus contraignant au niveau des flux réseaux + +L'instructure sur OVH n'est pas concerné par cette notion de zone, aussi il n'existe que le choix **Zone Défaut** + +## Création d'une zone + +Cliquer sur le bouton **+ Ajouter une nouvelle zone**. + +Un exemple de création d'une nouvelle zone, les explications se trouvant après: + +![zone creation](/img/console_admin/zone_creation.png) + +1. **Nom court de la zone**: Nom court à des fins techniques, aka un id (*pub dans l'exemple*) +2. **Nom complet de la zone**: Nom qui sera affichée dans la console à destination des utilisateurs (*Zone publique dans l'exemple*) +3. **Informations supplémentaires sur la zone**: Champ libre pour informer les utilisateurs du but de la zone (*Zone Publique de moindre sensibilité* dans l'exemple) +4. **Clusters associés**: Quels sont les clusters disponibles dans cette zone particulière ? (*dans l'exemple seul le cluster formation-ovh est associé à la zone*) + +## Mise à jour et Suppression + +Sélectionner la zone voulue via sa tuile. Le nom court d'une zone ne pourra pas être modifié étant lié à d'autres éléments techniques. + +Seule une zone sans cluster associé peut être supprimée. De même il faut que le cluster soit vide de tous projets pour pouvoir être supprimé. diff --git a/hexaforge/contribute.md b/hexaforge/contribute.md new file mode 100644 index 0000000..42e709b --- /dev/null +++ b/hexaforge/contribute.md @@ -0,0 +1,30 @@ +# Contribution au produit Hexaforge + +Merci de nous aider à améliorer la plateforme de services Hexaforge. L'ensemble des composants est publié en licence ouverte et le projet dans son ensemble est ouvert à contribution. + +## Notre engagement + +Dans l'intérêt de favoriser un environnement ouvert et accueillant, nous, en tant que contributeurs et mainteneurs, nous engageons à faire de la participation à notre projet et à notre communauté une expérience sans harcèlement pour tous, quels que soient l'âge, la taille, le handicap, l'origine ethnique, l'identité et l'expression de genre, niveau d'expérience, nationalité, apparence personnelle, race, religion ou identité et orientation sexuelles. + +## Liste des ressources + +Le projet Hexaforge est constitué d'un ensemble de repos github suivant : + +- __Applicatifs :__ + - Console de la plateforme : + - Installation de la plateforme : +- __Documentation :__ + - Documentation du produit Hexaforge +- __Tutoriels :__ + - Application de démo Java à construire sur la plateforme Hexaforge + - Application de démo de contenu statique à construire sur la plateforme Hexaforge + - Déploiement par helm chart de l'application de démo Java + - Déploiement par fichiers de manifests de l'application de démo Java + - Déploiement par helm chart de l'application de démo de contenu statique + - Déploiement par fichiers de manifests de l'application de démo de contenu statique + - Déploiement par helm chart dans un context de monorepo (code + helm dans le même repo) + - Tutorial GitOps + +## Contribution + +Pour contribuer au projet, vous pouvez, sur chacune des ressources ci-dessous créer une *issue* github, par exemple pour le projet de [documentation](https://github.com/cloud-pi-native/documentation/issues) diff --git a/hexaforge/guide/alerting.md b/hexaforge/guide/alerting.md new file mode 100644 index 0000000..d3d8e26 --- /dev/null +++ b/hexaforge/guide/alerting.md @@ -0,0 +1,115 @@ +# Alerting + +Retrouver ce service dans la console Cloud Pi via le menu `Projet > Mes Projets > Sélectionner un projet > Mes Services` et cliquer sur l'icône Grafana qui vous intéresse. + +Dans cette section, nous allons découvrir comment créer une alerte et la router vers un service web. + +## Connexion +Pour visualiser vos métriques, sélectionner Grafana dans le tableau de bord "Mes Services". + +Pour se logguer, cliquer sur le bouton en bas de page commençant par "Sign in with..." + +![signin](/img/guide/grafana-sign-in.png) + +Via la menu hamburger en haut à gauche, vous aurez accès aux dashboards. + +![menu](/img/guide/grafana_menu.png) +![menu dashboard](/img/guide/grafana_menu_alerting.png) + +## Créer une alerte +Dans le menu, sélectionner `Alert Rules`, vous retrouvez ici toutes les alertes définies. + +Pour créer une alerte, cliquer sur le bouton `Create alert rule` +![create alert](/img/guide/grafana_create_alert.png) + +Les étapes d'après expliquent les informations demandées pour créer une alerte: +- Donner un nom à son alerte +![create_alert_step_1](/img/guide/alerting/create_alert_step_1.png) + +--- +- Choisir `Mimir or Loki alert` et `Prometheus` comme datasource + +:warning: **La métrique choisie doit renvoyer vraie quand l'alerte doit être levée** :warning: + +Par exemple ici, AlertManager surveille le nombre de pod pgrest ready et s'il est inférieur à 1, cela lève l'alerte +![create_alert_step_2](/img/guide/alerting/create_alert_step_2.png) + +--- +- Pendant combien de temps la métrique doit être évaluée à vrai avant de lever l'alerte +![create_alert_step_3](/img/guide/alerting/create_alert_step_3.png) + +--- +- Choisir le namespace et le groupe (voir capture d'écran après pour savoir à quoi cela correspond) + +:warning: **Pour créer un nouveau namespace/groupe, remplir la zone de texte et valider en appuyant sur la touche `entrée`** :warning: + +![create_alert_step_4](/img/guide/alerting/create_alert_step_4.png) + +*Affichage des alertes selon le namespace et le groupe* +![alert_ns_group](/img/guide/alerting/alert_ns_group.png) + +--- +- Il est possible de définir des labels supplémentaires quand l'alerte est levée, comme le label `refapp` + +:warning: **Pour créer un nouveau label, remplir la zone de texte et valider en appuyant sur la touche `entrée`** :warning: +![create_alert_step_5](/img/guide/alerting/create_alert_step_5.png) + +--- +- Remonter en haut de la page et cliquer sur le bouton `Save and exit` pour sauvegarder l'alerte + +### Etat des alertes +Une alerte a 3 états différents: +- **Normal**: le service tourne normalement +- **Pending**: changement d'état en cours +- **Firing**: le service n'est plus assuré et l'alerte est levée + +Service Normal +![alert_ns_group](/img/guide/alerting/alert_ns_group.png) + +Service Firing +![alert_firing](/img/guide/alerting/alert_firing.png) + +## Points de contact +Les contact points définissent les différents canaux qu'il est possible d'utiliser pour notifier d'une alerte (les plus courants étant les emails et les webhook) + +Cliquer sur `Contact points` dans le menu. + +Dans la liste déroulante `Choose Alertmanager`, choisir `Alertmanager` +![contact_point_manager](/img/guide/alerting/contact_point_manager.png) + +Cliquer sur le bouton `+ Add contact point` + +Remplir les informations selon le canal voulu, exemple pour un webhook: +![contact_point_create](/img/guide/alerting/contact_point_create.png) + +Dans le sous menu `> Optional webhook settings` il est possible de retrouver les options d'authentification pour les webhooks + +## Politiques de notifications +Les alertes levées sont normalement envoyées via le canal de communication défini par défaut dans les contact points. + +Il est possible de définir d'autres politiques pour envoyer certaines alertes à d'autres canaux de communication. + +Cliquer sur `Notification policies` dans le menu + +Dans la liste déroulante `Choose Alertmanager`, choisir `Alertmanager` +![contact_point_manager](/img/guide/alerting/contact_point_manager.png) + +La première politique sera celle par défaut (choisir un canal approprié pour les recevoir), il est possible par la suite de définir des politiques imbriquées pour router les alertes selon des règles spécifiques + +--- +La liste déroulante `Default contact Point` permet de choisir le canal de communication par défaut. +![policy_default](/img/guide/alerting/policy_default.png) +Cliquer sur `Add default policy` pour sauvegarder + +--- +Il est par la suite possible de définir des politiques imbriquées. + +Choisir où l'imbrication se fera et cliquer sur le bouton `+ New nested policy` + +Une nouvelle fenêtre s'ouvre, où il est possible de choisir les alertes selon l'existence d'un label, etc. (attention le bouton `Add policy` se trouve en bas) + +Exemple si le label `refapp`est égal à `demo`, alors l'alerte est routée vers le point de contact nommé `opsdroid` +![notification_policy_nested_create](/img/guide/alerting/notification_policy_nested_create.png) + +Cliquer sur `Add policy` pour créer la nouvelle politique imbriquée, que l'on retrouve sous celle par défaut dans cet exemple: +![notification_policies](/img/guide/alerting/notification_policies.png) diff --git a/hexaforge/guide/archive-logs.md b/hexaforge/guide/archive-logs.md new file mode 100644 index 0000000..4678f4b --- /dev/null +++ b/hexaforge/guide/archive-logs.md @@ -0,0 +1,203 @@ +# Archivage des logs + +Il est possible de demander le transfert des logs de son application vers son namespace applicatif afin de par exemple les archiver pour des raisons légales. + +Cette section va décrire comment recevoir les logs applicatifs et les archiver sur un S3 grâce au logiciel [vector](https://vector.dev) + +Vector est un ETL open-source édité par l'entreprise Datadog et est le choix recommandé d'OpenShift pour le traitement des logs. + +Un chart helm est disponible [ici](https://artifacthub.io/packages/helm/vector/vector), voici comment le configurer pour démarrer un serveur http de réception des logs et les archiver sur un S3. + +L'archivage des logs se fera par paquet (30min ou 100Mo) et sera stocké dans un dossier YYYY/MM/DD/... + +Les clés de sécurité (AK/SK) sont sauvegardés dans un secret, voir avec [SOPS comment les chiffrer](/guide/secrets-management) + +## Archivage + +**Chart.yaml:** +*Version 0.30.0 à la date d'écriture de cette documentation* +```yaml +dependencies: + - name: vector + version: 0.30.0 + repository: "https://helm.vector.dev" + condition: vector.enabled +``` + +**values.yaml:** +```yaml +vector: + enabled: true + commonLabels: + app: my-app + tier: logs + component: vector + podMonitor: + enabled: true + fullnameOverride: vector + persistence: + enabled: true + size: 10Gi + extraVolumes: + - name: aws-creds + secret: + secretName: aws-log-archive + extraVolumeMounts: + - name: aws-creds + mountPath: /var/aws/ + resources: + requests: + cpu: 100m + memory: 200Mi + limits: + cpu: 100m + memory: 200Mi + customConfig: + data_dir: /vector-data-dir + api: + enabled: true + address: 127.0.0.1:8686 + playground: false + sources: + internal_metrics: + type: internal_metrics + http_server: + type: http_server + address: 0.0.0.0:8080 + sinks: + prom_exporter: + type: prometheus_exporter + flush_period_secs: 3600 + inputs: [internal_metrics] + address: 0.0.0.0:9090 + aws_s3_out: + type: aws_s3 + acknowledgements: + enabled: true + tls: + verify_certificate: false + inputs: + - http_server + endpoint: "https://monendpointS3" + bucket: logs + region: eu-east-1 + auth: + credentials_file: /var/aws/credentials + compression: gzip + encoding: + codec: raw_message + key_prefix: "%Y/%m/%d/" + buffer: + type: disk + max_size: 268435488 + batch: + max_bytes: 104857600 + timeout_secs: 1800 + tags: + Project: monprojet +``` + +Les clés de sécurité (AK/SK): +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: aws-log-archive +type: Opaque +data: + credentials: |- + [default] + aws_access_key_id = ++++++++++++ + aws_secret_access_key = ++++++++++++ +``` + +:warning: **Pour profiter de ce service, ouvrir un ticket auprès de la ServiceTeam détaillant le namespace source, la méthode de transmission (http, kafka, syslog) ainsi que l'url (+ port) vers laquelle envoyer les logs.** :warning: + +## Bonus: générer des métriques à partir des logs +Vector est capable de parser les logs afin d'en tirer des métriques. + +Dans l'exemple précédent, le podMonitor ainsi que le service lié à prometheus sont démarrés, il ne reste plus que les instructions liées au parsage des logs pour avoir des métriques qui remontent dans grafana. + +L'exemple suivant prend en exemple des logs issus de postgrest (log au format apache combined). + +Ainsi le log suivant: `127.0.0.1 bob frank [10/Oct/2000:13:55:36 -0700] "GET /apache_pb.gif HTTP/1.0" 200 2326 "http://www.seniorinfomediaries.com/vertical/channels/front-end/bandwidth" "Mozilla/5.0 (X11; Linux i686; rv:5.0) Gecko/1945-10-12 Firefox/37.0"` + +est parsé en: +```json +{ + "agent": "Mozilla/5.0 (X11; Linux i686; rv:5.0) Gecko/1945-10-12 Firefox/37.0", + "host": "127.0.0.1", + "identity": "bob", + "message": "GET /apache_pb.gif HTTP/1.0", + "method": "GET", + "path": "/apache_pb.gif", + "protocol": "HTTP/1.0", + "referrer": "http://www.seniorinfomediaries.com/vertical/channels/front-end/bandwidth", + "size": 2326, + "status": 200, + "timestamp": "2000-10-10T20:55:36Z", + "user": "frank" +} +``` + +L'idée est de compter le nombre de requête par utilisateur (ici frank). + +La propriété `transforms` permet de transformer ses logs (voir [documentation](https://vector.dev/docs/reference/configuration/transforms/) pour plus d'exemple). + +Les transformations peuvent s'enchaîner, c'est ce qui est utilisé ici sélectionner, parser et remonter une métrique. + +```yaml +vector: + customConfig: + sources: + internal_metrics: + type: internal_metrics + http_server: + type: http_server + address: 0.0.0.0:8080 + transforms: + remap: # Parse les logs reçus (format json) pour ne garder que le payload sans toutes les informations ajoutées par vector + type: remap + inputs: + - http_server + source: >- + . = parse_json!(.message) + parse_pgrest_log: + # Check si le log reçu correspond est émis par le pod qui contient un label component:postgrest + # Si c'est le cas, parse la clé message qui est au format apache combined + type: remap + inputs: + - remap # Fait appel au transform précédent + source: >- + component, err = string(.kubernetes.labels.component) + + if err != null { + abort + } + + if !contains(component, "postgrest") { + abort + } + + . = parse_apache_log!(.message, "combined") + pgrest_log_to_metrics: + # # Transforme le log en métrique, ici compter le nombre de requête par utilisateur + type: log_to_metric + inputs: + - parse_pgrest_log # Fait appel au transform précédent + metrics: + - type: counter + field: user + name: response_total + namespace: tcnp + tags: + user: "{{ `{{user}}` }}" + sinks: + prom_exporter: + type: prometheus_exporter + flush_period_secs: 3600 + inputs: + - internal_metrics + - pgrest_log_to_metrics # Ajout du dernier transform afin d'avoir la métrique exposée au format prometheus + address: 0.0.0.0:9090 +``` diff --git a/hexaforge/guide/best-practices.md b/hexaforge/guide/best-practices.md new file mode 100644 index 0000000..65bec35 --- /dev/null +++ b/hexaforge/guide/best-practices.md @@ -0,0 +1,192 @@ +# Bonnes pratiques + +## Applicatifs + +Une application Cloud π Native doit respecter les [Twelve-Factor](https://12factor.net/fr/) + +D'autres bonnes pratiques à réspecter impérantivement: + +1. Base de code + + Le code de l'application et de déploiement doit etre **versionné** dans un dépôt de source de type **Git** (Public/Privée) **accessible depuis internet**. + +2. Dépendances + + __TOUTES__ dépendances necessaires à la constuction de l'application (Libraries,Images, ...) doivent provenir des dépôts de librairies connus tels que Maven, Composer et Node. Il est aussi possible de construire les dépendences par l'offre Cloud π Native et les déposer dans son gestionnaire d'artefact. + +3. Configuration / Service Externe + + __TOUTES__ la configuration applicative pouvant être amenée a être modifié, par exemple la configuration entre deux environnements applicatifs est la plus part du temps différente. Elle doit donc être injectée par des variables d'environnement au runtime ou via un fichier de configuration dynamique via une ConfigMap + +4. Port + + Afin de respecter les préconisation de sécurité, les applications déployées doivent écouter sur des ports > 1024. + +6. Logs + + L'application __NE DOIT PAS__ écrire dans un fichier de logs spécifique mais écrire l'ensemble de ces logs dans la sortie standards (stdout) au format GELF ou à defaut JSON. + + Les logs seront accessibles plus facilement de cette manière depuis les outils de supervisions. + +7. Processus + + Les applications doivent être __STATELESS__, si des données de session/cache doivent être utilisé et partagé par l'application alors elles doivent faire l'objet d'un service externe prévus à cet effet telsque Redis. + +8. Processus d’administration + + Les opérations d'administrations doivent être faites via des initContainer (Init/Migration bdd, ...) ou des CronJob (Backup bdd, ...) + +L'ensemble de ces bonnes pratiques sont détaillés dans la documentation OpenShift [ici](https://docs.openshift.com/container-platform/4.12/openshift_images/create-images.html) + +## Architectures + +L'application déployée doit être conteneurisée (sous la forme d'un ou plusieurs conteneurs). + - Les __Dockerfiles__ doivent être dans le dépôt pour permettre à la chaine de reconstruire l'application. + - Les images de bases des __Dockerfiles__ doivent être accessibles publiquement ou reconstuire par l'offre Cloud π Native . + - Les images doivent être __rootless__, l'utilisateur qui lance le processus au sein du conteneur ne doit pas être `root`. + - L'utilisateur lançant le processus dans le conteneur doit avoir les droits adéquats en lecture / écriture sur le système de fichiers si l'application doit manipuler ce dernier. + - Des sondes de "Readiness"/"Liveness" doivent être implémenté. + - Des limits/requests doivent etre mise en place. + +## Déploiement + +L'application doit se déployer à l'aide de fichiers d'__Infrastructure As Code__: + - Utiliser des manifestes [kubernetes](https://kubernetes.io/) avec Kustomize pour variabliser vos manifestes (cf. [tutoriels](/guide/tutorials)) + - Utiliser des charts [helm](https://helm.sh/) (cf. [tutoriels](/guide/tutorials) pour avoir des exemples de fichiers). + - Utiliser [Kustomize](https://kustomize.io/) + +## Labels + +Les ressources doivent comporter des labels permettant de les identifier. les labels pourraient etre decomposés de la facon suivante : + +``` Yaml +App : " " +Env : " " +Tier : " " +Criticality : " " +Component : " " +``` + +## Tag d'images + +Les images poussées dans le registry devront etre unique et identifiés via un Sha ou Short-Sha qui pourrait etre lié au commit Git. Grace a cela une gestion des releases et un rollback seront possibles. + +Exemple de valeur pour le Tag de l'image : + +``` +CI_COMMIT_SHA +CI_COMMIT_SHORT_SHA +CI_COMMIT_TAG +CI_JOB_ID +``` + +## Politiques de nommage + +Les noms de toutes les ressources Openshift ne doivent jamais etre trop longs, il est donc conseillé de choisir des noms courts. +il se pourrait que des ressources ne soient pas déployées si le nom est trop long. +Coté exploitation, cela facilite grandement la gestion. + +Exemple : + +``` +Service : env-ms-svc +Deployment : env-ms-dep +Statefulset : env-ms-sts +ConfigMap : env-ms-cm +Secret : env-secret +CronJob : env-name-cj +Route : env-route +PVC : env-name-pvc +``` + +## Secrets + +Les secrets comportent toutes les informations sensibles. Les différents types de secrets peuvent etre : + +- Passwords +- Certificats +- Usernames +- Tokens + +Toutes les secrets devront etre contenus dans un Vault qui sera mis a disposition pour l'ensemble des projets. Les objets contenus dans le Vault sont séparés par projets (NS). + +## Liveness et Readiness + +Il est très important de mettre en place ces checks afin de vérifier l'etat de vos applications. Ceci est nécessaire pour assurer la haute disponibilité et la résilience de vos applications. +Cela peut-etre une fonctionnalité de l'application, une page d'un site web, une entrée en base de donnée, etc. + +``` Yaml +livenessProbe: + httpGet: + path: / + port: 80 + httpHeaders: + initialDelaySeconds: 3 + periodSeconds: 3 +readinessProbe: + httpGet: + path: /ready + port: 80 + initialDelaySeconds: 3 + periodSeconds: 3 +``` + +## SSL + +Afin d'optimiser un flux sécurisé,il est préférable que cela soit de bout en bout. + +Exemple du schéma de distribution de la requete. + +Users --HTTPS-> ReverseProxy --HTTPS-> Ingress Kubernetes --HTTPS-> Container (Best Case) + +Users --HTTPS-> ReverseProxy --HTTPS-> Ingress Kubernetes --HTTP-> Container (Usual Case) + +## HPA (Horizontal Pod Autoscaling) + +Le scaling est très important afin de répondre aux besoins en termes d'affluence. il est aujourd'hui un atout majeur pour avoir une application qui soit le plus disponible possible avec des performances élevées. Pour cela il est donc possible de définir des triggers afin d'upscale l'applicatif (CPU, RAM, Métriques Applicatives). + +## QOS + +Il est important de définir les consommations de chaque POD (prévisionnelles), Savoir si il serait intéressant que certains disposent d’une "request" égal a la "limit" afin d’assurer une réservation des ressources. (Guaranteed Class) +L'utilisation du "Burstable" n'est pas pas une bonne pratique. il est vraiment necessaire d'avoir une "limit" même si celle-ci n'est pas équivalente a la "request". + +Exemple : + +```Yaml +limits: + memory: "200Mi" + cpu: "700m" +requests: + memory: "200Mi" + cpu: "700m" +``` + +## Taille des images + +Il est très important de construire des images les plus légères possibles, c'est a dire utiliser uniquement les paquets nécéssaires au bon fonctionnement de l'application ainsi que la meilleure image de base. +C'est un gros vecteur de sécurité, de charge stockage et réseau. + +Exemple d'image base Lightway : Alpine + +## Politiques réseau + +Les "Network policies" sont par défaut en "Deny ALL". Il est donc à vous de déifnir les flux entrants et sortants sur les namespaces de vos projets. + +ReverseProxy-->Networkpolicies-->Pods (Ingress) + +Pods-->Networkpolicies-->Proxy (Egress) + +```Yaml + +kind: NetworkPolicy +apiVersion: networking.k8s.io/v1 +metadata: + name: web-allow-external +spec: + podSelector: + matchLabels: + Tier: frontend + ingress: + - ports: + - port: 80 +``` diff --git a/hexaforge/guide/deployment-with-argo.md b/hexaforge/guide/deployment-with-argo.md new file mode 100644 index 0000000..e31ee5b --- /dev/null +++ b/hexaforge/guide/deployment-with-argo.md @@ -0,0 +1,30 @@ +# Déploiement de votre application + +Une fois qu'un dépôt d'infrastructure est synchronisé, il convient de se rendre sur le service ArgoCD depuis la liste des services : +![argocd](/img/tuto/4argocd.png) + +Cliquez sur le projet nouvellement créé afin de finaliser son configuration: modification du dépôt d'infrastructure par défaut, ou le cluster de déploiement applicative. + +Allez dans le menu en haut et cliquez sur App detail : +![ArgoCD-menus](/img/tuto/4argocd-menus-bouton.png) + +Sur l'écran qui s'affiche, cliquez sur le bouton *EDIT* et adaptez les valeurs renseignées par defaut par la console et selectionner le cluster de déployement. +![ArgoCD-app-details](/img/tuto/4argocd-app-details.png) + +Notamment: + +- **CLUSTER**: correspond au cluster sur lequel l'application doit être déployée, cela dépends des informations saisie lors de l'étape de [gérer les environnements](/guide/environments-management). +- **TARGET REVISION**: correspond à la branche du repo d'infra à déployer, par defaut il point sur HEAD (master). A adapter si le repo utilise une branche +- **PATH** qui est positionné à base par defaut et qui correspond à un déploiement de type fichiers de manifests ou kustmize. Dans le cas d'un déploiement de type HELM, modifier le PATH point pointer vers la racine en mettant un point dans le champs : . ou préciser le répertoire correspondant à la racine du chart +- Dans l'onglet **PARAMETERS**, il est possible de surcharger certaines valeurs du fichier values (mais il est préférable de modifier le fichier values directement) + +Finir la saisie en cliquant sur le bouton *SAVE* + +Le déploiement se fait automatiquement par ArgoCD, mais il est possible de forcer la synchronisation avec le repo sur gitlab Cloud π Native en cliquant sur les boutons: + +- *REFRESH* pour forcer la synchronisation depuis le repo gitlab de la plateforme Cloud π Native +- *SYNC* pour forcer le rafraichissement entre l'état défini par git et l'état réel des objets créés par ArgoCD. + +Une fois le déploiement est correctement effectué le status de l'application ArgoCD doit correspondre à : + +![ArgoCD-menus](/img/tuto/4argocd-menus.png) diff --git a/hexaforge/guide/environments-management.md b/hexaforge/guide/environments-management.md new file mode 100644 index 0000000..1c42e7d --- /dev/null +++ b/hexaforge/guide/environments-management.md @@ -0,0 +1,26 @@ +# Gestion des environnements + +Depuis la console il est possible de créer des environnements applicatifs pour son projet. + +Un environnement correspond à un namespace sur un cluster pour son projet applicatif. + +La console crée automatiquement : + - un namespace applicatif par environnement sur le cluster correspondant. + - le pullsecret associé au projet. + - les quotas correspondant à l'environnement sur le namespace + - une application ArgoCD par environnement et par repo de code infrastructure. + + ## Création d'un environnement + + Depuis la console aller dans le menu ![environnement](/img/environnement/menu.png) + + Donner : + - Un nom à l'environnement, par exemple integration + - Un type (dev / staging / integration / prod) le type d'environnement donne accès à des quotas différents + ![type](/img/environnement/type-env.png) + - Un dimensionnement (quota) + ![quota](/img/environnement/quota-env.png) + - Le cluster de destination + ![quota](/img/environnement/cluster-env.png) + +Cliquez sur le bouton **Ajouter l'environnement** pour créer l'environnement diff --git a/hexaforge/guide/get-started.md b/hexaforge/guide/get-started.md new file mode 100644 index 0000000..a4523e6 --- /dev/null +++ b/hexaforge/guide/get-started.md @@ -0,0 +1,47 @@ +# Démarrer + +La prise en main de la plateforme Cloud π Native se fait par la console. + +## Etape 1 - Accès à la console + +Une fois sur la console, il faut se connecter en cliquant en haut à droite sur le bouton se connecter : +![se connecter](/img/tuto/1tuto-connexion.png) + +> La création des comptes utilisateurs est opérée par les administrateurs de la plateforme. + +## Etape 2 - Créer un projet + +Créer un projet sur la console (un détail des opérations à mener est trouvable [ici](/guide/projects-management)) + +**Attention, un projet ne peut changer de nom après sa création.** + +## Etape 3 - Ajouter des collaborateurs + +Ajouter vos collaborateurs sur le projet, un guide est disponible [ici](/guide/team) + +Les collaborateurs devant accéder à Argo CD devront être ajoutés à chaque environnement concernés, voir le guide [ici](/guide/team#attribution-de-droits-a-un-membre) + +## Etape 4 - Ajouter un dépôt synchronisé + +Ajouter vos dépôts (qui devront par la suite être synchronisé - manuellement ou via un automatisation), un guide est disponible [ici](/guide/repositories-management). + +Il existe deux types de dépôts: + +- dépôt avec du code applicatif: génère une image docker utilisée plus tard dans vos déploiements (doit contenir un Dockerfile et un fichier gitlab-ci nommé `.gitlab-ci-dso.yaml`) +- dépôt avec du code d'infrastructure: manifest / template kuztomize / chart helm générant votre infrastructure via ArgoCD + +> Note: il est possible d'avoir un seul dépôt avec les 2 fonctionnalités + +## Etape 5 - Ajouter un environnement + +Un environnement est un namespace cloisonné au sens kubernetes permettant de déployer le code d'infrastructure du dépôt idoine. + +Pour déployer un environnement un guide est disponible [ici](/guide/environments-management). + +> Note: les collaborateurs du projet devant intervenir sur ArgoCD concernant l'infrastructure doivent être rajouté sur chaque environnement, un guide disponible [ici](/guide/team#attribution-de-droits-a-un-membre). + +## Divers + +- Afin d'accéder à vos images construites via Cloud Pi Native et stockées sur Harbor, un secret, nommé `registry-pull-secret`, est créé automatiquement par la plateforme. + +- Un tutoriel est disponible [ici](/guide/tutorials) pour automatiser la synchronisation entre votre dépôt primaire et le dépôt sur la plateforme Cloud Pi Native. diff --git a/hexaforge/guide/logs-kibana.md b/hexaforge/guide/logs-kibana.md new file mode 100644 index 0000000..9eee89a --- /dev/null +++ b/hexaforge/guide/logs-kibana.md @@ -0,0 +1,57 @@ +# Logs + +Retrouver ce service dans la console Cloud Pi via le menu `Projet > Mes Projets > Sélectionner un projet > Mes Services` et cliquer sur l'icône Kibana qui vous intéresse. + +## Connexion +Pour visualiser vos logs, sélectionner Kibana dans le tableau de bord "Mes Services". + +Pour se logguer, cliquer sur le bouton `dso-client` + +![login](/img/guide/kibana/log-in.png) + +*Les prochaines étapes ne seront à faire qu'une seule fois* + +- Kibana va demander l'autorisation d'accéder à des ressources, cocher tout et cliquer sur `Allow selected permissions` +![authorize](/img/guide/kibana/authorize.png) + +- Kibana va s'ouvrir sur une page de création d'index, aucun n'étant pré-paramétré. +Remplir la zone de texte avec `app-*` pour sélectionner tous les index présents et futurs puis cliquer sur le bouton `> Next step` +![create_index_pattern](/img/guide/kibana/create_index_pattern.png) + +Kibana va demander quel champ utiliser pour la date, choisir `@timestamp` dans la liste déroulante puis cliquer sur le bouton `Create index pattern` +![create_index_timestamp](/img/guide/kibana/create_index_timestamp.png) + +Félicitations, vous venez de créer votre premier index Kibana et allez pouvoir dès à présent découvrir et filtrer vos logs +![create_index_valid](/img/guide/kibana/create_index_valid.png) + +## Explorer vos logs +Pour explorer et requêter vos logs, allez sur l'onglet `Discover` +![discover](/img/guide/kibana/discover.png) + +Cette page se décompose en plusieurs partie détaillées ci-dessous: + +En haut, les options concernant la plage de temps (pour rappel, seulement 7 jours de logs sont disponibles) et l'auto-refresh +![discover_time](/img/guide/kibana/discover_time.png) + +--- +Juste en dessous, la zone de requête, avec comme exemple les lignes de logs dont le nom du container est `pgrest-tcnp` et le message (aka la sortie console des containers) contient le mot `WAF`. +Cliquer sur le bouton `Refresh` pour obtenir le résultat de la requête. +![discover_query](/img/guide/kibana/discover_query.png) + +--- +A gauche se trouve les champs requêtables (ceux trouvés dans l'index créé à l'étape précédente) +![discover_available_fields](/img/guide/kibana/discover_available_fields.png) + +--- +A droite se trouve les résultats avec un graphique reprenant la disparité des lignes de logs selon la date. + +En en dessous, les logs correspondants à la recherche (avec les critères surlignés). + +*A noter qu'il est possible de déplier les résultats en cliquant sur la flèche à côté de la date* + +![discover_results](/img/guide/kibana/discover_results.png) + +## Aller plus loin +La documentation de Kibana se trouve [ici](https://www.elastic.co/guide/en/kibana/6.8/index.html) + +Plus d'informations concernant la syntaxe de requêtage [ici](https://www.elastic.co/guide/en/kibana/6.8/kuery-query.html) diff --git a/hexaforge/guide/metrics.md b/hexaforge/guide/metrics.md new file mode 100644 index 0000000..e5f8712 --- /dev/null +++ b/hexaforge/guide/metrics.md @@ -0,0 +1,94 @@ +# Métriques + +Retrouver ce service dans la console Cloud Pi via le menu `Projet > Mes Projets > Sélectionner un projet > Mes Services` et cliquer sur l'icône Grafana correspondant au cluster sur lequel votre déploiement applicatif est présent. + +Dans cette section, nous allons découvrir comment créer un nouveau dashboard contenant un graphique. + +## Connexion +Pour visualiser vos métriques, sélectionner Grafana dans le tableau de bord "Mes Services". + +Pour se logguer, cliquer sur le bouton en bas de page commençant par "Sign in with..." + +![signin](/img/guide/grafana-sign-in.png) + +Une fois connecté, l'accès aux dashboards est disponible via la menu hamburger en haut à gauche + +![menu](/img/guide/grafana_menu.png) +![menu dashboard](/img/guide/grafana_menu_dashboard.png) + +Par défaut, les équipes de Cloud Pi Native ont prévu un dashboard reprenant les informations d'infrastructure (CPU/RAM/Quota/Réseaux/Stockage) de vos différents namespace. + +![dashboard_infra](/img/guide/dashboard_infra.png) + +Il est possible d'en ajouter d'autres, ceux-ci seront automatiquement sauvegardés pour une utilisation future. + +## Créer un dashboard +Pour créer un dashboard, se rendre dans la liste des dashboard et cliquer sur `New > New Dashboard` +![new dashboard](/img/guide/grafana_new_dashboard.png) + +Cliquer sur le bouton `+ Add visualization` +![add visualization](/img/guide/grafana_add_visualization.png) + +Grafana va ouvrir une page pour créer une nouvelle visualisation, un exemple avec la capture d'écran suivante: +![first visualization](/img/guide/grafana_first_visualization.png) + +--- +En bas, on retrouve les informations concernant les requêtes sur les métriques: +![zoom queries](/img/guide/grafana_first_visualization_metrics.png) + +Ici on veut la consommation de RAM du container postgresql + +Le bouton `run queries` permet de prévisualiser le graphique obtenu + +--- +Le panel du haut permet de gérer la fênetre de temps pour laquelle on veut les métriques. + +![time window](/img/guide/grafana_first_visualization_time_window.png) + +Sur l'exemple, le prévisualisation contient les métriques pour les 5 dernières minutes + +Cette fênetre peut être glissante (5 dernières minutes, la dernière heure, la semaine passée) ou fixe (du 24/12/2023 à 23h55 au 25/12/2023 à 0h05) + +Le bouton composé de 2 flèches formant un cercle permet de rafraichir la prévisualisation avec la fenêtre de temps choisie + +--- +Le panel de droite permet de définir des options pour le graphique, notamment son type (ici `bar chart`) et le titre associé (ici `RAM postgresql`) +![option](/img/guide/grafana_first_visualization_option.png) + +--- +Tout en haut à droite se trouve 3 boutons: +![visualization_save](/img/guide/grafana_visualization_save.png) + +- `Discard`: Annule la création de la visualisation +- `Save`: Créer la nouvelle visualisation et sauvegarde le dashboard +- `Apply`: Créer la nouvelle visualisation + +Cliquer sur `Apply` pour créer la visualisation + +--- +Votre nouvelle visualisation est maintenant sur votre dashboard ! +![first_dashboard](/img/guide/grafana_first_dashboard.png) + +Grâce au bouton `Add`, il est possible de créer d'autres visualisations et ensuite de les agencer comme vous le voulez. + +A côté du bouton `Add` se trouve le bouton pour sauvegarder le dashboard, cliquer dessus: + +![first_dashboard_save](/img/guide/grafana_dashboard_save.png) + +Remplir les informations et cliquer sur `Save` + +--- +Votre dashboard est maintenant disponible dans la liste des dashbords +![dashboard_list](/img/guide/grafana_list_dashboard_final.png) + +>[!WARNING] +> Les dashboards personnels ne sont pas sauvegardés, penser à faire un backup du code yaml nécessaire à sa mise en place + +## Aller plus loin +La communauté propose des dashboards pré-définis pour la plupart des outils. + +Quelques liens utiles concernant les dashboard: +- : Dashboards créés par la communauté +- : dashboards créés par la société Sysdig basés sur le principe des golden signals +- : Documentation sur le langage PromQL, permettant d'interroger Prometheus +- : Comment importer un dashboard dans grafana diff --git a/hexaforge/guide/projects-management.md b/hexaforge/guide/projects-management.md new file mode 100644 index 0000000..e4e71f2 --- /dev/null +++ b/hexaforge/guide/projects-management.md @@ -0,0 +1,44 @@ +# Gestion des projets + +Un projet est un espace virtuel (namespace au sens kubernetes) cloisonné pour une seule application. + +Chaque projet contient une liste de collaborateurs (voir [Gestion des équipes](/guide/team)) ainsi qu'un ou plusieurs dépôts de code (voir [Gestion des dépôts](/guide/repositories-management.md)) + +## Création d'un projet + +Une fois connecté sur la console, le menu gauche présente une entrée "Mes Projets" contenant la liste de ses projets. +![mes projets](/img/tuto/2tuto-mes-projets.png) + +Cliquez sur le bouton **+ Créer un projet** afin d'ajouter un nouveau projet: +![créer projet](/img/guide/project/create_project.png) + +Sur cet écran il est nécessaire de renseigner : + +- **Nom de l'organisation**: correspondant à l'entité administratif de rattachement. +- **Nom du projet**: ce nom servira à créer un groupe dans gitlab de la plateforme Cloud π Native et sera une composante du namespace Kubernetes créé. + +Valider la saisie en cliquant sur **Commander mon espace projet** + +La création d'un projet va lancer le provisionnement des différents [services](/platform/introduction.html#services-core-proposes-par-la-plateforme), ce qui signifie principalement la configuration de ces outils avec un espace dédié pour le projet, son cloisonnement avec les autres projets et l'authentification des utilisateurs projet dans ces outils. Cette opération pourra prendre quelques minutes et le nouveau projet est présenté en cours de construction: + +A la fin du processus de création, liste de tous vos projets est affiché avec le nouveau projet disponible + +![tuile projet](/img/guide/project/monprojettuile.png) + +Au clic sur le projet, une page de tableau de bord est affichée +![projet - tableau de bord](/img/guide/project/monprojet_tableaudebord.png) + +Deux informations affichées: + +- si le projet est verrouillé, demander à la ServiceTeam les raisons et le déverrouillage du projet +- si les dernières opérations concernant le projet ont réussi + +Un certain nombre d'actions sont disponibles: + +- **Reprovisionner le projet**: la console DSO étant en cours de développement actif, des changements ont lieu et peuvent perturber le bon fonctionnement des projets. Ce bouton permet de mettre à jour son projet par rapport aux derniers développement de la console. +- **Afficher les secrets des services**: affiche des configurations utiles mais sensible des projets (seul le propriétaire du projet peut voir les secrets) +![mon projet - secrets](/img/guide/project/monprojet_secrets.png) +La partie GitLab permet d'avoir le token ainsi que l'id du dépôt mirror (permettant de cloner son dépôt primaire sur Cloud Pi Native). Cela permet d'automatiser cette action via des pipelines sur votre dépôt primaire. +Concernant Harbor, la registry stockant les images construites sur la plateforme CPiN +Pour la section Kubernetes, le nom du secret permettant de s'authentifier auprès d'Harbor. +- **Supprimer le projet monprojet**: après confirmation, supprime définitivement le projet. Aucune restauration n'est possible. diff --git a/hexaforge/guide/repositories-management.md b/hexaforge/guide/repositories-management.md new file mode 100644 index 0000000..9e8604f --- /dev/null +++ b/hexaforge/guide/repositories-management.md @@ -0,0 +1,74 @@ +# Gestion des dépôts + +En phase de développement, les équipes projets sont autonomes et travaillent avec leurs outils sans contraintes apportées par la plateforme Cloud π Native. La synchronisation des dépôts est le processus qui permet de *copier* les dépôts externes stockés sur github, gitab.com, bitbucket, etc. vers le repo de code de la plateforme Cloud π Native. la seule contrainte est que le repo externe soit accessible depuis Internet. Ce repo peut être public ou privé. Pour plus d'information, voir la page dédiée au [repo de code](/services/gitlab) + +Cliquez sur le menu gauche **Dépôts** +![menu-projet-depot](/img/tuto/3tuto-depots.png) + +## Ajouter un dépôt + +Puis sur le bouton **+ Ajouter un nouveau dépôt** + +Remplir le formulaire de des dépôts: + +- Choisir un nom +- Saisir l'URL du repo git distant. Dans le cas d'un repo privé cocher la case et préciser les credentials d'accès +- Deux types de repo peuvent être ajoutés: + - Un repo applicatif: contenant du code applicatif et qui sera construit afin de créer des images Docker à déployer sur l'infrastructure cible. + - Un repo d'infra: contenant les manifests de déploiement ou chart HELM contenant *l'infrastructure as code* du projet à déployer + +![ajout dépôt](/img/tuto/3tuto-depots-ajouter.png) + +Dans le cas d'un dépôt de code applicatif, générer les fichiers de *gitlab-ci* en cliquant sur le bouton *Fichiers de GitLab CI*. Le fichier `.gitlab-ci-dso.yml` est à placer à la racine de votre dépôt externe. Ces fichiers seront utilisés par le GitLab de Cloud π Native pour effectuer les divers tests, scans et déploiements du projet. + +![gitlab-ci-dso](/img/tuto/3tuto-depots-ajouter-gitlab-ci.png) + +Cliquer enfin sur le bouton `Ajouter le dépôt`. + +Lorsqu'un dépôt est créé dans la console en tant que `dépôt d'infrastructure`, la plateforme créée automatiquement l'application [ArgoCD](https://argo-cd.readthedocs.io/en/stable/) associée qui permettra le déploiement. + +Une fois que le dépôt est correctement ajouté, il apparait avec une icône indiquant son statut : + +depots synchronisés ok + +> Cette opération demande d'attendre jusqu'à quelques minutes. +> +> Des exemples de dépôts sont disponibles dans la sections [tutoriels](tutorials). + +## Synchronisation d'un dépôt + +Il est possible de synchroniser son dépôt depuis la console. Pour cela cliquer sur la tuile d'un dépôt, une page s'ouvre avec tout en haut la branche à synchroniser et un bouton **Lancer la synchronisation** + +![repository synchro](/img/guide/repository_synchro.png) + +Ce bouton lancer une pipeline sur la GitLab DSO afin de synchroniser la branche voulue. + +> Il est possible de lancer via curl cette pipeline, le propriétaire du projet peut retrouver la commande dans les secrets du projet. +> Cette commande pourra servir de base pour un GitHub action, etc... +> +> Exemple de GitHub Action : +> ```yaml +> name: Webhook to update the Cloud Pi repo +> on: push +> jobs: +> curl: +> runs-on: ubuntu-latest +> steps: +> - name: call webhook +> env: +> # Needs GIT_MIRROR_TOKEN to be added to github repo actions secrets +> GIT_MIRROR_TOKEN: ${{ secrets.GIT_MIRROR_TOKEN }} +> BRANCH_TO_SYNC: ${{ github.head_ref || github.ref_name }} +> run: | +> REPOSITORY_NAME= +> GIT_MIRROR_PROJECT_ID= +> +> curl -X POST --fail \ +> -F token=$GIT_MIRROR_TOKEN \ +> -F ref=main \ +> -F variables[GIT_BRANCH_DEPLOY]=$BRANCH_TO_SYNC \ +> -F variables[PROJECT_NAME]=$REPOSITORY_NAME \ +> "https://gitlab.apps.dso.numerique-interieur.com/api/v4/projects/$GIT_MIRROR_PROJECT_ID/trigger/pipeline" +> ``` +> +> A noter dans l'exemple précedent qu'il convient d'utiliser le bon url Gitlab. diff --git a/hexaforge/guide/secrets-management.md b/hexaforge/guide/secrets-management.md new file mode 100644 index 0000000..618a721 --- /dev/null +++ b/hexaforge/guide/secrets-management.md @@ -0,0 +1,189 @@ +# Gestion des secrets + +Le déploiement applicatif suit le principe gitOps et donc de "pousser" l'ensemble des manifestes et charts helm sur un repository GIT. Cependant, ce principe ne peut s'appliquer aux secrets afin de ne pas divulger le contenu d'un secret dans l'historique du repository. + +La solution que nous proposons aujourd'hui est [SOPS](https://github.com/mozilla/sops). Avec SOPS, vos secrets applicatifs sont poussés chiffrés sur vos dépôts git. Une clé asymétrique est utilisée dont la clé privée n'est connue que du cluster Kubernetes hébergeant votre application et la clé publique accessible à tous les projets. + +Dans le cas ou vous choisissez l'offre de services de la plateforme SecNumCloud MIOM pour déployer vos applicatifs dans les clusters kubernetes gérés par les équipes Cloud π Native, des paires de clés au format age ont été générées sur les différents clusters et les clés publiques ont été déposées par les admins dans le dépôt `documentation-dso-projets-interne` du GitLab de la plateforme. + +Exportez la variable `AGE_KEY` avec la valeur du cluster souhaité, exemple : + +```bash +export AGE_KEY=age1g867s7tcftkgkdraz3ezs8xk5c39x6l4thhekhp9s63qxz0m7cgs5kan9a +``` + +Afin de chiffrer un secret, il faut commencer par créer un objet kubernetes de type SopsSecret par exemple : + +:warning: __*Ne pas encode en base64 les secrets dans ce fichier, sops s'en occupera automatiquement*__ :warning: +```yaml +apiVersion: isindir.github.com/v1alpha3 +kind: SopsSecret +metadata: + name: mysecret-sops +spec: + secretTemplates: + - name: secret-exemple + labels: + label1: label1-value1 + annotations: + key1: key1-value + stringData: + data-name0: data-value0 + data: + data-name1: ZGF0YS12YWx1ZTE= + - name: token-exemple + stringData: + token: supersecrettoken + - name: docker-login + type: kubernetes.io/dockerconfigjson + stringData: + .dockerconfigjson: '{"auths":{"index.docker.io":{"username":"user","password":"pass","email":"toto@example.com","auth":"dXNlcjpwYXNz"}}}' +``` + +Ce fichier **ne doit pas** être commité et envoyé sur un dépôt Git et rester uniquement en local. Seul la version chiffrée peut être envoyée sur le dépôt Git. + +Il convient donc de chiffrer ce fichier via SOPS avec la clé publique correspondant à l'environnement. Par exemple : + +```bash +sops -e --age $AGE_KEY --encrypted-suffix Templates secret.sops.yaml > secret.sops.enc.yaml +``` + +Attention, le fichier chiffré doit conserver l'extension .yaml + +Le contenu du fichier devient alors : + +```yaml +apiVersion: isindir.github.com/v1alpha3 +kind: SopsSecret +metadata: + name: mysecret-sops +spec: + secretTemplates: + - name: ENC[AES256_GCM,data:GCTwnqz3qLWBltXkI1E=,iv:6s/89KUaymATUyyiavb1JQdndbvBY5XrBwdqg7Zp7nM=,tag:LcEyQU0/UvYWt7YCyGiFpw==,type:str] + labels: + label1: ENC[AES256_GCM,data:YKnixwbNsFPccmx7Kw==,iv:TQNNfHyvcJaXTnuNAi7iq/HHGpjtIN3SInxds1aWJpM=,tag:LCHNCjIQ8lrKRzlHIflYRA==,type:str] + annotations: + key1: ENC[AES256_GCM,data:IrcoTdCj0sS+tA==,iv:W5ccDu7jna7fP/ZfQ6cYaQX/uqU9PjKJ83PgJpHR9b0=,tag:4UDYI4WHXgipY8wXZu/NhA==,type:str] + stringData: + data-name0: ENC[AES256_GCM,data:t431CrKunuDACSw=,iv:pou2IIpBl6LeKloCC1yGzHA8Vkt/0Jo0nu8M4e+8XW0=,tag:kkuw1HXkSCS9f5K73MBEgw==,type:str] + data: + data-name1: ENC[AES256_GCM,data:p7ffMnDqVKj8Vog=,iv:KI07DuHBarC4du/sqrLus4o9s7o5knu/wu3W8ssO4e8=,tag:TgKXwVJJGEI9H5jWM5Ca4A==,type:str] + - name: ENC[AES256_GCM,data:isdJvbWonL593lfI4w==,iv:bpHG0fsIXWcmJ3fCDebKXeFGWNrHfHRWTQ86e+Dgruw=,tag:HmgDZLLssR+roPBSsSrizw==,type:str] + stringData: + token: ENC[AES256_GCM,data:QYXc7S8EHkSblo7RDW9Ovw==,iv:9lJcVQ5EJR+LYVFX/0OUJ+uZqQx0kiL2Kze8OJ3fu0M=,tag:QDpVKlSS1jj+OnWzpfCW2Q==,type:str] + - name: ENC[AES256_GCM,data:pHr2cwiFjGsIBZj+,iv:x1TkramaD0peRJe95n+r+ye5IWeeE630C0LwbVWJ154=,tag:7TiqbtURY7fn+9r2V7PlDA==,type:str] + type: ENC[AES256_GCM,data:8ZBm++dOCx4xlmPW4bZagHMVua5gj7v7GVkEtBRX,iv:Y8HYgfO8Ae9SY3WYF/BYhKY9n6KESwQEHMNUPZfQd9o=,tag:LqlUy6FLcYAtYEa8qtx5NQ==,type:str] + stringData: + .dockerconfigjson: ENC[AES256_GCM,data:1TmIvfP95WReEpGqF2/ukxkvyFVdYbO3gda+oAtNZqwRZw749qvU8koYsi012s1/yhutll5v3ldqUYtr4sNuVS7TFVy2/qZ+ryiBaI8qUxt+kOx85eyfp36pJolwQtdQPNanRTLLkV4mf1JzSYOG6WAokkQ=,iv:X1jzTyp+CzTIowxH6gl2cIInk892cuO9/5JUkuCJdqI=,tag:DbtJe3pRo8TMrBO/gt4BDw==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1g867s7tcftkgkdraz3ezs8xk5c39x6l4thhekhp9s63qxz0m7cgs5kan9a + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBTZFJGdkRzeVJFdDVUVjVS + SmU0ekE0aGplVzhxZm5UTklzZnA3QlIwRzNNCjJha21CU0VEZkt3SHB0THlVZ1ZM + VnlBSEZpbmJZVnlyY1VCTjdXZEtOR2cKLS0tIHBhRkprelpsQTJZWGphYUtRSlhJ + ZnpFSDNYT0M3K294VmlBVitmN09nUlUKI+THCBdEkTnAElA3b0z4r8Nx1KcW7gks + H5xJwqzzNn5C+UMy+v+Qn2hzg07juISBTDVcLtBDggVrZOAsh8kTMQ== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2023-04-18T15:02:34Z" + mac: ENC[AES256_GCM,data:Cpl1/GWn2LQivSo0qNTGyDxqCxm79DnomIpf1uDsoIuA5qqsluCUja0RLkEOm/fUD+UKzL8Muaqjo8+fbuKOvr4nfqaeARACPz377tdPEH55DHyg8Czv00OsxdHZ8C9BGeeSZr3YHDqQEKqQpK1zs7rBz/2adqD1SXrOFu+aiuQ=,iv:w+4DAXVAvD7IvDCBMTF+NfMRctp0dEWl+QsRJPsrd70=,tag:fWa0Sz3TlCQ2lIkVe6zE4Q==,type:str] + pgp: [] + encrypted_suffix: Templates + version: 3.7.3 +``` + +Ce fichier peut être commité et envoyé sur un dépôt git car le contenu est chiffré. + +> A noter que chaque élément du secretTemplates donnera lieu à un objet Secret dans kubernetes une fois le secret déchiffrée lors du déploiement. +Ainsi, dans l'exemple, le secret secret-exemple sera crée avec les données suivantes +```yaml +data: + data-name0: ZGF0YS12YWx1ZTA= + data-name1: ZGF0YS12YWx1ZTE= +``` +Le secret peut alors être utilisé directement par les POD de façon classique, par exemple : + +```yaml +spec: + containers: + - name: myContainer + image: myImage:MyTag + env: + - name: My_SECRET + valueFrom: + secretKeyRef: + name: secret-exemple + key: data-name0 +``` + +## Chiffrement partiel + +Il est aussi possible de chiffrer **partiellement** le SoapSecret si celui-ci contient des données plus ou moins sensibles si dans le fichier suivant on veut chiffrer que la clé password + +```yaml +apiVersion: isindir.github.com/v1alpha3 +kind: SopsSecret +metadata: + name: mysecret-sops +spec: + secretTemplates: + - name: exemple + data: + password: c2VjcmV0 + clearValue: ZGF0YS1jbGVhcg== +``` + +Il sera possible de définir une **encrypted_regex** qui défini le regex pattern des clés que l'on souhaite chiffrer, dans le fichier de configuration **.sops.yaml** à la racine du projet. + +```yaml +creation_rules: + - path_regex: .*newsecret.sops.yaml.* + encrypted_regex: "^.*password.*$" + age: age1g867s7tcftkgkdraz3ezs8xk5c39x6l4thhekhp9s63qxz0m7cgs5kan9a +``` + +Je chiffre mon secret + +```bash +sops -e newsecret.sops.yaml > newsecret.sops.enc.yaml +``` + +Le fichier de sorti aura le format suivant, on peut voir que seul la clé **password** a été chiffrée + +```yaml +apiVersion: isindir.github.com/v1alpha3 +kind: SopsSecret +metadata: + name: mysecret-sops +spec: + secretTemplates: + - name: exemple + data: + password: ENC[AES256_GCM,data:0yl7pmw7,iv:EH29fOotz0gKKEGesOO2v7fwM8FPtBgpBpZQllnP9K0=,tag:GQVbRh6rhYCdquk2wOInzw==,type:str] + clearValue: ZGF0YS1jbGVhcg== +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1g867s7tcftkgkdraz3ezs8xk5c39x6l4thhekhp9s63qxz0m7cgs5kan9a + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBZU3d0Z2N6QytuaHZWTXBm + QlRlV2RCM2ZKZW1DZ0lLT0xQdjUxKzVGYlRrCnMrT0hINTdBYkZaMDZzYlVHci9w + TGRHcUIzcEZqZGdsYVdxcERGdE9xRmsKLS0tIGdBL0NSNDdRYVVHRFU2WUQxS1Fw + SG5sa1ZJRUNjOWY5QURpcHZrWDI2SjAKO8hY5sVJ4wixFzN+Q7QB8MEheizsmKrB + m5JPbGUHmC15/HzSb0o8UFGXoi2MeDMie8hMu+A8uqVIhiBUrga3FA== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2023-04-20T14:31:45Z" + mac: ENC[AES256_GCM,data:17CYI5VKgxnc5Ae9dY/cwBu0d2hFKC+xdN5Y5vIIqdvXF6IOQKPQRwdNSXaLIjFWo9Xk+NP0nzAFbqyrIAR7hgGg5uWE0dAaWQw6NKgWvDIBWPU/Et2JuuBlbmny3cO//geij3XiODDAXxUg19XIDol0+f1Q5IPgPrtghKs6YC4=,iv:4YnMWSD23xRwNIiiAXMTM44ORq03J5dBNKkn9yE7bXw=,tag:Q+3SfVPTJjp777qlOwEEBg==,type:str] + pgp: [] + encrypted_regex: ^.*password.*$ + version: 3.7.3 +``` diff --git a/hexaforge/guide/team.md b/hexaforge/guide/team.md new file mode 100644 index 0000000..6811d11 --- /dev/null +++ b/hexaforge/guide/team.md @@ -0,0 +1,40 @@ +# Gestion des équipes + +Cette page présente la gestion des équipes sur un projets. + +Cette fonctionnalité se trouve dans le menu "Equipe" sur un projet. + +![Menu](/img/team/menu.png) + +## Membres du projet + +La page Equipe présente la liste des membres du projet : + +![Menu](/img/team/members.png) + +Depuis cette liste, il est possible de retirer une personne de la liste sur l'icone 'X' + +## Ajouter une personne au projet + +L'ajout d'une personne au projet s'effectue sur la partie basse de la page en saisissant l'adresse e-mail d'une personne existante dans le référentiel utilisateur CPiN. + +Lors de la saisie une auto-complétion permet de rechercher les personnes existantes dans le référentiel utilisateurs + +![Menu](/img/team/members.png) + +> Pour Ajouter une personne au référentiel CPiN, il convient de créer un ticket sur l'outil de [tickets](https://support.dev.numerique-interieur.com) + +## Attribution de droits à un membre + +> Attention, seul le créateur du projet peut ajouter des repos de code à un projet. + +Une fois qu'une personne a été ajoutée à un projet, il convient de lui donner des droits sur les environnements du projet. Pour cela, aller dans le menu environnement, choisir l'environnement sur lequel ajouter la personne et aller en bas de page. Saisir le nom de la personne dans le champ de saisie Accréditer un membre du projet. + +![Attribution de droits](/img/team/permission-environnement.png) + +Une fois selectionner, lui attribuer les droits (sur ArgoCD): + - r : droits de lecture seule sur l'environnement (visibilité du projet sur ArgoCD) + - rw : droits de lecture et écriture sur l'environnement (visibilité du projet sur ArgoCD et modification des values) + - rwd : droits de lecture, écriture et suppression sur l'environnement (visibilité du projet sur ArgoCD et modification des values et suppression des objets : pods etc.) + +> L'attribution de droits à un membre pour un environnement est une opération *nécessaire* pour donner accès à ArgoCD sur l'environnement concerné. diff --git a/hexaforge/guide/tutorials.md b/hexaforge/guide/tutorials.md new file mode 100644 index 0000000..e9f2301 --- /dev/null +++ b/hexaforge/guide/tutorials.md @@ -0,0 +1,110 @@ +# Tutoriels + +Choisir entre un déploiement via le dépôt d'Infrastructure As Code `Manifestes` ou `Helm` lors de l'ajout du dépôt d'infrastructure dans la console. + +## Déployer une application stateless + +Tutoriel de déploiement d'un serveur web servant une page html statique. + +### Nginx + +Technologies: + +- Server web Nginx + +#### Dépôts + +__Multirepo__ + +| Description | Dépôt | +| ------------------ | --------------------------------------------------------------- | +| Applicatif | | +| IAC *(Manifestes)* | | +| IAC *(Helm)* | | + +__Monorepo__ + +| Description | Dépôt | +| ------------------------- | --------------------------------------------------------- | +| Applicatif + IAC *(Helm)* | | + +### Nginx / Nodejs + +Technologies: + +- Server web Nginx +- Api Nodejs + +#### Dépôts + +__Monorepo__ + +| Description | Dépôt | +| ------------------------- | -------------------------------------------------- | +| Applicatif + IAC *(Helm)* | | + +## Déployer une application statefull + +Tutoriel de déploiement d'une application dialoguant avec une base de données. + +### Java / Postgresql + +Technologies: + +- Application Java +- Base de données Postgresql + +#### Dépôts + +__Multirepo__ + +| Description | Dépôt | +| ------------------ | ------------------------------------------------------------- | +| Applicatif | | +| IAC *(Manifestes)* | | +| IAC *(Helm)* | | + +## Mocks + +### Data-tooling + +Un mock data-tooling permettant d'exposer un base de données PostgreSQL en tant qu'api rest est disponible [ici](https://github.com/cloud-pi-native/mock-data-tooling). + +Ce mock contenant les outils suivants: + +- haproxy: agit en tant qu'API Gateway +- postgrest: expose la base de données postgres au protocol REST +- cloudpgnative: opérateur k8s pour gérer un cluster de postgresql +- pgadmin: administration de la base de données +- vector: gestion des logs +- sops: gestion des secrets + +> Ce chart helm est capable de gérer la réplication de base de données sur de multiples environnements cloisonnés via une synchronisation des wals depuis un S3 + +Pour l'utiliser, forker le dépôt et modifier le chart helm. + +Il est accompagné d'un autre chart helm disponible [ici](https://github.com/cloud-pi-native/mock-data-tooling-minio) permettant d'installer un S3 (minio) avec un certain nombre de buckets créés par défaut. + +### INES et Passage 2 + +Une fois que vous avez validé votre déploiement sur la console DSO d'OVH, la suite logique est de répéter ce procédé au sein du réseau ministériel. Et dépendamment des besoins de votre application, vous aurez besoin ou non de communiquer avec les équipes de Passage2 et d'INES. + +Pour vous aider, un mock a été mis en place [ici](https://github.com/cloud-pi-native/helm-projects-mocks/) + +## Divers + +### Monorepo + +Il est aussi possible d'utiliser un monorepo comprenant le code applicatif ainsi que le code d'infrastructure, dans ce cas ajouter ce seul dépôt de code et cocher la case `Dépôt contenant du code d'infrastructure`. + +### Accès aux images Harbor + +Un secret nommé `registry-pull-secret` est automatiquement créé par la plateforme Cloud Pi Native lors de la création d'un environnement. + +Vous pouvez retrouver un exemple d'utilisation de ce secret [ici](https://github.com/cloud-pi-native/exemples_ServiceTeam/blob/main/misc/pull_images_from_harbor/README.md) + +### Exemples + +Divers code d'exemple écrits par l'équipe Cloud Pi Native sont trouvables [ici](https://github.com/cloud-pi-native/exemples_ServiceTeam/). + +Ces exemples se concentrent sur des points précis, comme le monitoring, l'utilisation de sops ou encore l'archivage des logs et sont fréquemment enrichis. diff --git a/hexaforge/index.md b/hexaforge/index.md new file mode 100644 index 0000000..d7652b7 --- /dev/null +++ b/hexaforge/index.md @@ -0,0 +1,23 @@ +--- +layout: home +hero: + name: Hexaforge + text: Self-hosted PaaS + tagline: Gérez avec simplicité et harmonie le cycle de vie de vos applications cloud + actions: + - theme: brand + text: Voir sur GitHub + link: https://github.com/cloud-pi-native +features: + - title: Description + details: Présentation de la plateforme, sa philosophie et son architecture + link: /platform/introduction + - title: Installation + details: Guide d'installation de la plateforme + link: /installation/introduction + - title: Utilisation + details: Guide d'utilisation de la plateforme + link: /guide/get-started + - title: Administration + details: Guide d'administration de la console Hexaforge + link: /administration/introduction diff --git a/hexaforge/installation/configuration.md b/hexaforge/installation/configuration.md new file mode 100644 index 0000000..6c3beef --- /dev/null +++ b/hexaforge/installation/configuration.md @@ -0,0 +1,196 @@ +## Configuration + +Une fois le dépôt socle cloné, lancez une première fois la commande suivante depuis votre environnement de déploiement : + +```bash +ansible-playbook install.yaml +``` + +Elle vous signalera que vous n'avez encore jamais installé le socle sur votre cluster, puis vous invitera à modifier la ressource de scope cluster et de type **dsc** nommée **conf-dso** via la commande suivante : + +```bash +kubectl edit dsc conf-dso +``` + +Vous pourrez procéder ainsi si vous le souhaitez, mais pour des raisons de traçabilité et de confort d'édition vous préférerez peut être déclarer la ressource `dsc` nommée `conf-dso` dans un fichier YAML, par exemple « ma-conf-dso.yaml », puis la créer via la commande suivante : + +```bash +kubectl apply -f ma-conf-dso.yaml +``` + +Voici un **exemple** de fichier de configuration valide, à adapter à partir de la section **spec**, notamment au niveau du champ "global.rootDomain" (votre domaine principal précédé d'un point), des mots de passe de certains outils, du proxy ainsi que des sections CA et ingress : + +```yaml +--- +kind: DsoSocleConfig +apiVersion: cloud-pi-native.fr/v1alpha +metadata: + name: conf-dso +spec: + additionalsCA: + - kind: ConfigMap + name: kube-root-ca.crt + exposedCA: + type: configmap + configmap: + namespace: default + name: ca-cert + key: ingress.crt + argocd: + admin: + enabled: true + password: WeAreThePasswords + values: + image: + registry: docker.io + repository: bitnami/argo-cd + tag: 2.7.6-debian-11-r2 + certmanager: {} + cloudnativepg: {} + console: + dbPassword: AnotherPassBitesTheDust + values: {} + gitlab: + values: {} + gitlabOperator: {} + gitlabRunner: {} + global: + environment: production + projectsRootDir: + - my-root-dir + - projects-sub-dir + rootDomain: .example.com + harbor: + adminPassword: WhoWantsToPassForever + pvcRegistrySize: 50Gi + values: + nginx: + image: + repository: docker.io/goharbor/nginx-photon + tag: v2.9.1 + portal: + image: + repository: docker.io/goharbor/harbor-portal + tag: v2.9.1 + core: + image: + repository: docker.io/goharbor/harbor-core + tag: v2.9.1 + jobservice: + image: + repository: docker.io/goharbor/harbor-jobservice + tag: v2.9.1 + registry: + registry: + image: + repository: docker.io/goharbor/registry-photon + tag: v2.9.1 + controller: + image: + repository: docker.io/goharbor/harbor-registryctl + tag: v2.9.1 + trivy: + image: + repository: docker.io/goharbor/trivy-adapter-photon + tag: v2.9.1 + notary: + server: + image: + repository: docker.io/goharbor/notary-server-photon + tag: v2.9.1 + signer: + image: + repository: docker.io/goharbor/notary-signer-photon + tag: v2.9.1 + database: + internal: + image: + repository: docker.io/goharbor/harbor-db + tag: v2.9.1 + redis: + internal: + image: + repository: docker.io/goharbor/redis-photon + tag: v2.9.1 + exporter: + image: + repository: docker.io/goharbor/harbor-exporter + tag: v2.9.1 + ingress: + annotations: + route.openshift.io/termination: edge + tls: + type: tlsSecret + tlsSecret: + name: ingress-tls + method: in-namespace + keycloak: + values: + image: + registry: docker.io + repository: bitnami/keycloak + tag: 19.0.3-debian-11-r22 + kubed: {} + nexus: + storageSize: 5Gi + proxy: + enabled: true + 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 + port: "3128" + sonarqube: + postgresPvcSize: 25Gi + values: + image: + registry: docker.io + repository: sonarqube + edition: community + tag: 9.9.2-{{ .Values.edition }} + sops: + values: + image: + tag: 0.11.0 + 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 +``` + +Les champs utilisables dans cette ressource de type **dsc** peuvent être décrits pour chaque outil à l'aide de la commande `kubectl explain`. Exemple avec argocd : + +``` +kubectl explain dsc.spec.argocd +``` + +## Utilisation de vos propres values + +Comme nous pouvons le voir dans l'exemple de configuration fourni ci-dessus, plusieurs outils sont notamment configurés à l'aide d'un champ `values`. + +Il s'agit de valeurs de chart [Helm](https://helm.sh/fr). Vous pouvez les utiliser ici pour surcharger les valeurs par défaut. + +Voici les liens vers les documentations de chart Helm pour les outils concernés : + +- [Argo CD](https://github.com/bitnami/charts/tree/main/bitnami/argo-cd) +- [Console Cloud π Native](https://github.com/cloud-pi-native/console#readme) +- [GitLab](https://gitlab.com/gitlab-org/charts/gitlab) +- [Harbor](https://github.com/goharbor/harbor-helm) +- [Keycloak](https://github.com/bitnami/charts/tree/main/bitnami/keycloak) +- [SonarQube](https://github.com/bitnami/charts/tree/main/bitnami/sonarqube) +- [SOPS](https://github.com/isindir/sops-secrets-operator/tree/master/chart/helm3/sops-secrets-operator) +- [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. diff --git a/hexaforge/installation/debug.md b/hexaforge/installation/debug.md new file mode 100644 index 0000000..59ea6a3 --- /dev/null +++ b/hexaforge/installation/debug.md @@ -0,0 +1,32 @@ +# Debug + +## Réinstallation + +Si vous rencontrez des problèmes lors de l'éxécution du playbook, vous voudrez certainement relancer l'installation d'un ou plusieurs composants plutôt que d'avoir à tout réinstaller. + +Pour cela, vous pouvez utiliser les tags qui sont associés aux rôles dans le fichier « install.yaml ». + +Voici par exemple comment réinstaller uniquement les composants keycloak et console, dans la chaîne DSO paramétrée avec la `dsc` par défaut (`conf-dso`), via les tags correspondants : + +```bash +ansible-playbook install.yaml -t keycloak,console +``` + +Si vous voulez en faire autant sur une autre chaîne DSO, paramétrée avec votre propre `dsc` (nommée par exemple `ma-dsc`), alors vous utiliserez l'[extra variable](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_variables.html#defining-variables-at-runtime) `dsc_cr` comme ceci : + +```bash +ansible-playbook install.yaml -e dsc_cr=ma-dsc -t keycloak,console +``` + +## CloudNativePG + +La BDD PostgreSQL des composants Keycloak et SonarQube est installée à l'aide de l'opérateur communautaire [CloudNativePG](https://cloudnative-pg.io/), via le role `cloudnativepg`. + +Le playbook d'installation, en s'appuyant sur le role en question, s'assurera préalablement que cet opérateur n'est pas déjà installé dans le cluster. Il vérifiera pour cela la présence de deux éléments : + +- L'API `postgresql.cnpg.io/v1`. +- La `MutatingWebhookConfiguration` nommée `cnpg-mutating-webhook-configuration`. + +Si l'un ou l'autre de ces éléments sont absents du cluster, cela signifie que l'opérateur CloudNativePG n'est pas installé. Le rôle associé procédera donc à son installation. + +**Attention !** Assurez-vous que si une précédente instance de CloudNativePG a été désinstallée du cluster elle l'a été proprement. En effet, si l'opérateur CloudNativePG avait déjà été installé auparavant, mais qu'il n'a pas été correctement désinstallé au préalable, alors il est possible que les deux ressources vérifiées par le role soient toujours présentes. Dans ce cas de figure, l'installation de Keycloak ou de SonarQube échouera car l'opérateur CloudNativePG n'aura pas été installé par le role. diff --git a/hexaforge/installation/installation.md b/hexaforge/installation/installation.md new file mode 100644 index 0000000..6995015 --- /dev/null +++ b/hexaforge/installation/installation.md @@ -0,0 +1,93 @@ +# Installation + +## Lancement + +Dès que votre [configuration](#configuration) est prête, c'est à dire que la ressource `dsc` par défaut `conf-dso` a bien été mise à jour avec les éléments nécessaires et souhaités, relancez la commande suivante : + +```bash +ansible-playbook install.yaml +``` + +Patientez … + +Pendant l'installation, vous pourrez surveiller l'arrivée des namespaces correspondants dans le cluster, via la commande suivante : + +```bash +watch "kubectl get ns | grep 'dso-'" +``` + +Par défaut, ils sont en effet tous préfixés « dso- ». + +## Déploiement de plusieurs plateformes DSO dans un même cluster + +Suite à une première installation réussie et selon vos besoins, il est possible d'installer dans un même cluster une ou plusieurs autres plateformes DSO, en parallèle de celle installée par défaut. + +Pour cela, il vous suffit de déclarer une **nouvelle ressource de type dsc dans le cluster**, en la nommant différemment de la ressource `dsc` par défaut qui pour rappel se nomme `conf-dso`, et en y modifiant les éléments souhaités. + +Comme vu plus haut dans la section [Configuration](#configuration), déclarez votre ressource de type `dsc` personnalisée **dans un fichier YAML**. + +Il s'agira simplement de **modifier le nom de la ressource dsc** (section `metadata`, champ `name`) puis **adapter les paramètres souhaités** (mots de passe, ingress, CA, proxy, values …). + +Pensez également à déclarer pour chaque outil **un `namespace` et un `subDomain` différents** de ceux déjà déclarés lors de la première installation du socle DSO. + +Exemple pour Argo CD : + +```yaml +argocd: + namespace: mynamespace-argocd + subDomain: argocd-perso + admin: + enabled: true + password: PasswordForEveryone + values: + image: + registry: docker.io + repository: bitnami/argo-cd + tag: 2.7.6-debian-11-r2 +``` + +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 : + +```bash +cat ./roles/socle-config/files/config.yaml +``` + +Lorsque votre nouvelle configuration est prête, et déclarée par exemple dans le fichier « ma-conf-perso.yaml », créez-là dans le cluster comme ceci : + +```bash +kubectl apply -f ma-conf-perso.yaml +``` + +Vous pourrer ensuite la retrouver via la commande : + +```bash +kubectl get dsc +``` + +Puis éventuellement l'afficher (exemple avec une `dsc` nommée `ma-dsc`) : + +```bash +kubectl get dsc ma-dsc -o yaml +``` + +Dès lors, il vous sera possible de déployer une nouvelle chaîne DSO dans ce cluster, en plus de celle existante. Pour cela, vous utiliserez l'[extra variable](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_variables.html#defining-variables-at-runtime) Ansible prévue à cet effet, nommée `dsc_cr` (pour DSO Socle Config Custom Resource). + +Par exemple, si votre nouvelle ressource `dsc` se nomme `ma-dsc`, alors vous lancerez l'installation correspondante comme ceci : + +```bash +ansible-playbook install.yaml -e dsc_cr=ma-dsc +``` + +Pendant l'installation, et si vous avez nommé vos namespaces en utilisant un même suffixe ou préfixe, vous pourrez surveiller l'arrivée de ces namespaces dans le cluster. + +Exemple avec des namespaces préfixés « mynamespace- » : + +```bash +watch "kubectl get ns | grep 'mynamespace-'" +``` + +Exemple avec des namespaces dont le suffixe est « -mynamespace » : + +```bash +watch "kubectl get ns | grep '\-mynamespace'" +``` diff --git a/hexaforge/installation/introduction.md b/hexaforge/installation/introduction.md new file mode 100644 index 0000000..e4eddf5 --- /dev/null +++ b/hexaforge/installation/introduction.md @@ -0,0 +1,27 @@ +# Introduction +Le dépot de la plateforme Cloud π Native est sur GitHub: https://github.com/cloud-pi-native/socle +Son installation s'effectue d'une manière automatisée avec **Ansible** + +La dernière release de la plateforme Cloud π Native effectuera l'installation des services suivants : + +| Service | Site officiel | +| --------------------------- | ------------------------------------------------------------------------------ | +| Console Cloud π Native | | +| Argo CD | | +| Cert-manager | | +| Console Cloud π Native | | +| CloudNativePG | | +| GitLab | | +| gitLab-ci-catalog | | +| GitLab Runner | | +| Harbor | | +| Keycloak | | +| Kubed | | +| Sonatype Nexus Repository | | +| SonarQube Community Edition | | +| SOPS | | +| HashiCorp Vault | | + +L'installation de certains services peuvent prendre un peu de temps, par exemple Keycloak ou GitLab. + +Vous trouvez les versions de l'ensemble des outils de la plateforme Cloud π Native installés [ici](https://github.com/cloud-pi-native/socle/blob/main/versions.md) diff --git a/hexaforge/installation/prerequisites.md b/hexaforge/installation/prerequisites.md new file mode 100644 index 0000000..7fe1754 --- /dev/null +++ b/hexaforge/installation/prerequisites.md @@ -0,0 +1,52 @@ +# Prérequis + +Aujourd'hui l'installation de la plateforme Cloud π Native est testée uniquement sur un cluster OpenShift (version 4.X). +La compatibilité kubernetes sera effective dans une prochaine release. + +Vous devrez disposer d'un **accès administrateur au cluster**. + +Vous aurez besoin d'une machine distincte du cluster, tournant sous GNU/Linux avec une distribution de la famille Debian ou Red Hat. Cette machine vous servira en tant qu'**environnement de déploiement** [Ansible control node](https://docs.ansible.com/ansible/latest/network/getting_started/basic_concepts.html#control-node). Elle nécessitera donc l'installation d'[Ansible](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html), et plus précisément du paquet **ansible**, pour disposer au moins de la commande `ansible-playbook` ainsi que de la collection [community.general](https://github.com/ansible-collections/community.general). + +Toujours sur votre environnement de déploiement, vous devrez : + +- Clôner le présent [dépôt](https://github.com/cloud-pi-native/socle). +- Disposer d'un fichier de configuration ```~/.kube/config``` paramétré avec les accès administrateur, pour l'appel à l'API du cluster (section users du fichier en question). + +L'installation de la suite des prérequis **sur l'environnement de déploiement** s'effectue à l'aide du playbook nommé `install-requirements.yaml`. Il est mis à disposition dans le répertoire `admin-tools` du dépôt socle que vous aurez clôné. + +Si l'utilisateur avec lequel vous exécutez ce playbook dispose des droits sudo sans mot de passe (option NOPASSWD du fichier sudoers), vous pourrez le lancer directement sans options : + +```bash +ansible-playbook admin-tools/install-requirements.yaml +``` + +Sinon vous devrez utiliser l'option `-K` (abréviation de l'option `--ask-become-pass`) qui vous demandera le mot de passe sudo de l'utilisateur : + +```bash +ansible-playbook -K admin-tools/install-requirements.yaml +``` + +Pour information, le playbook `install-requirements.yaml` vous installera les éléments suivants **sur l'environnement de déploiement** : + +- Paquet requis pour l'installation des modules python : + - python3-pip + +- Paquets requis pour l'installation du gestionnaire de paquets Homebrew : + - git + - ruby + - tar + +- Modules python : + - pyyaml + - kubernetes + - python-gitlab + +- Collection Ansible [kubernetes.core](https://github.com/ansible-collections/kubernetes.core) si elle n'est pas déjà présente. + +- Gestionnaire de paquets [Homebrew](https://brew.sh/) pour une installation simplifiée des prérequis restants sur la plupart des distributions GNU/Linux utilisables en production. Testé sous Debian, Ubuntu, Red Hat Enterprise Linux et Rocky Linux. + +- Commandes installées avec Homebrew : + - [kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/) + - [helm](https://helm.sh/docs/intro/install/) + - [yq](https://github.com/mikefarah/yq/#install), facultative mais utile pour debug. + - [age](https://github.com/FiloSottile/age#installation), outil de chiffrement qui fournit les commandes `age` et `age-keygen` nécessaires pour l'installation de SOPS. diff --git a/hexaforge/installation/secrets.md b/hexaforge/installation/secrets.md new file mode 100644 index 0000000..8de5d52 --- /dev/null +++ b/hexaforge/installation/secrets.md @@ -0,0 +1,33 @@ +# Récupération des secrets + +Au moment de leur initialisation, certains outils stoquent des secrets qui ne sont en principe plus disponibles ultérieurement. + +**Attention !** Pour garantir l'[idempotence](https://fr.wikipedia.org/wiki/Idempotence), ces secrets sont stockés dans plusieurs ressources du cluster. Supprimer ces ressources **indique à Ansible qu'il doit réinitialiser les composants associés**. + +Afin de faciliter la récupération des secrets, un playbook d'administration nommé « get-credentials.yaml » est mis à disposition dans le répertoire « admin-tools ». + +Pour le lancer : + +```bash +ansible-playbook admin-tools/get-credentials.yaml +``` + +Ce playbook permet également de cibler un outil en particulier, grâce à l'utilisation de tags qui sont listés au début de l'exécution, exemple avec keycloak : + +```bash +ansible-playbook admin-tools/get-credentials.yaml -t keycloak +``` + +Enfin, dans le cas où plusieurs chaînes DSO sont déployées dans le même cluster, il permet de cibler la chaîne DSO voulue via l'utilisation de l'[extra variable](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_variables.html#defining-variables-at-runtime) `dsc_cr`, exemple avec une chaîne utilisant la `dsc` nommée `ma-conf` : + +```bash +ansible-playbook admin-tools/get-credentials.yaml -e dsc_cr=ma-conf +``` + +Et bien sûr cibler un ou plusieurs outils en même temps, via les tags. Exemple : + +```bash +ansible-playbook admin-tools/get-credentials.yaml -e dsc_cr=ma-conf -t keycloak,argocd +``` + +**Remarque importante** : Il est **vivement encouragé** de **sauvegarder les valeurs** qui vous sont fournies par le playbook « get-credentials.yaml ». Par exemple dans un fichier de base de données chiffré de type KeePass ou Bitwarden. Il est toutefois important de **ne pas les modifier ou les supprimer** sous peine de voir certains composants, par exemple Vault, être réinitialisés. diff --git a/hexaforge/installation/uninstallation.md b/hexaforge/installation/uninstallation.md new file mode 100644 index 0000000..af6ddbb --- /dev/null +++ b/hexaforge/installation/uninstallation.md @@ -0,0 +1,70 @@ +# Désinstallation + +## Chaîne complète + +Un playbook de désinstallation nommé « uninstall.yaml » est disponible. + +Il permet de désinstaller **toute la chaîne DSO en une seule fois**. + +Pour le lancer, en vue de désinstaller la chaîne DSO qui utilise la `dsc` par défaut `conf-dso` : + +```bash +ansible-playbook uninstall.yaml +``` + +Vous pourrez ensuite surveiller la déinstallation des namespaces par défaut via la commande suivante : + +```bash +watch "kubectl get ns | grep 'dso-'" +``` + +**Attention !** Si vous souhaitez plutôt désinstaller une autre chaîne, déployée en utilisant votre propre ressource de type `dsc`, alors vous devrez utiliser l'[extra variable](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_variables.html#defining-variables-at-runtime) `dsc_cr`, comme ceci (exemple avec une `dsc` nommée `ma-dsc`) : + +```bash +ansible-playbook uninstall.yaml -e dsc_cr=ma-dsc +``` + +Selon les performances ou la charge de votre cluster, la désinstallation de certains composants (par exemple GitLab) pourra prendre un peu de temps. + +Pour surveiller l'état d'une désinstallation en cours il sera possible, si vous avez correctement préfixé ou suffixé vos namespaces dans votre configuration, de vous appuyer sur la commande suivante. Exemple avec le préfixe « mynamespace- » : + +```bash +watch "kubectl get ns | grep 'mynamespace-'" +``` + +Même exemple, mais avec le suffixe « -mynamespace » : + +```bash +watch "kubectl get ns | grep '\-mynamespace'" +``` + +**Remarques importantes** : + +- Par défaut le playbook de désinstallation, s'il est lancé sans aucun tag, ne supprimera pas les ressources suivantes : + - **Cert-manager** déployé dans le namespace `cert-manager`. + - **CloudNativePG** déployé dans le namespace spécifié par le fichier « config.yaml » du role `socle-config`, déclaré lors de l'installation avec la `dsc` par défaut `conf-dso`. + - **Kubed** déployé dans le namespace `openshift-infra`. +- Les trois composants en question pourraient en effet être utilisés par une autre instance de la chaîne DSO, voire même par d'autres ressources dans le cluster. Si vous avez conscience des risques et que vous voulez malgré tout désinstaller l'un de ces trois outils, vous pourrez le faire via l'utilisation des tags correspondants : + - Pour Kubed : `-t kubed` (ou bien `-t confSyncer`). + - Pour Cert-manager : `-t cert-manager`. + - Pour CloudNativePG : `-t cnpg` (ou bien `-t cloudnativepg`). + +## Désinstaller un ou plusieurs outils + +Le playbook de désinstallation peut aussi être utilisé pour supprimer un ou plusieurs outils **de manière ciblée**, via les tags associés. + +L'idée est de faciliter leur réinstallation complète, en utilisant ensuite le playbook d'installation (voir la sous-section [Réinstallation](#réinstallation) de la section Debug). + +Par exemple, pour désinstaller uniquement les outils Keycloak et ArgoCD configurés avec la `dsc` par défaut (`conf-dso`), la commande sera la suivante : + +```bash +ansible-playbook uninstall.yaml -t keycloak,argocd +``` + +Pour faire la même chose sur les mêmes outils, mais s'appuyant sur une autre configuration (via une `dsc` nommée `ma-dsc`), vous rajouterez là encore l'[extra variable](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_variables.html#defining-variables-at-runtime) `dsc_cr`. Exemple : + +```bash +ansible-playbook uninstall.yaml -t keycloak,argocd -e dsc_cr=ma-dsc +``` + +**Remarque importante** : Si vous désinstallez la ressource **console** via le tag approprié, et que vous souhaitez ensuite la réinstaller, vous devrez impérativement **relancer une installation complète** du socle DSO (sans tags) plutôt que de réinstaller la console seule. En effet, la configmap `dso-config` qui lui est associée est alimentée par les autres outils à mesure de l'installation. diff --git a/hexaforge/installation/versions.md b/hexaforge/installation/versions.md new file mode 100644 index 0000000..f6561e5 --- /dev/null +++ b/hexaforge/installation/versions.md @@ -0,0 +1,345 @@ +# Gel des versions d'images + +Comme indiqué précédemment, le gel des version d'images est géré par le champ `values` que vous pourrez spécifier, pour chaque outil concerné, dans la ressource `dsc` de configuration par défaut (`conf-dso`) ou votre propre `dsc`. + +Ce champ correspond rigoureusement à ce qui est utilisable pour une version donnée du chart Helm de l'outil en question. + +Lors d'une **première installation du socle**, nous vous recommandons de **ne pas geler immédiatement vos versions d'images dans la `dsc`**. En effet, le playbook et les roles associés installeront les dépôts Helm de chaque outil et utiliseront la version d'image qui correspond à la version du chart définie par défaut. + +Ceci vous permettra ensuite d'utiliser la commande `helm` pour rechercher plus facilement les versions d'images disponibles et à quelles versions de charts elles sont associées. + +Lorsque vous gelez vos images dans la `dsc`, il est **fortement recommandé** d'utiliser un tag d'image en adéquation avec la version de chart utilisée, tel que fourni par la commande `helm search repo -l nom-de-mon-outil-ici --version version-de-chart-ici`. + +Lorsque vos values sont à jour **pour tous les outils concernés**, avec les versions d'images désirées, appliquez le changement en utilisant votre fichier de définition. Exemple : + +```bash +kubectl apply -f ma-conf-dso.yaml +``` + +Puis relancez l'[Installation](#installation). + +Les sections suivantes détaillent la façon de procéder au gel de version d'image pour chaque outil : +- [Gel des versions d'images](#gel-des-versions-dimages) + - [Argo CD](#argo-cd) + - [Cert-manager](#cert-manager) + - [CloudNativePG](#cloudnativepg) + - [Console Cloud π Native](#console-cloud-π-native) + - [GitLab](#gitlab) + - [GitLab Runner](#gitlab-runner) + - [Harbor](#harbor) + - [Keycloak](#keycloak) + - [Kubed (config-syncer)](#kubed-config-syncer) + - [Sonatype Nexus Repository](#sonatype-nexus-repository) + - [SonarQube Community Edition](#sonarqube-community-edition) + - [SOPS](#sops) + - [Vault](#vault) + +## 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.7.6-debian-11-r2 + imagePullPolicy: IfNotPresent +``` + +Pour mémoire, les values utilisables sont disponibles ici : + +Les releases d'Argo CD et leurs changelogs se trouvent ici : + +## Cert-manager + +La version d'image utilisée par cert-manager est directement liée à la version de chart déployée. Elle est donc déjà gelée par défaut. + +Il est recommandé de ne pas modifier cette version de chart, sauf si vous savez ce que vous faites. + +## CloudNativePG + +Comme avec cert-manager, il existe une correspondance biunivoque entre la version de chart utilisée et la version d'application ("APP VERSION") de l'opérateur. + +Ainsi, spécifier une version de chart est suffisant pour geler la version d'image au niveau de l'opérateur. + +Il est recommandé de ne pas modifier cette version de chart, sauf si vous savez ce que vous faites. + +Comme indiqué dans sa [documentation officielle](https://cloudnative-pg.io/documentation/1.20/quickstart/#part-3-deploy-a-postgresql-cluster), par défaut CloudNativePG installera la dernière version mineure disponible de la dernière version majeure de PostgreSQL au moment de la publication de l'opérateur. + +De plus, comme l'indique la [FAQ officielle](https://cloudnative-pg.io/documentation/1.20/faq/), CloudNativePG utilise des conteneurs d'application immutables. Cela signifie que le conteneur ne sera pas modifié durant tout son cycle de vie (aucun patch, aucune mise à jour ni changement de configuration). + +## Console Cloud π Native + +La version d'image utilisée par la Console Cloud π Native est directement liée à la version de chart déployée. Elle est donc déjà gelée par défaut. + +Il est recommandé de ne pas modifier cette version de chart, sauf si vous savez ce que vous faites. + +## GitLab + +La version d'image utilisée par GitLab est directement liée à la version de chart déployée. Elle est donc déjà gelée par défaut. + +Par ailleurs le chart Helm de GitLab est déployé via l'opérateur GitLab, lui même déployé via Helm. + +Il existe ainsi une correspondance directe entre la version de chart utilisée pour déployer l'opérateur et les versions de charts GitLab que cet opérateur sera en mesure d'installer. + +Cette correspondance est fournie par la page de documentation suivante : + +https://gitlab.com/gitlab-org/cloud-native/gitlab-operator/-/tags + +Dans le même ordre d'idée, une version de chart GitLab correspond à une version d'instance GitLab. + +La correspondance entre versions de charts GitLab et versions d'instances GitLab est fournie par la page de documentation suivante : + +https://docs.gitlab.com/charts/installation/version_mappings.html + +Il est donc recommandé de ne pas modifier les versions de charts déjà fixées au moment de la sortie du socle, sauf si vous savez ce que vous faites. Dans le cas où vous souhaiteriez les modifier, gardez à l'esprit les correspondances signalées précédemment, entre version du chart de l'opérateur et versions de chart GitLab qu'il peut installer. + +## GitLab Runner + +La version d'image utilisée par GitLab Runner est directement liée à la version de chart déployée. Elle est donc déjà gelée par défaut. + +Il est recommandé de ne pas modifier cette version de chart, sauf si vous savez ce que vous faites. + +Si toutefois vous souhaitez la modifier, sachez que la version majeure.mineure de l'instance GitLab Runner doit idéalement correspondre à celle de l'instance GitLab, comme expliqué ici : + +https://docs.gitlab.com/runner/#gitlab-runner-versions + +## Harbor + +Fixer le numéro de version du chart Helm sera normalement suffisant pour fixer aussi le numéro de version des images associées. Le numéro de version de ces images sera celui visible dans la colonne "APP VERSION" de la commande `helm search repo -l harbor/harbor`. + +Il est toutefois possible de fixer les versions d'images pour Harbor de façon plus fine (**recommandé en production**). + +Il sera ainsi possible de fixer l'image de chacun des composants. + +Les différents tags utilisables sont disponibles ici : + +- nginx : +- portal : +- core : +- jobservice : +- registry (registry) : +- registry (controller) : +- trivy : +- notary (server) : +- notary (signer) : +- database : +- redis : +- exporter : + +**Rappel** : Il est néanmoins recommandé de positionner des tags d'images en adéquation avec la version du chart Helm utilisée et documentée dans le fichier [versions](https://github.com/cloud-pi-native/socle/versions), situé à la racine du socle, c'est à dire d'utiliser le numéro "APP VERSION" retourné par la commande `helm search repo -l harbor/harbor --version numero-de-version-de-chart`. + +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.13.1 du chart : + +```yaml +harbor: + adminPassword: WhoWantsToPassForever + pvcRegistrySize: 50Gi + values: + nginx: + image: + repository: docker.io/goharbor/nginx-photon + tag: v2.9.1 + portal: + image: + repository: docker.io/goharbor/harbor-portal + tag: v2.9.1 + core: + image: + repository: docker.io/goharbor/harbor-core + tag: v2.9.1 + jobservice: + image: + repository: docker.io/goharbor/harbor-jobservice + tag: v2.9.1 + registry: + registry: + image: + repository: docker.io/goharbor/registry-photon + tag: v2.9.1 + controller: + image: + repository: docker.io/goharbor/harbor-registryctl + tag: v2.9.1 + trivy: + image: + repository: docker.io/goharbor/trivy-adapter-photon + tag: v2.9.1 + notary: + server: + image: + repository: docker.io/goharbor/notary-server-photon + tag: v2.9.1 + signer: + image: + repository: docker.io/goharbor/notary-signer-photon + tag: v2.9.1 + database: + internal: + image: + repository: docker.io/goharbor/harbor-db + tag: v2.9.1 + redis: + internal: + image: + repository: docker.io/goharbor/redis-photon + tag: v2.9.1 + exporter: + image: + repository: docker.io/goharbor/harbor-exporter + tag: v2.9.1 +``` + +Pour mémoire, les values utilisables sont disponibles et documentées ici : + +## Keycloak + +Le composant Keycloak est installé à l'aide du chart Helm Bitnami. + +Nous utiliserons un tag dit "[immutable](https://docs.bitnami.com/kubernetes/apps/keycloak/configuration/understand-rolling-immutable-tags/)" (**recommandé en production**). + +Les différents tags utilisables pour l'image de Keycloak 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 "19.0.3-debian-11-r22" 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 +keycloak: + values: + image: + registry: docker.io + repository: bitnami/keycloak + tag: 19.0.3-debian-11-r22 +``` + +Pour mémoire, les values utilisables sont disponibles ici : + +Les release notes de Keycloak se trouvent ici : + +## Kubed (config-syncer) + +La version d'image utilisée par Kubed est directement liée à la version de chart déployée. Elle est donc déjà gelée par défaut. + +Il est recommandé de ne pas modifier cette version de chart, sauf si vous savez ce que vous faites. + +## Sonatype Nexus Repository + +Le composant nexus est installé directement via le manifest de deployment « nexus.yml.j2 » intégré au role associé. + +L'image utilisée est déjà gelée. Son numéro de version est spécifié dans le fichier [versions](https://github.com/cloud-pi-native/socle/versions) situé à la racine du socle. + +Il est recommandé de ne pas modifier cette version, sauf si vous savez ce que vous faites. + +Si toutefois vous souhaitez la modifier, les tags d'images utilisables sont disponibles ici : + +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.56.0 +``` + +## SonarQube Community Edition + +Le composant SonarQube est installé via son [chart Helm officiel](https://github.com/SonarSource/helm-chart-sonarqube/tree/master/charts/sonarqube). + +Les tags d'images utilisables sont ceux retournés par la commande suivante, au niveau de la colonne "APP VERSION" : + +```bash +helm search repo -l sonarqube/sonarqube +``` + +Il faudra juste leur ajouter le suffixe "-community" qui correspond à l'édition utilisée, ou bien le suffixe -{{ .Values.edition }} si nous précisons aussi l'édition dans nos values. + +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: 9.9.2-{{ .Values.edition }} +``` + +## SOPS + +Fixer la version d'image de SOPS sera **recommandé en production**. + +Pour spécifier cette version d'image, 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 +sops: + namespace: mynamespace-sops + values: + image: + tag: 0.11.0 +``` + +Pour mémoire, les values utilisables sont disponibles et documentées ici : + +Les numéros de version de chart Helm et d'image se trouvent ici : + +S'agissant de l'image, ces numéros correspondent à la colonne "Operator". + +Il est également possible de les retrouver via la commande de recherche dans vos dépôts Helm vue précédemment : + +```bash +helm search repo -l sops/sops-secrets-operator +``` + +Ceci à condition que vos dépôts soient à jour. + +## Vault + +Fixer les versions d'images de Vault est **recommandé en production**. + +Les values utilisables sont disponibles et documentées ici : + +Il sera possible de fixer l'image : +- du Vault Agent Sidecar Injector (via le repository hashicorp/vault-k8s), +- du Vault Agent (via le repository hashicorp/vault). + +Les différents tags d'images utilisables sont disponibles ici : +- Pour le Vault Agent Sidecar Injector : +- Pour le Vault Agent : + +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 +``` + +**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é. diff --git a/hexaforge/platform/compatibility.md b/hexaforge/platform/compatibility.md new file mode 100644 index 0000000..c7cbb6e --- /dev/null +++ b/hexaforge/platform/compatibility.md @@ -0,0 +1,19 @@ +# Compatibilité Cloud π Native + +## Prérequis techniques + +Les critères permettant de déterminer la compatibilité de vos applications à la plateforme Cloud π Native : +- Vos applications doivent être conteneurisés sur une souche d'OS Linux. Les applications nécessitant un OS Windows ne sont pas éligibles à l'offre. +- Vos applications doivent être **sans état** (`stateless`) et partir du principe qu'un composant applicatif (`pod`) peut être détruit à tout moment. Le stockage persistant de données est porté **principalement** par les bases de données. En cas de maintien de session applicative, un déport vers un composant de type Redis est nécessaire. +- La configuration de vos applications se font par leurs environnement (principalement par des variables d'environnements). Seuls ces éléments changent entre vos environnements applicatifs (environnement dev et production par exemple) : il s'agit de la même image de conteneur déployée avec un configuration différente. +- Vos images de conteneurs doivent être **rootless**. +- Le FileSystem de vos images de conteneurs doivent être en lecture seule. + +## Prérequis organisationnels + +- Avoir un compte dans le service SSO (Keycloak) de la plateforme Cloud π Native. +- Dans le cas ou votre dépôt de source externe est privé, un jeton d'accès personnel (PAT dans GiHub) avec le scope `repo` permettant de pull le dépôt sera demandé lors de l'enrolement sur la plateforme Cloud π Native. + +## Prérequis techniques + +Cf. [les bonnes pratiques](/guide/best-practices) diff --git a/hexaforge/platform/glossary.md b/hexaforge/platform/glossary.md new file mode 100644 index 0000000..9077648 --- /dev/null +++ b/hexaforge/platform/glossary.md @@ -0,0 +1,16 @@ +# Glossaire + +| Nom | Description | +| ------------- | -------------------------------------------------------------------------------------------------------------- | +| Argocd | Service de déploiement automatique (GitOps) | +| Console | Application web permettant de consommer la plateforme (en quelque sorte le cerveau) | +| Dépôt externe | Dépôt de code sur lequel travaillent les utilisateurs au quotidien | +| Dépôt interne | Dépôt de code interne de la plateforme vers lequel est cloné le dépôt externe | +| DSO | DSO pour DevSecOps est le nom communément utilisé par les équipes Cloud Pi Native pour parler de la plateforme | +| GitLab | Service d'hébergement de code source et service de CI/CD | +| Gitops | Système de déploiement via l'observation de code source dans un dépôt | +| Harbor | Service d'hébergement d'image de conteneur | +| Nexus | Service d'hébergement d'artefacts (ex: lib npm) | +| Sonarqube | Service d'analyse de la qualité de code | +| Vault | Service d'hébergement de secrets | +| Trivy | Service d'analyse de CVE dans les images de conteneur | diff --git a/hexaforge/platform/introduction.md b/hexaforge/platform/introduction.md new file mode 100644 index 0000000..29cd642 --- /dev/null +++ b/hexaforge/platform/introduction.md @@ -0,0 +1,50 @@ +# Introduction + +Le PaaS (Platform-as-a-Service) est une forme de cloud computing dans laquelle la plateforme logicielle est fournie par un tiers. D'abord destiné aux développeurs et aux programmeurs, le PaaS permet à l'utilisateur de développer, d'exécuter et de gérer ses propres applications, sans avoir à créer ni entretenir l'infrastructure ou la plateforme généralement associée au processus. + +Les plateformes PaaS peuvent s'exécuter dans le cloud ou sur site. En ce qui concerne les offres gérées, le fournisseur héberge le matériel et les logiciels sur sa propre infrastructure et met à disposition de l'utilisateur une plateforme, sous la forme d'une solution intégrée, d'une pile de solutions ou d'un service. + +## Description de la plateforme + +Cloud π Native est composée d'une **plateforme de services Open Source** à destination des équipes DevSecOps. + +**La plateforme** comprend: + +- Une [usine de logicielle](https://github.com/cloud-pi-native/socle) qui utilise plusieurs services. +- Une [console](https://github.com/cloud-pi-native/console) Web consommant ses services afin de construire et déployer vos ressources applicatives (projets, membres, environnements, etc). Il est aussi possible d'enregistrer des services supplémentaires grâce à son `architecture core / plugins`. Chaque plugin s'enregistre sur des hooks liés au cycle de vie du projet (création d'un projet, d'un environnement ou d'un dépôt, ajout d'un membre, etc...). Les plugins enregistrés recoivent l'ensemble des informations liées aux actions sur les projets par le biais du gestionnaire de plugins. L'ajout d'un nouveau plugin est détaillé [ici](https://github.com/cloud-pi-native/console/blob/main/misc/plugins.md) + +## Architecture fonctionnelle de la plateforme + +![archi](/img/architecture.png) + +## Services core proposés par la plateforme + +Liste des services de la plateforme : + +| Service | Description | Obligatoire | +| -------------- | ------------------------------------------ | ----------- | +| Argocd | Outil de déploiement automatique (GitOps) | Oui | +| Harbor / Trivy | Hébergement / analyse d'image de conteneur | Oui | +| GitLab | Hébergement de code et pipeline CI/CD | Oui | +| Kubernetes | Création des ressources kubernetes | Oui | +| Nexus | Hébergement d'artefacts | Oui [1] | +| Sonarqube | Analyse de qualité de code | Oui | +| Vault | Hébergement de secrets | Oui | + +[1] : *Instanciation au niveau du projet obligatoire mais utilisation selon le besoin.* + +## Ambition + +L'ambition de cette plateforme est de proposer aux équipes projets une offre de services large, complète déployée au sein d'un cloud souverain et permettant d'automatiser la construction et le déploiement de vos projets en assurant les standards de qualité et sécurité. + +Pour pouvoir manipuler les services de cette plateforme, la première étape consister à synchroniser le code applicatif depuis un repo externe accéssible depuis la plateforme. + +La chaine de CI/CD sur le GitLab de la plateforme permet: + +- Lancer vos jeux de tests applicatif (unitaires, de bout en bout, ...). +- Effectuer une analyse de la qualité de votre code source à l'aide du service [Sonarqube](https://www.sonarqube.org/). +- Construire vos images de conteneur de l'application dans la CI/CD du service [GitLab](https://about.gitlab.com/). +- Scanner vos images et le code source à l'aide de [Trivy](https://aquasecurity.github.io/trivy). +- Stocker vos images dans un registry de conteneurs dans la plateforme: [Harbor](https://goharbor.io/). + +Une fois l'application construite et les images de cette dernière stockées dans la registry de la plateforme, le déploiement sur un cluster kubernetes pourra être effectué selon le modèle gitops à l'aide du service [ArgoCD](https://argo-cd.readthedocs.io/en/stable/). diff --git a/hexaforge/platform/roadmap.md b/hexaforge/platform/roadmap.md new file mode 100644 index 0000000..93ddb75 --- /dev/null +++ b/hexaforge/platform/roadmap.md @@ -0,0 +1,3 @@ +# Feuille de route + +:construction: *Disponible prochainement* :construction: diff --git a/hexaforge/platform/skills-matrix.md b/hexaforge/platform/skills-matrix.md new file mode 100644 index 0000000..a600d87 --- /dev/null +++ b/hexaforge/platform/skills-matrix.md @@ -0,0 +1,24 @@ +# Matrice de compétences + +Cette page liste les technologies nécessaires à maitriser avant d'utiliser la plateforme Cloud π Native. + +## Compétences + +| Technologie | Commentaires | +| ---------------- | ---------------------------------------------------------------------------------------------------------------- | +| Conteneurisation | **Obligatoire** Connaitre les principes de construction et de lancement d'images Docker | +| Kubernetes | **Obligatoire** Connaître et comprendre les principes et objets principaux de k8s et les manifest de déploiement | +| GitLab-CI | **Obligatoire** Connaître les pipelines de déploiements gitlab-ci | +| Helm | **Conseillé** Savoir utiliser et créer un chart HELM | +| GitOps | **Obligatoire** Comprendre les principes de déploiement GitOps | +| Openshift | **Conseillé** Comprendre les différences avec kubernetes | +| GitOps/ArgoCD | **Conseillé** Connaitre l'utilisation d'ArgoCD | + +## Liens utiles + +- [Kubernetes Basics: Pods, Nodes, Containers, Deployments and Clusters](https://www.youtube.com/watch?v=B_X4l4HSgtc) - *video en anglais* +- [Kubernetes in 5 mins](https://www.youtube.com/watch?v=PH-2FfFD2PU) - *video en anglais* +- [Adapting Docker and Kubernetes containers to run on Red Hat OpenShift Container Platform](https://developers.redhat.com/blog/2020/10/26/adapting-docker-and-kubernetes-containers-to-run-on-red-hat-openshift-container-platform#) - *article en anglais* +- [Building rootless containers for JavaScript front ends](https://developers.redhat.com/blog/2021/03/04/building-rootless-containers-for-javascript-front-ends#) - *article en anglais* +- [What is GitOps?](https://about.gitlab.com/topics/gitops/) - article en anglais* +- [Appréhender le GitOps, le déploiement continu façon kube native](https://blog.wescale.fr/appr%C3%A9hender-le-gitops-le-d%C3%A9ploiement-continu-fa%C3%A7on-kube-native) diff --git a/hexaforge/public/examples/postgres.yaml b/hexaforge/public/examples/postgres.yaml new file mode 100644 index 0000000..fcf45ad --- /dev/null +++ b/hexaforge/public/examples/postgres.yaml @@ -0,0 +1,71 @@ +--- +apiVersion: v1 +kind: PersistentVolumeClaim # Create PVC +metadata: + namespace: mynamespace + name: postgresql-data-claim # Sets name of PV +spec: + accessModes: + - ReadWriteOnce # Sets read and write access + resources: + requests: + storage: 1Gi # Sets volume size +--- +apiVersion: v1 +kind: Service +metadata: + namespace: mynamespace + name: postgres # Sets service name + labels: + app: postgres # Labels and Selectors +spec: + type: ClusterIP # Sets service type + ports: + - port: 5432 # Sets port to run the postgres application + selector: + app: postgres +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: mynamespace + name: postgres-demo # Sets Deployment name +spec: + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + app: postgres + template: + metadata: + labels: + app: postgres + spec: + containers: + - name: postgres + image: bitnami/postgresql:14.9.0 + imagePullPolicy: IfNotPresent + ports: + - containerPort: 5432 # Exposes container port + env: + - name: POSTGRES_USER + value: demo_user + - name: POSTGRES_PASSWORD + value: "My$ecrETPAss0rd*" + - name: POSTGRES_DB + value: demo + - name: POSTGRESQL_DATABASE + value: demo + volumeMounts: + - mountPath: /bitnami/postgresql + name: postgredb + resources: + limits: + memory: 512Mi + cpu: 500m + restartPolicy: Always + volumes: + - name: postgredb + persistentVolumeClaim: + claimName: postgresql-data-claim diff --git "a/hexaforge/public/img/agreement/acces_services_observabilit\303\251.png" "b/hexaforge/public/img/agreement/acces_services_observabilit\303\251.png" new file mode 100644 index 0000000..cbc7e77 Binary files /dev/null and "b/hexaforge/public/img/agreement/acces_services_observabilit\303\251.png" differ diff --git a/hexaforge/public/img/architecture.png b/hexaforge/public/img/architecture.png new file mode 100644 index 0000000..932f597 Binary files /dev/null and b/hexaforge/public/img/architecture.png differ diff --git a/hexaforge/public/img/argocd-example.png b/hexaforge/public/img/argocd-example.png new file mode 100644 index 0000000..5f3e6c8 Binary files /dev/null and b/hexaforge/public/img/argocd-example.png differ diff --git a/hexaforge/public/img/argocd.png b/hexaforge/public/img/argocd.png new file mode 100644 index 0000000..e078eb3 Binary files /dev/null and b/hexaforge/public/img/argocd.png differ diff --git a/hexaforge/public/img/console_admin/cluster_ajout.png b/hexaforge/public/img/console_admin/cluster_ajout.png new file mode 100644 index 0000000..45b5242 Binary files /dev/null and b/hexaforge/public/img/console_admin/cluster_ajout.png differ diff --git a/hexaforge/public/img/console_admin/cluster_details_env.png b/hexaforge/public/img/console_admin/cluster_details_env.png new file mode 100644 index 0000000..7d08c61 Binary files /dev/null and b/hexaforge/public/img/console_admin/cluster_details_env.png differ diff --git a/hexaforge/public/img/console_admin/cluster_liste.png b/hexaforge/public/img/console_admin/cluster_liste.png new file mode 100644 index 0000000..d8db5b1 Binary files /dev/null and b/hexaforge/public/img/console_admin/cluster_liste.png differ diff --git a/hexaforge/public/img/console_admin/cluster_suppression.png b/hexaforge/public/img/console_admin/cluster_suppression.png new file mode 100644 index 0000000..3881090 Binary files /dev/null and b/hexaforge/public/img/console_admin/cluster_suppression.png differ diff --git a/hexaforge/public/img/console_admin/create_org.png b/hexaforge/public/img/console_admin/create_org.png new file mode 100644 index 0000000..1df05a5 Binary files /dev/null and b/hexaforge/public/img/console_admin/create_org.png differ diff --git a/hexaforge/public/img/console_admin/environnement_creation.png b/hexaforge/public/img/console_admin/environnement_creation.png new file mode 100644 index 0000000..dcfd3c8 Binary files /dev/null and b/hexaforge/public/img/console_admin/environnement_creation.png differ diff --git a/hexaforge/public/img/console_admin/journaux_erreur.png b/hexaforge/public/img/console_admin/journaux_erreur.png new file mode 100644 index 0000000..223ace1 Binary files /dev/null and b/hexaforge/public/img/console_admin/journaux_erreur.png differ diff --git a/hexaforge/public/img/console_admin/menu_admin.png b/hexaforge/public/img/console_admin/menu_admin.png new file mode 100644 index 0000000..e092cfe Binary files /dev/null and b/hexaforge/public/img/console_admin/menu_admin.png differ diff --git a/hexaforge/public/img/console_admin/plugin_configuration.png b/hexaforge/public/img/console_admin/plugin_configuration.png new file mode 100644 index 0000000..8f30681 Binary files /dev/null and b/hexaforge/public/img/console_admin/plugin_configuration.png differ diff --git a/hexaforge/public/img/console_admin/projet_detail.png b/hexaforge/public/img/console_admin/projet_detail.png new file mode 100644 index 0000000..13ef6e2 Binary files /dev/null and b/hexaforge/public/img/console_admin/projet_detail.png differ diff --git a/hexaforge/public/img/console_admin/quota_creation.png b/hexaforge/public/img/console_admin/quota_creation.png new file mode 100644 index 0000000..5ae568a Binary files /dev/null and b/hexaforge/public/img/console_admin/quota_creation.png differ diff --git a/hexaforge/public/img/console_admin/recherche_projet.png b/hexaforge/public/img/console_admin/recherche_projet.png new file mode 100644 index 0000000..d794163 Binary files /dev/null and b/hexaforge/public/img/console_admin/recherche_projet.png differ diff --git a/hexaforge/public/img/console_admin/recherche_utilisateurs.png b/hexaforge/public/img/console_admin/recherche_utilisateurs.png new file mode 100644 index 0000000..dac8c48 Binary files /dev/null and b/hexaforge/public/img/console_admin/recherche_utilisateurs.png differ diff --git a/hexaforge/public/img/console_admin/zone_creation.png b/hexaforge/public/img/console_admin/zone_creation.png new file mode 100644 index 0000000..86d9627 Binary files /dev/null and b/hexaforge/public/img/console_admin/zone_creation.png differ diff --git a/hexaforge/public/img/creation.png b/hexaforge/public/img/creation.png new file mode 100644 index 0000000..fc74f50 Binary files /dev/null and b/hexaforge/public/img/creation.png differ diff --git a/hexaforge/public/img/environnement/cluster-env.png b/hexaforge/public/img/environnement/cluster-env.png new file mode 100644 index 0000000..66b491f Binary files /dev/null and b/hexaforge/public/img/environnement/cluster-env.png differ diff --git a/hexaforge/public/img/environnement/create-env.png b/hexaforge/public/img/environnement/create-env.png new file mode 100644 index 0000000..3dab74e Binary files /dev/null and b/hexaforge/public/img/environnement/create-env.png differ diff --git a/hexaforge/public/img/environnement/menu.png b/hexaforge/public/img/environnement/menu.png new file mode 100644 index 0000000..891dfb3 Binary files /dev/null and b/hexaforge/public/img/environnement/menu.png differ diff --git a/hexaforge/public/img/environnement/quota-env.png b/hexaforge/public/img/environnement/quota-env.png new file mode 100644 index 0000000..3ad96f7 Binary files /dev/null and b/hexaforge/public/img/environnement/quota-env.png differ diff --git a/hexaforge/public/img/environnement/type-env.png b/hexaforge/public/img/environnement/type-env.png new file mode 100644 index 0000000..2192230 Binary files /dev/null and b/hexaforge/public/img/environnement/type-env.png differ diff --git a/hexaforge/public/img/gitlab-ci-read-secrets.png b/hexaforge/public/img/gitlab-ci-read-secrets.png new file mode 100644 index 0000000..8e5d15c Binary files /dev/null and b/hexaforge/public/img/gitlab-ci-read-secrets.png differ diff --git a/hexaforge/public/img/gitlab-ci-vault.png b/hexaforge/public/img/gitlab-ci-vault.png new file mode 100644 index 0000000..b230970 Binary files /dev/null and b/hexaforge/public/img/gitlab-ci-vault.png differ diff --git a/hexaforge/public/img/gitlab.png b/hexaforge/public/img/gitlab.png new file mode 100644 index 0000000..dfa91c2 Binary files /dev/null and b/hexaforge/public/img/gitlab.png differ diff --git a/hexaforge/public/img/gitlab.svg b/hexaforge/public/img/gitlab.svg new file mode 100644 index 0000000..602ffcc --- /dev/null +++ b/hexaforge/public/img/gitlab.svg @@ -0,0 +1 @@ +GitLab home page \ No newline at end of file diff --git a/hexaforge/public/img/gitops.png b/hexaforge/public/img/gitops.png new file mode 100644 index 0000000..8c310d8 Binary files /dev/null and b/hexaforge/public/img/gitops.png differ diff --git a/hexaforge/public/img/global-vision.png b/hexaforge/public/img/global-vision.png new file mode 100644 index 0000000..63bdaae Binary files /dev/null and b/hexaforge/public/img/global-vision.png differ diff --git a/hexaforge/public/img/guide/alerting/alert_firing.png b/hexaforge/public/img/guide/alerting/alert_firing.png new file mode 100644 index 0000000..7b31a53 Binary files /dev/null and b/hexaforge/public/img/guide/alerting/alert_firing.png differ diff --git a/hexaforge/public/img/guide/alerting/alert_ns_group.png b/hexaforge/public/img/guide/alerting/alert_ns_group.png new file mode 100644 index 0000000..e3a8d42 Binary files /dev/null and b/hexaforge/public/img/guide/alerting/alert_ns_group.png differ diff --git a/hexaforge/public/img/guide/alerting/contact_point_create.png b/hexaforge/public/img/guide/alerting/contact_point_create.png new file mode 100644 index 0000000..c63224c Binary files /dev/null and b/hexaforge/public/img/guide/alerting/contact_point_create.png differ diff --git a/hexaforge/public/img/guide/alerting/contact_point_manager.png b/hexaforge/public/img/guide/alerting/contact_point_manager.png new file mode 100644 index 0000000..6238e28 Binary files /dev/null and b/hexaforge/public/img/guide/alerting/contact_point_manager.png differ diff --git a/hexaforge/public/img/guide/alerting/create_alert_step_1.png b/hexaforge/public/img/guide/alerting/create_alert_step_1.png new file mode 100644 index 0000000..5540ec4 Binary files /dev/null and b/hexaforge/public/img/guide/alerting/create_alert_step_1.png differ diff --git a/hexaforge/public/img/guide/alerting/create_alert_step_2.png b/hexaforge/public/img/guide/alerting/create_alert_step_2.png new file mode 100644 index 0000000..fb34276 Binary files /dev/null and b/hexaforge/public/img/guide/alerting/create_alert_step_2.png differ diff --git a/hexaforge/public/img/guide/alerting/create_alert_step_3.png b/hexaforge/public/img/guide/alerting/create_alert_step_3.png new file mode 100644 index 0000000..b6aad0c Binary files /dev/null and b/hexaforge/public/img/guide/alerting/create_alert_step_3.png differ diff --git a/hexaforge/public/img/guide/alerting/create_alert_step_4.png b/hexaforge/public/img/guide/alerting/create_alert_step_4.png new file mode 100644 index 0000000..9667ca8 Binary files /dev/null and b/hexaforge/public/img/guide/alerting/create_alert_step_4.png differ diff --git a/hexaforge/public/img/guide/alerting/create_alert_step_5.png b/hexaforge/public/img/guide/alerting/create_alert_step_5.png new file mode 100644 index 0000000..39e8787 Binary files /dev/null and b/hexaforge/public/img/guide/alerting/create_alert_step_5.png differ diff --git a/hexaforge/public/img/guide/alerting/notification_policies.png b/hexaforge/public/img/guide/alerting/notification_policies.png new file mode 100644 index 0000000..42e3dfe Binary files /dev/null and b/hexaforge/public/img/guide/alerting/notification_policies.png differ diff --git a/hexaforge/public/img/guide/alerting/notification_policy_nested_create.png b/hexaforge/public/img/guide/alerting/notification_policy_nested_create.png new file mode 100644 index 0000000..85043c6 Binary files /dev/null and b/hexaforge/public/img/guide/alerting/notification_policy_nested_create.png differ diff --git a/hexaforge/public/img/guide/alerting/policy_default.png b/hexaforge/public/img/guide/alerting/policy_default.png new file mode 100644 index 0000000..6e425f5 Binary files /dev/null and b/hexaforge/public/img/guide/alerting/policy_default.png differ diff --git a/hexaforge/public/img/guide/dashboard_infra.png b/hexaforge/public/img/guide/dashboard_infra.png new file mode 100644 index 0000000..0701e41 Binary files /dev/null and b/hexaforge/public/img/guide/dashboard_infra.png differ diff --git a/hexaforge/public/img/guide/grafana-sign-in.png b/hexaforge/public/img/guide/grafana-sign-in.png new file mode 100644 index 0000000..0ddfb82 Binary files /dev/null and b/hexaforge/public/img/guide/grafana-sign-in.png differ diff --git a/hexaforge/public/img/guide/grafana_add_visualization.png b/hexaforge/public/img/guide/grafana_add_visualization.png new file mode 100644 index 0000000..963e6b1 Binary files /dev/null and b/hexaforge/public/img/guide/grafana_add_visualization.png differ diff --git a/hexaforge/public/img/guide/grafana_create_alert.png b/hexaforge/public/img/guide/grafana_create_alert.png new file mode 100644 index 0000000..ed892f4 Binary files /dev/null and b/hexaforge/public/img/guide/grafana_create_alert.png differ diff --git a/hexaforge/public/img/guide/grafana_dashboard_save.png b/hexaforge/public/img/guide/grafana_dashboard_save.png new file mode 100644 index 0000000..ec481b0 Binary files /dev/null and b/hexaforge/public/img/guide/grafana_dashboard_save.png differ diff --git a/hexaforge/public/img/guide/grafana_dashboard_submenu.png b/hexaforge/public/img/guide/grafana_dashboard_submenu.png new file mode 100644 index 0000000..ae2c9bb Binary files /dev/null and b/hexaforge/public/img/guide/grafana_dashboard_submenu.png differ diff --git a/hexaforge/public/img/guide/grafana_first_dashboard.png b/hexaforge/public/img/guide/grafana_first_dashboard.png new file mode 100644 index 0000000..a462335 Binary files /dev/null and b/hexaforge/public/img/guide/grafana_first_dashboard.png differ diff --git a/hexaforge/public/img/guide/grafana_first_visualization.png b/hexaforge/public/img/guide/grafana_first_visualization.png new file mode 100644 index 0000000..4e1be9a Binary files /dev/null and b/hexaforge/public/img/guide/grafana_first_visualization.png differ diff --git a/hexaforge/public/img/guide/grafana_first_visualization_metrics.png b/hexaforge/public/img/guide/grafana_first_visualization_metrics.png new file mode 100644 index 0000000..614edf1 Binary files /dev/null and b/hexaforge/public/img/guide/grafana_first_visualization_metrics.png differ diff --git a/hexaforge/public/img/guide/grafana_first_visualization_option.png b/hexaforge/public/img/guide/grafana_first_visualization_option.png new file mode 100644 index 0000000..2c5898d Binary files /dev/null and b/hexaforge/public/img/guide/grafana_first_visualization_option.png differ diff --git a/hexaforge/public/img/guide/grafana_first_visualization_time_window.png b/hexaforge/public/img/guide/grafana_first_visualization_time_window.png new file mode 100644 index 0000000..a3b5f03 Binary files /dev/null and b/hexaforge/public/img/guide/grafana_first_visualization_time_window.png differ diff --git a/hexaforge/public/img/guide/grafana_list_dashboard_final.png b/hexaforge/public/img/guide/grafana_list_dashboard_final.png new file mode 100644 index 0000000..6c1f975 Binary files /dev/null and b/hexaforge/public/img/guide/grafana_list_dashboard_final.png differ diff --git a/hexaforge/public/img/guide/grafana_menu.png b/hexaforge/public/img/guide/grafana_menu.png new file mode 100644 index 0000000..b32644c Binary files /dev/null and b/hexaforge/public/img/guide/grafana_menu.png differ diff --git a/hexaforge/public/img/guide/grafana_menu_alerting.png b/hexaforge/public/img/guide/grafana_menu_alerting.png new file mode 100644 index 0000000..35a8cd0 Binary files /dev/null and b/hexaforge/public/img/guide/grafana_menu_alerting.png differ diff --git a/hexaforge/public/img/guide/grafana_menu_dashboard.png b/hexaforge/public/img/guide/grafana_menu_dashboard.png new file mode 100644 index 0000000..bafe7f7 Binary files /dev/null and b/hexaforge/public/img/guide/grafana_menu_dashboard.png differ diff --git a/hexaforge/public/img/guide/grafana_new_dashboard.png b/hexaforge/public/img/guide/grafana_new_dashboard.png new file mode 100644 index 0000000..aed97f5 Binary files /dev/null and b/hexaforge/public/img/guide/grafana_new_dashboard.png differ diff --git a/hexaforge/public/img/guide/grafana_visualization_save.png b/hexaforge/public/img/guide/grafana_visualization_save.png new file mode 100644 index 0000000..acaa886 Binary files /dev/null and b/hexaforge/public/img/guide/grafana_visualization_save.png differ diff --git a/hexaforge/public/img/guide/kibana/authorize.png b/hexaforge/public/img/guide/kibana/authorize.png new file mode 100644 index 0000000..8e5b6d0 Binary files /dev/null and b/hexaforge/public/img/guide/kibana/authorize.png differ diff --git a/hexaforge/public/img/guide/kibana/create_index_pattern.png b/hexaforge/public/img/guide/kibana/create_index_pattern.png new file mode 100644 index 0000000..87f1a3b Binary files /dev/null and b/hexaforge/public/img/guide/kibana/create_index_pattern.png differ diff --git a/hexaforge/public/img/guide/kibana/create_index_timestamp.png b/hexaforge/public/img/guide/kibana/create_index_timestamp.png new file mode 100644 index 0000000..ad29366 Binary files /dev/null and b/hexaforge/public/img/guide/kibana/create_index_timestamp.png differ diff --git a/hexaforge/public/img/guide/kibana/create_index_valid.png b/hexaforge/public/img/guide/kibana/create_index_valid.png new file mode 100644 index 0000000..2a48b98 Binary files /dev/null and b/hexaforge/public/img/guide/kibana/create_index_valid.png differ diff --git a/hexaforge/public/img/guide/kibana/discover.png b/hexaforge/public/img/guide/kibana/discover.png new file mode 100644 index 0000000..3633ad5 Binary files /dev/null and b/hexaforge/public/img/guide/kibana/discover.png differ diff --git a/hexaforge/public/img/guide/kibana/discover_available_fields.png b/hexaforge/public/img/guide/kibana/discover_available_fields.png new file mode 100644 index 0000000..d2a2615 Binary files /dev/null and b/hexaforge/public/img/guide/kibana/discover_available_fields.png differ diff --git a/hexaforge/public/img/guide/kibana/discover_query.png b/hexaforge/public/img/guide/kibana/discover_query.png new file mode 100644 index 0000000..9f3afe5 Binary files /dev/null and b/hexaforge/public/img/guide/kibana/discover_query.png differ diff --git a/hexaforge/public/img/guide/kibana/discover_results.png b/hexaforge/public/img/guide/kibana/discover_results.png new file mode 100644 index 0000000..8439338 Binary files /dev/null and b/hexaforge/public/img/guide/kibana/discover_results.png differ diff --git a/hexaforge/public/img/guide/kibana/discover_time.png b/hexaforge/public/img/guide/kibana/discover_time.png new file mode 100644 index 0000000..f025d1c Binary files /dev/null and b/hexaforge/public/img/guide/kibana/discover_time.png differ diff --git a/hexaforge/public/img/guide/kibana/log-in.png b/hexaforge/public/img/guide/kibana/log-in.png new file mode 100644 index 0000000..6c31310 Binary files /dev/null and b/hexaforge/public/img/guide/kibana/log-in.png differ diff --git a/hexaforge/public/img/guide/kibana_authorize_access.png b/hexaforge/public/img/guide/kibana_authorize_access.png new file mode 100644 index 0000000..439b36a Binary files /dev/null and b/hexaforge/public/img/guide/kibana_authorize_access.png differ diff --git a/hexaforge/public/img/guide/kibana_login_openshift.png b/hexaforge/public/img/guide/kibana_login_openshift.png new file mode 100644 index 0000000..2400de3 Binary files /dev/null and b/hexaforge/public/img/guide/kibana_login_openshift.png differ diff --git a/hexaforge/public/img/guide/project/create_project.png b/hexaforge/public/img/guide/project/create_project.png new file mode 100644 index 0000000..ef20265 Binary files /dev/null and b/hexaforge/public/img/guide/project/create_project.png differ diff --git a/hexaforge/public/img/guide/project/monprojet_secrets.png b/hexaforge/public/img/guide/project/monprojet_secrets.png new file mode 100644 index 0000000..c49b541 Binary files /dev/null and b/hexaforge/public/img/guide/project/monprojet_secrets.png differ diff --git a/hexaforge/public/img/guide/project/monprojet_tableaudebord.png b/hexaforge/public/img/guide/project/monprojet_tableaudebord.png new file mode 100644 index 0000000..71fd76a Binary files /dev/null and b/hexaforge/public/img/guide/project/monprojet_tableaudebord.png differ diff --git a/hexaforge/public/img/guide/project/monprojettuile.png b/hexaforge/public/img/guide/project/monprojettuile.png new file mode 100644 index 0000000..15f5f13 Binary files /dev/null and b/hexaforge/public/img/guide/project/monprojettuile.png differ diff --git a/hexaforge/public/img/guide/repository_synchro.png b/hexaforge/public/img/guide/repository_synchro.png new file mode 100644 index 0000000..1030ab9 Binary files /dev/null and b/hexaforge/public/img/guide/repository_synchro.png differ diff --git a/hexaforge/public/img/learning-process.png b/hexaforge/public/img/learning-process.png new file mode 100644 index 0000000..774ef75 Binary files /dev/null and b/hexaforge/public/img/learning-process.png differ diff --git a/hexaforge/public/img/mocks/add-repo.png b/hexaforge/public/img/mocks/add-repo.png new file mode 100644 index 0000000..9308fb6 Binary files /dev/null and b/hexaforge/public/img/mocks/add-repo.png differ diff --git a/hexaforge/public/img/mocks/mocks-argo-app-details.png b/hexaforge/public/img/mocks/mocks-argo-app-details.png new file mode 100644 index 0000000..fe7efe4 Binary files /dev/null and b/hexaforge/public/img/mocks/mocks-argo-app-details.png differ diff --git a/hexaforge/public/img/mocks/mocks-argo-parameters.png b/hexaforge/public/img/mocks/mocks-argo-parameters.png new file mode 100644 index 0000000..5c1ce1a Binary files /dev/null and b/hexaforge/public/img/mocks/mocks-argo-parameters.png differ diff --git a/hexaforge/public/img/mocks/mocks-argo.png b/hexaforge/public/img/mocks/mocks-argo.png new file mode 100644 index 0000000..f585db6 Binary files /dev/null and b/hexaforge/public/img/mocks/mocks-argo.png differ diff --git a/hexaforge/public/img/nexus.png b/hexaforge/public/img/nexus.png new file mode 100644 index 0000000..809e5fb Binary files /dev/null and b/hexaforge/public/img/nexus.png differ diff --git a/hexaforge/public/img/onboarding-process.png b/hexaforge/public/img/onboarding-process.png new file mode 100644 index 0000000..a1ff773 Binary files /dev/null and b/hexaforge/public/img/onboarding-process.png differ diff --git a/hexaforge/public/img/repo-sync-01.png b/hexaforge/public/img/repo-sync-01.png new file mode 100644 index 0000000..2209920 Binary files /dev/null and b/hexaforge/public/img/repo-sync-01.png differ diff --git a/hexaforge/public/img/repo-sync-02.png b/hexaforge/public/img/repo-sync-02.png new file mode 100644 index 0000000..f2a8f2b Binary files /dev/null and b/hexaforge/public/img/repo-sync-02.png differ diff --git a/hexaforge/public/img/sonarqube.svg b/hexaforge/public/img/sonarqube.svg new file mode 100644 index 0000000..cee213d --- /dev/null +++ b/hexaforge/public/img/sonarqube.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/hexaforge/public/img/team/add.png b/hexaforge/public/img/team/add.png new file mode 100644 index 0000000..11876ef Binary files /dev/null and b/hexaforge/public/img/team/add.png differ diff --git a/hexaforge/public/img/team/members.png b/hexaforge/public/img/team/members.png new file mode 100644 index 0000000..1ff5cd0 Binary files /dev/null and b/hexaforge/public/img/team/members.png differ diff --git a/hexaforge/public/img/team/menu.png b/hexaforge/public/img/team/menu.png new file mode 100644 index 0000000..6867b7e Binary files /dev/null and b/hexaforge/public/img/team/menu.png differ diff --git a/hexaforge/public/img/team/permission-environnement.png b/hexaforge/public/img/team/permission-environnement.png new file mode 100644 index 0000000..c8aac8a Binary files /dev/null and b/hexaforge/public/img/team/permission-environnement.png differ diff --git a/hexaforge/public/img/tuto/1tuto-connexion.png b/hexaforge/public/img/tuto/1tuto-connexion.png new file mode 100644 index 0000000..a57fb5b Binary files /dev/null and b/hexaforge/public/img/tuto/1tuto-connexion.png differ diff --git a/hexaforge/public/img/tuto/2tuto-acces-services.png b/hexaforge/public/img/tuto/2tuto-acces-services.png new file mode 100644 index 0000000..7985660 Binary files /dev/null and b/hexaforge/public/img/tuto/2tuto-acces-services.png differ diff --git a/hexaforge/public/img/tuto/2tuto-commander-projet.png b/hexaforge/public/img/tuto/2tuto-commander-projet.png new file mode 100644 index 0000000..bbe1f4f Binary files /dev/null and b/hexaforge/public/img/tuto/2tuto-commander-projet.png differ diff --git a/hexaforge/public/img/tuto/2tuto-creer-projet-termine.png b/hexaforge/public/img/tuto/2tuto-creer-projet-termine.png new file mode 100644 index 0000000..ab3e77e Binary files /dev/null and b/hexaforge/public/img/tuto/2tuto-creer-projet-termine.png differ diff --git a/hexaforge/public/img/tuto/2tuto-creer-projet.png b/hexaforge/public/img/tuto/2tuto-creer-projet.png new file mode 100644 index 0000000..19ec9a0 Binary files /dev/null and b/hexaforge/public/img/tuto/2tuto-creer-projet.png differ diff --git a/hexaforge/public/img/tuto/2tuto-mes-projets.png b/hexaforge/public/img/tuto/2tuto-mes-projets.png new file mode 100644 index 0000000..4f55c27 Binary files /dev/null and b/hexaforge/public/img/tuto/2tuto-mes-projets.png differ diff --git a/hexaforge/public/img/tuto/3tuto-depots-ajouter-gitlab-ci.png b/hexaforge/public/img/tuto/3tuto-depots-ajouter-gitlab-ci.png new file mode 100644 index 0000000..46cfcb8 Binary files /dev/null and b/hexaforge/public/img/tuto/3tuto-depots-ajouter-gitlab-ci.png differ diff --git a/hexaforge/public/img/tuto/3tuto-depots-ajouter-ok.png b/hexaforge/public/img/tuto/3tuto-depots-ajouter-ok.png new file mode 100644 index 0000000..60a72f8 Binary files /dev/null and b/hexaforge/public/img/tuto/3tuto-depots-ajouter-ok.png differ diff --git a/hexaforge/public/img/tuto/3tuto-depots-ajouter.png b/hexaforge/public/img/tuto/3tuto-depots-ajouter.png new file mode 100644 index 0000000..c22b745 Binary files /dev/null and b/hexaforge/public/img/tuto/3tuto-depots-ajouter.png differ diff --git a/hexaforge/public/img/tuto/3tuto-depots.png b/hexaforge/public/img/tuto/3tuto-depots.png new file mode 100644 index 0000000..50a6405 Binary files /dev/null and b/hexaforge/public/img/tuto/3tuto-depots.png differ diff --git a/hexaforge/public/img/tuto/3tuto-environnement.png b/hexaforge/public/img/tuto/3tuto-environnement.png new file mode 100644 index 0000000..2fbe27d Binary files /dev/null and b/hexaforge/public/img/tuto/3tuto-environnement.png differ diff --git a/hexaforge/public/img/tuto/4argocd-app-details.png b/hexaforge/public/img/tuto/4argocd-app-details.png new file mode 100644 index 0000000..2c3bef3 Binary files /dev/null and b/hexaforge/public/img/tuto/4argocd-app-details.png differ diff --git a/hexaforge/public/img/tuto/4argocd-menus-bouton.png b/hexaforge/public/img/tuto/4argocd-menus-bouton.png new file mode 100644 index 0000000..5498d0f Binary files /dev/null and b/hexaforge/public/img/tuto/4argocd-menus-bouton.png differ diff --git a/hexaforge/public/img/tuto/4argocd-menus.png b/hexaforge/public/img/tuto/4argocd-menus.png new file mode 100644 index 0000000..bde2b41 Binary files /dev/null and b/hexaforge/public/img/tuto/4argocd-menus.png differ diff --git a/hexaforge/public/img/tuto/4argocd.png b/hexaforge/public/img/tuto/4argocd.png new file mode 100644 index 0000000..58c47f7 Binary files /dev/null and b/hexaforge/public/img/tuto/4argocd.png differ diff --git a/hexaforge/public/img/tuto/etat-services.png b/hexaforge/public/img/tuto/etat-services.png new file mode 100644 index 0000000..e0d0ac6 Binary files /dev/null and b/hexaforge/public/img/tuto/etat-services.png differ diff --git a/hexaforge/public/img/vault.svg b/hexaforge/public/img/vault.svg new file mode 100644 index 0000000..0eeb10f --- /dev/null +++ b/hexaforge/public/img/vault.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hexaforge/public/img/vision.png b/hexaforge/public/img/vision.png new file mode 100644 index 0000000..da0ca55 Binary files /dev/null and b/hexaforge/public/img/vision.png differ diff --git a/hexaforge/services/artefacts.md b/hexaforge/services/artefacts.md new file mode 100644 index 0000000..74b0d54 --- /dev/null +++ b/hexaforge/services/artefacts.md @@ -0,0 +1,58 @@ +# Artefects + +## Nexus + +### Présentation + +Pour stocker et gérer vos artefacts applicatifs, l'usine logcielle de l'offre Cloud π Native vous propose le service de gestionnaire d'artefacts applicatif **Nexus** en version communautaire. + +Il est mis à à disposition des projets afin de stocker les artefacts "intermédiaires" (library java, js, ...) necessaires pour la construction des artefacts finaux embarqués sur les images des conteneurs projets. + +A noter que cette instance Nexus fait également *proxy* vers les différents repos publics (maven central, npm, composer, etc.) + +### Utilisation depuis la CI + +Pour utiliser le service Nexus pour vos projets Maven ou NPM, des variables d'environnements sont préconfigurées dans le service GitLab: + + - MVN_CONFIG_FILE + - NPM_FILE + +Pour l'utilisation d'un langage de programmation différent dans le développement de vos applications, les variables d'environnement suivantes présentes dans GitLab définissant l'accès au service nexus: + + - NEXUS_HOST_URL + - NEXUS_PASSWORD + - NEXUS_USERNAME + +Les urls de repositories seront toujours constuites de la même façon **\${NEXUS_HOST_URL}/repository/${PROJECT_PATH}-XXX** + +## Dépôts d'images de conteneurs: Harbor + +Harbor est la registry d'images de conteneurs utilisé pour stocker, gérer et distribuer les images de conteneurs des différents clusters, ainsi que de les scanner pour détecter les vulnérabilités de sécurité. +Celui-ci est préconfiguré dans les templates GitLab CI et utilisable via l'exemple suivant : + +```yaml +build_docker_back: + variables: + WORKING_DIR: server + IMAGE_NAMES: candilibv2-devops + DOCKERFILE: server/Dockerfile-devops + TAG: $CI_COMMIT_BRANCH + stage: build-docker + extends: + - .kaniko:simple-build-push +``` + +Il sera possible de définir différentes variables d'environnement dans GITLAB pour définir le TAG de l'image du conteneur, son nom et le path du Dockerfile: + - IMAGE_NAMES: Nom de l'image de conteneur qui sera push dans le registry Harbor + - DOCKERFILE: Chemin relatif depuis la racine du projet vers le Dockerfile + - TAG: Tag de l'image par default le nom de la branche sera utilisé, il est possible d'utiliser d'autres valeurs disponible dans [GitLab](https://docs.gitlab.com/ee/ci/variables/predefined_variables.html) comme le $CI_COMMIT_SHORT_SHA ou des valeurs personnaliées. + +Les images seronts publiées (Push) sur l'url prédéfini de harbor ayant le format suivant : + +`/-//` + +Exemple: `harbor.apps.c6.numerique-interieur.com/mi-monprojet/monimage-backend:v2` + +> *Les images publiées par la CI seront signées afin de garantir leur origine et harbor autorisera uniquement l'utilisation d'une image signée* + +Harbor est également accessible aux utilisateurs afin de pouvoir vérifier les analyses de sécurité des images de conteneurs. diff --git a/hexaforge/services/gitlab.md b/hexaforge/services/gitlab.md new file mode 100644 index 0000000..f88dd2b --- /dev/null +++ b/hexaforge/services/gitlab.md @@ -0,0 +1,72 @@ +# Gestionnaire de sources + +## Présentation + +Pour stocker et gérer vos sources applicatifs, l'usine logicielle de l'offre Cloud π Native vous propose le service de gestionnaire de source **GitLab** en version communautaire. + +Le principe de l'offre Cloud π Native est de laisser les projets autonomes sur leur chaine de construction sur les environnements de développement et notamment les outils utilisés. Ainsi, une équipe projet peut utiliser le gestionnaire de source qu'il souhaite en amont de l'offre Cloud π Native : Github, GitLab.com, Bitbucket, GitLab on premise, etc. et sur des dépôts de code publics ou privés. La seule contrainte est que ce gestionnaire soit **accessible depuis Internet** afin qu'il puisse être *copié* sur le GitLab de l'usine logicielle de l'offre Cloud π Native. + +Dans la suite de cette page : + - *dépôt externe* correspond au dépôt GIT externe à la plateforme Cloud π Native, et utilisé généreralement pour tester vos développement; + - *dépôt interne* correspond à la copie du dépôt externe dans le service GitLab l'offre Cloud π Native; + - *gitlab interne* correspond à l'instance GitLab de l'offre Cloud π Native. + +![gitlab-synchro-repos](/img/repo-sync-01.png) + +> la copie des dépôts externes vers le GitLab interne est piloté par le GitLab interne. Le flux de synchronisation *part* de l'instance GitLab interne. + +## Import d'un dépôts externe depuis la Console DSO + +La déclaration de dépôts externes à synchroniser se fait depuis la **Console** Cloud π Native, une fois le projet est crée. Les opérations suivantes sont réalisées par la Console DSO: + - Création d'un groupe GitLab : / sur le GitLab interne; + - Attribution de droits d'administration sur le groupe GitLab /à l'utilisateur qui crée le projet; + - Création d'un dépôt vide correspondant au dépôt distant dans le groupe ci-dessus; + - Création d'un dépôt "mirror" avec les informations de synchrnonisation permettant, de réaliser un mirroir du dépôt GIT externe vers le dépôt interne créé plus haut. + +Les dépôts externes, sont synchronisés par la pipeline gitlab-ci du projet *mirror* correspondant. + +Une fois le projet applicatif est synchronisé, une pipeline gitlab-ci est lancé afin de construire le projet applicatif sur l'offre Cloud π Native. + +![Principe de synchronisation](/img/repo-sync-02.png) + +## Types de dépôts externes à synchroniser + +Deux types de dépôts sont pris en comptes par l'offre Cloud π Native : + + - Dépôt applicatifs + - Dépôt d'infrastructure applicatifs. + +### Dépôts applicatifs et chaine de construction gitlab-ci + +Les dépôts applicatifs contiennent le code source de vos applications. + +Les projets présents sur la plateforme Cloud π Native sont paramétrés pour exécuter une pipeline gitlab-ci. Les informations de votre pipeline sont présentes dans le fichier **gitlab-ci-dso.yml** qui doit être présent à la racine de votre dépôt externe du projet. Pour vous aider à construire vos premiers pipeline GitLab, nous vous proposons dans la console de la plateforme Cloud π Native des templates pour vous aider à la construction de projets de différents langages (Java, nodejs, python, etc.). Ces templates sont directement paramétrés avec des variables prédéfinies liées au projet courant. Cependant, ils sont donnés à titre d'exemple et doivent être adaptés aux besoins réels de vos projets. + +Les projets applicatifs sont analysés et construits et les images de conteneurs construits sont analysées, pui déposées dans le registry d'images de conteneurs qui est Harbor. + +### Variables prédéfinies gitlab-ci DSO + +Un certains nombres de variables pré-définies, en plus des variables standards de GitLab : + + - http_proxy, https_proxy, HTTP_PROXY et HTTPS_PROXY, PROXY_HOST, PROXY_PORT, : paramètres liés au proxy de l'environnement. + - MVN_CONFIG_FILE : fichier de configuration Maven avec le paramètrage pré-défini de l'environnement et du projet en cours, notamment pour le dépot d'artefact sur le repo Nexus. + - NEXUS_HOST_URL : URL d'accès au dépôt Nexus (stockage d'artefacts) + - NEXUS_HOSTNAME : Hostname du service Nexus + - NO_PROXY : variable contenant les URL qui ne nécessitent pas de passer par le proxy + - NPM_FILE : Fichier de configuration NPM pré-configuré pour l'environnement et le projet en cours + - REGISTRY_URL : URL d'accès à l'instance Harbor (image repository) + - SONAR_HOST_URL : URL d'accès à l'instance SonarQube (analyse de qualité statique) + - VAULT_AUTH_PATH : PATH dans l'URL d'accès à VAULT pour l'authentification par jwt + - VAULT_AUTH_ROLE : PATH dans l'URL d'accès à VAULT pour la récupération des roles depuis les appels de GitLab + - VAULT_SERVER_URL : URL d'accès à l'instance Vault (gestionnaire de secrets) + +### Dépôt source d'infrastructure applicatifs + +Suivant les principes *GitOps*, les déploiements sur l'orchestrateur du conteneurs (Celui de la plateforme Cloud π Native ou le votre) sont pilotés par un dépôt de code git contenant les manifests kubernetes, des charts **Helm** ou **Kustomize** . Ces dépôts de code sont nommés dépôts d'infrastructure permettent de déployer vos images de conteneurs, ainsi que vos objects kubernets (service, ingress, configmap ...) + +Ces dépôts sources sont utilisés par ArgoCD afin de déployer l'infrastructure applictive sur Kubernetes. Votre application est déployé dans un namespace dédié au projet et automatiquement provisionné par la console de la plateforme Cloud π Native. + +## Schéma de fonctionnement +Le schéma ci-dessous présente le fonctionnement général : + +![gitlab-général](/img/gitlab.png) diff --git a/hexaforge/services/gitops.md b/hexaforge/services/gitops.md new file mode 100644 index 0000000..a03e578 --- /dev/null +++ b/hexaforge/services/gitops.md @@ -0,0 +1,44 @@ +# Gitops + +## Philosophie et principes + +Pour le déploiement de votre infrastructure applicatif, l'usine logcielle de l'offre Cloud π Native vous propose le service GitOps [ArgoCD](https://argo-cd.readthedocs.io/en/stable/) en version communautaire. + +Gitops est un modèle de workflow permettant provisionner son infrastructure à l'image d'un repo git assurant +ansi la reproductibilité et le versionning. Ceci implique : + - Toute l'infrastructure est gérée par du code, déposé sur un dépôt source GIT + - Le dépôt source d'infrastructure GIT "pilote" les déploiements de l'infrastructure applicatif. + +![gitops](/img/gitops.png) + +## ArgoCD + +ArgoCD assure la mise en conformité de votre infrastructure avec le dépôt git d'infrastructure qui est la source de vérité. + +Lors de l'ajout d'un dépôt de type infrastructure depuis la console de plateforme Cloud π Native, un projet ArgoCD est automatiquement créé avec les informations du projet et de l'organisation. Ces dépôts d'infrastructure peuvent être au format : + - Manifests Kubernetes + - Kustomize + - Helm + +Un namespace est créé par projet. Ainsi, il est possible d'avoir plusieurs repos d'infrastructure pour un même projet DSO, par exemple un au format Helm et un au format Kustomize. + +ArgoCD offre une console de déploiement permettant de consulter et visualiser ses déploiement de façon graphique et également d'accéder aux *events* et *logs* de chaque ressource : + +![ArgoCD-console](/img/argocd-example.png) + +## Déploiement et redéploiement + +Suivant le principe GitOps et afin de déployer une application ou la redéployer, il est nécessaire de suivre les étapes suivantes: + - Correction d'anomalie et modification du numéro de version (tag) sur le déploiement depuis le repo applicatif externe + - Synchronisation des repos externes / internes + - Re construction de l'application via le pipeline gitlab-ci sur la plateforme Cloud π Native + - Construction de l'image Docker et la publier dans le gestionnaire d'image de la plateforme Harbor. + - Modification du dépôt d'infrastructure afin de mettre en cohérence le tag de l'image à déployer + - Synchronisation du dépôt externe d'infrastructure + +Il est possible d'automatiser ces différentes tâches comme suit : + - Utiliser l'identifiant de commit court (CI_COMMIT_SHORT_SHA) du repo applicatif comme tag d'image à construire + - Lors de la construction sur les repos externe, déclencher une étape permettant de modifier la référence de l'image à déployer sur le repo d'infra externe (kustomize ou helm values) avec l'identifiant du commit ci-dessus. + - Utiliser des triggers depuis le repo de code applicatif externe (github Action, gitlab-ci, etc.) pour déclencher la synchronisation des repos vers gitlab-ci de la plateforme Cloud π Native. + +> Attention ! Si le tag de l'image n'est pas modifié, aucune modification du repo d'infra n'est effectué et ArgoCD n'aura pas de modification à appliquer et les pods ne seront pas redéployés. diff --git a/hexaforge/services/sonarqube.md b/hexaforge/services/sonarqube.md new file mode 100644 index 0000000..8276b28 --- /dev/null +++ b/hexaforge/services/sonarqube.md @@ -0,0 +1,23 @@ +# Outil d'analyse qualimétrie + +## Présentation + +Pour l'analyse statique (bonnes pratiques et sécurité) de vos code sources applicatifs et infrastructures, l'usine logcielle de l'offre Cloud π Native vous propose le service de qualimétrie continu de code **SonarQube** en version communautaire. + +Des *Quality gates* sont positionnées afin de garantir que le code construit respecte les normes de sécurité et de qualité. + +Les variables d'environnement suivantes sont disponibles depuis GitLab lors des étapes de construction et permettant de contacter sonar : + +- SONAR_HOST_URL +- SONAR_TOKEN + +SonarQube est préconfiguré pour certains outils telsque npm et Maven, présents dans les templates [GitLab](https://cloud-pi-native.fr/services/gitlab.html) et utilisable via l'exemple suivant : + +```yaml +test_front: + variables: + WORKING_DIR: src + stage: test + extends: + - .node:sonar +``` diff --git a/hexaforge/services/vault.md b/hexaforge/services/vault.md new file mode 100644 index 0000000..c430ab7 --- /dev/null +++ b/hexaforge/services/vault.md @@ -0,0 +1,53 @@ +# Gestion des secrets (de la chaine) + +## Présentation + +Pour la gestion de l'ensemble des secrets, l'usine logcielle de l'offre Cloud π Native vous propose le service de gestion de secrets **Vault** en version communautaire. + +Les secrets des services de l'usine logicielle de l'offre Cloud π Native sont gérés par un coffre [Hashicorp Vault](https://www.vaultproject.io/). Pour l'instant seuls les secrets de la chaine CI/CD sont gérés dans cet espace et les clients (utilisateurs de l'offre Cloud π Native) n'ont pas accès à ce coffre. La gestion des secrets applicatif est traité [ici](/guide/secrets-management). + +Ainsi, les secrets gérés dans hashicorp Vault concernent, pour l'instant, les besoins internes de la plateforme à savoir les token et credentials d'accès aux différents outils depuis gitlab-ci (SonaQube, Nexus, etc.) + +## Organisation du Vault + +Les secrets de la chaine DevSecOps sont stockés sur Vault sur un engine kv v2 (clé / valeur). Ces secrets sont traités de façon hiérarchique dans une arborescence : + + - / + - projects/ + - organisation_1/ + - projet1/ + - Outil1/ + - Outil2/ + - Outil3/ + - Outil4/ + - projet2/ + - projet3/ + - organisation_2/ + - projet1/ + - projet2/ + - projet3/ + - organisation_3/ + - [...] + +Où *outilX* correspond aux différents outils de la chaine de construction. Ainsi, il est possible d'attribuer des droits d'accès à un projet pour l'ensemble de ses outils. + +## Intégration dans la chaine gitlab-ci + +Lors de la construction applicative par gitlab-ci, une première étape consiste à récupérer les secrets liés au projet. Pour cela gitlab-ci se connecte à vault via le protocole OpenId Connect et récupère uniquement les secrets liés à son projet applicatif. Vault génère un token d'accès unique, à durée courte, et limité au périmètre organisation / projet lié au projet dans gitlab. La première étape d'une pipeline gitlab consiste donc à récupérer les secrets de son environnement. Afin de simplifier cette étape, les templates de pipeline fournis par la console inclus directement cette étape comme suit : + +```yaml +read_secret: + stage: read-secret + extends: + - .vault:read_secret +``` + +La consultation de cette étape sur la pipeline peut être consultée depuis le menu de gitlab CI/CD -> pipeline : + +![stage_read_secret](/img/gitlab-ci-read-secrets.png) + +et les logs: + +![log_read_secret](/img/gitlab-ci-vault.png) + +> Cette étape est **obligatoire** afin de réaliser une contruction d'artefact. diff --git a/package.json b/package.json index a6b1dda..da65106 100644 --- a/package.json +++ b/package.json @@ -3,16 +3,27 @@ "type": "module", "version": "1.0.0", "scripts": { - "build": "vitepress build docs", - "dev": "vitepress dev docs --port 8081", - "docker:build": "docker build --tag cloud-pi-native/documentation --target prod .", - "docker:run": "docker run --publish 8081:8080 --rm cloud-pi-native/documentation", + "build": "run-p build:*", + "dev": "run-p dev:*", + "docker:build": "run-p docker:build:*", + "docker:run": "run-p docker:run:*", + "preview": "run-p preview:*", "format": "eslint . --fix", "lint": "eslint .", - "preview": "vitepress preview docs --port 8081" + "build:hexa": "vitepress build hexaforge", + "build:cpin": "vitepress build cloud-pi-native", + "dev:hexa": "vitepress dev hexaforge --port 8081", + "dev:cpin": "vitepress dev cloud-pi-native --port 8082", + "docker:build:hexa": "docker build --tag hexaforge/documentation --file Dockerfile.hexaforge --target prod .", + "docker:build:cpin": "docker build --tag cloud-pi-native/documentation --file Dockerfile.cloud-pi-native --target prod .", + "docker:run:hexa": "docker run --publish 8081:8080 --rm hexaforge/documentation", + "docker:run:cpin": "docker run --publish 8081:8080 --rm cloud-pi-native/documentation", + "preview:hexa": "vitepress preview hexaforge --port 8081", + "preview:cpin": "vitepress preview cloud-pi-native --port 8082" }, "devDependencies": { "@antfu/eslint-config": "^2.24.1", + "npm-run-all": "^4.1.5", "vitepress": "^1.2.3" }, "volta": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 37e1dba..2e8c861 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,6 +11,9 @@ importers: '@antfu/eslint-config': specifier: ^2.24.1 version: 2.25.1(@typescript-eslint/utils@8.1.0(eslint@9.9.0)(typescript@5.5.4))(@vue/compiler-sfc@3.4.27)(eslint@9.9.0)(typescript@5.5.4) + npm-run-all: + specifier: ^4.1.5 + version: 4.1.5 vitepress: specifier: ^1.2.3 version: 1.2.3(@algolia/client-search@4.20.0)(postcss@8.4.38)(search-insights@2.9.0)(typescript@5.5.4) @@ -769,10 +772,22 @@ packages: argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + array-buffer-byte-length@1.0.1: + resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} + engines: {node: '>= 0.4'} + array-union@2.1.0: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} + arraybuffer.prototype.slice@1.0.3: + resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==} + engines: {node: '>= 0.4'} + + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -798,6 +813,10 @@ packages: resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} engines: {node: '>=6'} + call-bind@1.0.7: + resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + engines: {node: '>= 0.4'} + callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} @@ -860,6 +879,10 @@ packages: core-js-compat@3.38.0: resolution: {integrity: sha512-75LAicdLa4OJVwFxFbQR3NdnZjNgX6ILpVcVzcC4T2smerB5lELMrJQQQoWV6TiuC/vlaFqgU2tKQx9w5s0e0A==} + cross-spawn@6.0.5: + resolution: {integrity: sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==} + engines: {node: '>=4.8'} + cross-spawn@7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} @@ -872,6 +895,18 @@ packages: csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + data-view-buffer@1.0.1: + resolution: {integrity: sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==} + engines: {node: '>= 0.4'} + + data-view-byte-length@1.0.1: + resolution: {integrity: sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==} + engines: {node: '>= 0.4'} + + data-view-byte-offset@1.0.0: + resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==} + engines: {node: '>= 0.4'} + debug@3.2.7: resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} peerDependencies: @@ -892,6 +927,14 @@ packages: deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} @@ -917,9 +960,33 @@ packages: error-ex@1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + es-abstract@1.23.3: + resolution: {integrity: sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==} + engines: {node: '>= 0.4'} + + es-define-property@1.0.0: + resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + es-module-lexer@1.5.4: resolution: {integrity: sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==} + es-object-atoms@1.0.0: + resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.0.3: + resolution: {integrity: sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==} + engines: {node: '>= 0.4'} + + es-to-primitive@1.2.1: + resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} + engines: {node: '>= 0.4'} + esbuild@0.21.5: resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} engines: {node: '>=12'} @@ -1176,6 +1243,9 @@ packages: focus-trap@7.5.4: resolution: {integrity: sha512-N7kHdlgsO/v+iD/dMoJKtsSqs5Dz/dXZVebRgJw23LDk+jMi/974zyiOYDziY2JPp8xivq9BmUGwIJMiuSBi7w==} + for-each@0.3.3: + resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -1184,10 +1254,25 @@ packages: function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + function.prototype.name@1.1.6: + resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} + engines: {node: '>= 0.4'} + + functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + get-caller-file@2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} + get-intrinsic@1.2.4: + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + engines: {node: '>= 0.4'} + + get-symbol-description@1.0.2: + resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==} + engines: {node: '>= 0.4'} + get-tsconfig@4.7.6: resolution: {integrity: sha512-ZAqrLlu18NbDdRaHq+AKXzAmqIUPswPWKUchfytdAjiRFnCe5ojG2bstg6mRiZabkKfCoL/e98pbBELIV/YCeA==} @@ -1211,16 +1296,26 @@ packages: resolution: {integrity: sha512-SmSKyLLKFbSr6rptvP8izbyxJL4ILwqO9Jg23UA0sDlGlu58V59D1//I3vlc0KJphVdUR7vMjHIplYnzBxorQA==} engines: {node: '>=18'} + globalthis@1.0.4: + resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} + engines: {node: '>= 0.4'} + globby@11.1.0: resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} engines: {node: '>=10'} + gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + 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==} + has-bigints@1.0.2: + resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} + has-flag@3.0.0: resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} engines: {node: '>=4'} @@ -1229,6 +1324,21 @@ packages: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-proto@1.0.3: + resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} + engines: {node: '>= 0.4'} + + has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + hasown@2.0.2: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} @@ -1255,23 +1365,50 @@ packages: resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} engines: {node: '>=8'} + internal-slot@1.0.7: + resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} + engines: {node: '>= 0.4'} + is-alphabetical@1.0.4: resolution: {integrity: sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==} is-alphanumerical@1.0.4: resolution: {integrity: sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==} + is-array-buffer@3.0.4: + resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} + engines: {node: '>= 0.4'} + is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + is-bigint@1.0.4: + resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} + + is-boolean-object@1.1.2: + resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} + engines: {node: '>= 0.4'} + is-builtin-module@3.2.1: resolution: {integrity: sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==} engines: {node: '>=6'} + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + is-core-module@2.15.0: resolution: {integrity: sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==} engines: {node: '>= 0.4'} + is-data-view@1.0.1: + resolution: {integrity: sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==} + engines: {node: '>= 0.4'} + + is-date-object@1.0.5: + resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} + engines: {node: '>= 0.4'} + is-decimal@1.0.4: resolution: {integrity: sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==} @@ -1290,6 +1427,14 @@ packages: is-hexadecimal@1.0.4: resolution: {integrity: sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==} + is-negative-zero@2.0.3: + resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} + engines: {node: '>= 0.4'} + + is-number-object@1.0.7: + resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} + engines: {node: '>= 0.4'} + is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} @@ -1298,6 +1443,32 @@ packages: resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} engines: {node: '>=8'} + is-regex@1.1.4: + resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} + engines: {node: '>= 0.4'} + + is-shared-array-buffer@1.0.3: + resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==} + engines: {node: '>= 0.4'} + + is-string@1.0.7: + resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} + engines: {node: '>= 0.4'} + + is-symbol@1.0.4: + resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} + engines: {node: '>= 0.4'} + + is-typed-array@1.1.13: + resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} + engines: {node: '>= 0.4'} + + is-weakref@1.0.2: + resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} + + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} @@ -1328,6 +1499,9 @@ packages: json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + json-parse-better-errors@1.0.2: + resolution: {integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==} + json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} @@ -1351,6 +1525,10 @@ packages: lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + load-json-file@4.0.0: + resolution: {integrity: sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==} + engines: {node: '>=4'} + local-pkg@0.5.0: resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==} engines: {node: '>=14'} @@ -1381,6 +1559,10 @@ packages: mdast-util-to-string@2.0.0: resolution: {integrity: sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==} + memorystream@0.3.1: + resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} + engines: {node: '>= 0.10.0'} + merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} @@ -1433,15 +1615,35 @@ packages: natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + nice-try@1.0.5: + resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} + 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==} + npm-run-all@4.1.5: + resolution: {integrity: sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==} + engines: {node: '>= 4'} + hasBin: true + nth-check@2.1.1: resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + object-inspect@1.13.2: + resolution: {integrity: sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==} + engines: {node: '>= 0.4'} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + object.assign@4.1.5: + resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} + engines: {node: '>= 0.4'} + optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} @@ -1481,6 +1683,10 @@ packages: resolution: {integrity: sha512-TDT4HqzUiTMO1wJRwg/t/hYk8Wdp3iF/ToMIlAoVQfL1Xs/sTxq1dKWSMjMbQmIarfWKymOyly40+zmPHXMqCA==} engines: {node: '>= 18'} + parse-json@4.0.0: + resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==} + engines: {node: '>=4'} + parse-json@5.2.0: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} @@ -1489,6 +1695,10 @@ packages: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} + path-key@2.0.1: + resolution: {integrity: sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==} + engines: {node: '>=4'} + path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} @@ -1496,6 +1706,10 @@ packages: path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + path-type@3.0.0: + resolution: {integrity: sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==} + engines: {node: '>=4'} + path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} @@ -1520,6 +1734,15 @@ packages: resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} engines: {node: '>=12'} + pidtree@0.3.1: + resolution: {integrity: sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==} + engines: {node: '>=0.10'} + hasBin: true + + pify@3.0.0: + resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} + engines: {node: '>=4'} + pkg-types@1.1.3: resolution: {integrity: sha512-+JrgthZG6m3ckicaOB74TwQ+tBWsFl3qVQg7mN8ulwSOElJ7gBhKzj2VkCPnZ4NlF6kEquYU+RIYNVAvzd54UA==} @@ -1527,6 +1750,10 @@ packages: resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} engines: {node: '>=4'} + possible-typed-array-names@1.0.0: + resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} + engines: {node: '>= 0.4'} + postcss-selector-parser@6.1.2: resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} engines: {node: '>=4'} @@ -1553,6 +1780,10 @@ packages: resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} engines: {node: '>=8'} + read-pkg@3.0.0: + resolution: {integrity: sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==} + engines: {node: '>=4'} + read-pkg@5.2.0: resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==} engines: {node: '>=8'} @@ -1569,6 +1800,10 @@ packages: resolution: {integrity: sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==} hasBin: true + regexp.prototype.flags@1.5.3: + resolution: {integrity: sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==} + engines: {node: '>= 0.4'} + regjsparser@0.10.0: resolution: {integrity: sha512-qx+xQGZVsy55CH0a1hiVwHmqjLryfh7wQyF5HO07XJ9f7dQMY/gPQHhlyDkIzJKC+x2fUCpCcUODUUUFrm7SHA==} hasBin: true @@ -1603,6 +1838,14 @@ packages: run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + safe-array-concat@1.1.2: + resolution: {integrity: sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==} + engines: {node: '>=0.4'} + + safe-regex-test@1.0.3: + resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==} + engines: {node: '>= 0.4'} + scslre@0.3.0: resolution: {integrity: sha512-3A6sD0WYP7+QrjbfNA2FN3FsOaGGFoekCVgTyypy53gPxhbkCIjtO6YWgdrfM+n/8sI8JeXZOIxsHjMTNxQ4nQ==} engines: {node: ^14.0.0 || >=16.0.0} @@ -1619,17 +1862,40 @@ packages: engines: {node: '>=10'} hasBin: true + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + + shebang-command@1.2.0: + resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} + engines: {node: '>=0.10.0'} + shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} + shebang-regex@1.0.0: + resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==} + engines: {node: '>=0.10.0'} + shebang-regex@3.0.0: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} + shell-quote@1.8.1: + resolution: {integrity: sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==} + shiki@1.7.0: resolution: {integrity: sha512-H5pMn4JA7ayx8H0qOz1k2qANq6mZVCMl1gKLK6kWIrv1s2Ial4EmD4s4jE8QB5Dw03d/oCQUxc24sotuyR5byA==} + side-channel@1.0.6: + resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} + engines: {node: '>= 0.4'} + sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} @@ -1670,10 +1936,29 @@ packages: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} + string.prototype.padend@3.1.6: + resolution: {integrity: sha512-XZpspuSB7vJWhvJc9DLSlrXl1mcA2BdoY5jjnS135ydXqLoqhs96JjDtCkjJEQHvfqZIp9hBuBMgI589peyx9Q==} + engines: {node: '>= 0.4'} + + string.prototype.trim@1.2.9: + resolution: {integrity: sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==} + engines: {node: '>= 0.4'} + + string.prototype.trimend@1.0.8: + resolution: {integrity: sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==} + + string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} + strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + strip-indent@3.0.0: resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} engines: {node: '>=8'} @@ -1752,6 +2037,22 @@ packages: resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} engines: {node: '>=8'} + typed-array-buffer@1.0.2: + resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==} + engines: {node: '>= 0.4'} + + typed-array-byte-length@1.0.1: + resolution: {integrity: sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==} + engines: {node: '>= 0.4'} + + typed-array-byte-offset@1.0.2: + resolution: {integrity: sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==} + engines: {node: '>= 0.4'} + + typed-array-length@1.0.6: + resolution: {integrity: sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==} + engines: {node: '>= 0.4'} + typescript@5.5.4: resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==} engines: {node: '>=14.17'} @@ -1760,6 +2061,9 @@ packages: ufo@1.5.4: resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} + unbox-primitive@1.0.2: + resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} + unist-util-stringify-position@2.0.3: resolution: {integrity: sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==} @@ -1843,6 +2147,17 @@ packages: typescript: optional: true + which-boxed-primitive@1.0.2: + resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + + which-typed-array@1.1.15: + resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} + engines: {node: '>= 0.4'} + + which@1.3.1: + resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} + hasBin: true + which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} @@ -2640,8 +2955,28 @@ snapshots: argparse@2.0.1: {} + array-buffer-byte-length@1.0.1: + dependencies: + call-bind: 1.0.7 + is-array-buffer: 3.0.4 + array-union@2.1.0: {} + arraybuffer.prototype.slice@1.0.3: + dependencies: + array-buffer-byte-length: 1.0.1 + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + is-array-buffer: 3.0.4 + is-shared-array-buffer: 1.0.3 + + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.0.0 + balanced-match@1.0.2: {} boolbase@1.0.0: {} @@ -2668,6 +3003,14 @@ snapshots: builtin-modules@3.3.0: {} + call-bind@1.0.7: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + set-function-length: 1.2.2 + callsites@3.1.0: {} caniuse-lite@1.0.30001651: {} @@ -2723,6 +3066,14 @@ snapshots: dependencies: browserslist: 4.23.3 + cross-spawn@6.0.5: + dependencies: + nice-try: 1.0.5 + path-key: 2.0.1 + semver: 5.7.2 + shebang-command: 1.2.0 + which: 1.3.1 + cross-spawn@7.0.3: dependencies: path-key: 3.1.1 @@ -2733,6 +3084,24 @@ snapshots: csstype@3.1.3: {} + data-view-buffer@1.0.1: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + + data-view-byte-length@1.0.1: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + + data-view-byte-offset@1.0.0: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + debug@3.2.7: dependencies: ms: 2.1.3 @@ -2743,6 +3112,18 @@ snapshots: deep-is@0.1.4: {} + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + gopd: 1.0.1 + + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + dir-glob@3.0.1: dependencies: path-type: 4.0.0 @@ -2766,8 +3147,79 @@ snapshots: dependencies: is-arrayish: 0.2.1 + es-abstract@1.23.3: + dependencies: + array-buffer-byte-length: 1.0.1 + arraybuffer.prototype.slice: 1.0.3 + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + data-view-buffer: 1.0.1 + data-view-byte-length: 1.0.1 + data-view-byte-offset: 1.0.0 + es-define-property: 1.0.0 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + es-set-tostringtag: 2.0.3 + es-to-primitive: 1.2.1 + function.prototype.name: 1.1.6 + get-intrinsic: 1.2.4 + get-symbol-description: 1.0.2 + globalthis: 1.0.4 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.2 + internal-slot: 1.0.7 + is-array-buffer: 3.0.4 + is-callable: 1.2.7 + is-data-view: 1.0.1 + is-negative-zero: 2.0.3 + is-regex: 1.1.4 + is-shared-array-buffer: 1.0.3 + is-string: 1.0.7 + is-typed-array: 1.1.13 + is-weakref: 1.0.2 + object-inspect: 1.13.2 + object-keys: 1.1.1 + object.assign: 4.1.5 + regexp.prototype.flags: 1.5.3 + safe-array-concat: 1.1.2 + safe-regex-test: 1.0.3 + string.prototype.trim: 1.2.9 + string.prototype.trimend: 1.0.8 + string.prototype.trimstart: 1.0.8 + typed-array-buffer: 1.0.2 + typed-array-byte-length: 1.0.1 + typed-array-byte-offset: 1.0.2 + typed-array-length: 1.0.6 + unbox-primitive: 1.0.2 + which-typed-array: 1.1.15 + + es-define-property@1.0.0: + dependencies: + get-intrinsic: 1.2.4 + + es-errors@1.3.0: {} + es-module-lexer@1.5.4: {} + es-object-atoms@1.0.0: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.0.3: + dependencies: + get-intrinsic: 1.2.4 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + es-to-primitive@1.2.1: + dependencies: + is-callable: 1.2.7 + is-date-object: 1.0.5 + is-symbol: 1.0.4 + esbuild@0.21.5: optionalDependencies: '@esbuild/aix-ppc64': 0.21.5 @@ -3134,13 +3586,40 @@ snapshots: dependencies: tabbable: 6.2.0 + for-each@0.3.3: + dependencies: + is-callable: 1.2.7 + fsevents@2.3.3: optional: true function-bind@1.1.2: {} + function.prototype.name@1.1.6: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + functions-have-names: 1.2.3 + + functions-have-names@1.2.3: {} + get-caller-file@2.0.5: {} + get-intrinsic@1.2.4: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.2 + + get-symbol-description@1.0.2: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + get-tsconfig@4.7.6: dependencies: resolve-pkg-maps: 1.0.0 @@ -3161,6 +3640,11 @@ snapshots: globals@15.9.0: {} + globalthis@1.0.4: + dependencies: + define-properties: 1.2.1 + gopd: 1.0.1 + globby@11.1.0: dependencies: array-union: 2.1.0 @@ -3170,14 +3654,32 @@ snapshots: merge2: 1.4.1 slash: 3.0.0 + gopd@1.0.1: + dependencies: + get-intrinsic: 1.2.4 + graceful-fs@4.2.11: {} graphemer@1.4.0: {} + has-bigints@1.0.2: {} + has-flag@3.0.0: {} has-flag@4.0.0: {} + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.0 + + has-proto@1.0.3: {} + + has-symbols@1.0.3: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.0.3 + hasown@2.0.2: dependencies: function-bind: 1.1.2 @@ -3197,6 +3699,12 @@ snapshots: indent-string@4.0.0: {} + internal-slot@1.0.7: + dependencies: + es-errors: 1.3.0 + hasown: 2.0.2 + side-channel: 1.0.6 + is-alphabetical@1.0.4: {} is-alphanumerical@1.0.4: @@ -3204,16 +3712,40 @@ snapshots: is-alphabetical: 1.0.4 is-decimal: 1.0.4 + is-array-buffer@3.0.4: + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + is-arrayish@0.2.1: {} + is-bigint@1.0.4: + dependencies: + has-bigints: 1.0.2 + + is-boolean-object@1.1.2: + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + is-builtin-module@3.2.1: dependencies: builtin-modules: 3.3.0 + is-callable@1.2.7: {} + is-core-module@2.15.0: dependencies: hasown: 2.0.2 + is-data-view@1.0.1: + dependencies: + is-typed-array: 1.1.13 + + is-date-object@1.0.5: + dependencies: + has-tostringtag: 1.0.2 + is-decimal@1.0.4: {} is-extglob@2.1.1: {} @@ -3226,10 +3758,43 @@ snapshots: is-hexadecimal@1.0.4: {} + is-negative-zero@2.0.3: {} + + is-number-object@1.0.7: + dependencies: + has-tostringtag: 1.0.2 + is-number@7.0.0: {} is-path-inside@3.0.3: {} + is-regex@1.1.4: + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + + is-shared-array-buffer@1.0.3: + dependencies: + call-bind: 1.0.7 + + is-string@1.0.7: + dependencies: + has-tostringtag: 1.0.2 + + is-symbol@1.0.4: + dependencies: + has-symbols: 1.0.3 + + is-typed-array@1.1.13: + dependencies: + which-typed-array: 1.1.15 + + is-weakref@1.0.2: + dependencies: + call-bind: 1.0.7 + + isarray@2.0.5: {} + isexe@2.0.0: {} js-tokens@4.0.0: {} @@ -3248,6 +3813,8 @@ snapshots: json-buffer@3.0.1: {} + json-parse-better-errors@1.0.2: {} + json-parse-even-better-errors@2.3.1: {} json-schema-traverse@0.4.1: {} @@ -3272,6 +3839,13 @@ snapshots: lines-and-columns@1.2.4: {} + load-json-file@4.0.0: + dependencies: + graceful-fs: 4.2.11 + parse-json: 4.0.0 + pify: 3.0.0 + strip-bom: 3.0.0 + local-pkg@0.5.0: dependencies: mlly: 1.7.1 @@ -3307,6 +3881,8 @@ snapshots: mdast-util-to-string@2.0.0: {} + memorystream@0.3.1: {} + merge2@1.4.1: {} micromark@2.11.4: @@ -3356,6 +3932,8 @@ snapshots: natural-compare@1.4.0: {} + nice-try@1.0.5: {} + node-releases@2.0.18: {} normalize-package-data@2.5.0: @@ -3365,10 +3943,33 @@ snapshots: semver: 5.7.2 validate-npm-package-license: 3.0.4 + npm-run-all@4.1.5: + dependencies: + ansi-styles: 3.2.1 + chalk: 2.4.2 + cross-spawn: 6.0.5 + memorystream: 0.3.1 + minimatch: 3.1.2 + pidtree: 0.3.1 + read-pkg: 3.0.0 + shell-quote: 1.8.1 + string.prototype.padend: 3.1.6 + nth-check@2.1.1: dependencies: boolbase: 1.0.0 + object-inspect@1.13.2: {} + + object-keys@1.1.1: {} + + object.assign@4.1.5: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + has-symbols: 1.0.3 + object-keys: 1.1.1 + optionator@0.9.4: dependencies: deep-is: 0.1.4 @@ -3416,6 +4017,11 @@ snapshots: es-module-lexer: 1.5.4 slashes: 3.0.12 + parse-json@4.0.0: + dependencies: + error-ex: 1.3.2 + json-parse-better-errors: 1.0.2 + parse-json@5.2.0: dependencies: '@babel/code-frame': 7.24.7 @@ -3425,10 +4031,16 @@ snapshots: path-exists@4.0.0: {} + path-key@2.0.1: {} + path-key@3.1.1: {} path-parse@1.0.7: {} + path-type@3.0.0: + dependencies: + pify: 3.0.0 + path-type@4.0.0: {} pathe@1.1.2: {} @@ -3443,6 +4055,10 @@ snapshots: picomatch@4.0.2: {} + pidtree@0.3.1: {} + + pify@3.0.0: {} + pkg-types@1.1.3: dependencies: confbox: 0.1.7 @@ -3451,6 +4067,8 @@ snapshots: pluralize@8.0.0: {} + possible-typed-array-names@1.0.0: {} + postcss-selector-parser@6.1.2: dependencies: cssesc: 3.0.0 @@ -3476,6 +4094,12 @@ snapshots: read-pkg: 5.2.0 type-fest: 0.8.1 + read-pkg@3.0.0: + dependencies: + load-json-file: 4.0.0 + normalize-package-data: 2.5.0 + path-type: 3.0.0 + read-pkg@5.2.0: dependencies: '@types/normalize-package-data': 2.4.4 @@ -3494,6 +4118,13 @@ snapshots: regexp-tree@0.1.27: {} + regexp.prototype.flags@1.5.3: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-errors: 1.3.0 + set-function-name: 2.0.2 + regjsparser@0.10.0: dependencies: jsesc: 0.5.0 @@ -3540,6 +4171,19 @@ snapshots: dependencies: queue-microtask: 1.2.3 + safe-array-concat@1.1.2: + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + has-symbols: 1.0.3 + isarray: 2.0.5 + + safe-regex-test@1.0.3: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-regex: 1.1.4 + scslre@0.3.0: dependencies: '@eslint-community/regexpp': 4.11.0 @@ -3552,16 +4196,47 @@ snapshots: semver@7.6.3: {} + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + + set-function-name@2.0.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + + shebang-command@1.2.0: + dependencies: + shebang-regex: 1.0.0 + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 + shebang-regex@1.0.0: {} + shebang-regex@3.0.0: {} + shell-quote@1.8.1: {} + shiki@1.7.0: dependencies: '@shikijs/core': 1.7.0 + side-channel@1.0.6: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + object-inspect: 1.13.2 + sisteransi@1.0.5: {} slash@3.0.0: {} @@ -3599,10 +4274,38 @@ snapshots: is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 + string.prototype.padend@3.1.6: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + + string.prototype.trim@1.2.9: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + + string.prototype.trimend@1.0.8: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + + string.prototype.trimstart@1.0.8: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + strip-ansi@6.0.1: dependencies: ansi-regex: 5.0.1 + strip-bom@3.0.0: {} + strip-indent@3.0.0: dependencies: min-indent: 1.0.1 @@ -3662,10 +4365,49 @@ snapshots: type-fest@0.8.1: {} + typed-array-buffer@1.0.2: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-typed-array: 1.1.13 + + typed-array-byte-length@1.0.1: + dependencies: + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + + typed-array-byte-offset@1.0.2: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + + typed-array-length@1.0.6: + dependencies: + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + possible-typed-array-names: 1.0.0 + typescript@5.5.4: {} ufo@1.5.4: {} + unbox-primitive@1.0.2: + dependencies: + call-bind: 1.0.7 + has-bigints: 1.0.2 + has-symbols: 1.0.3 + which-boxed-primitive: 1.0.2 + unist-util-stringify-position@2.0.3: dependencies: '@types/unist': 2.0.10 @@ -3769,6 +4511,26 @@ snapshots: optionalDependencies: typescript: 5.5.4 + which-boxed-primitive@1.0.2: + dependencies: + is-bigint: 1.0.4 + is-boolean-object: 1.1.2 + is-number-object: 1.0.7 + is-string: 1.0.7 + is-symbol: 1.0.4 + + which-typed-array@1.1.15: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-tostringtag: 1.0.2 + + which@1.3.1: + dependencies: + isexe: 2.0.0 + which@2.0.2: dependencies: isexe: 2.0.0