Les JRES 2024 c’est pour bientôt, le programme est en ligne, il est temps de choisir les sessions et les présentations auxquelles ont veut assister. Le site est plutôt (selon moi) bien fait, clair et lisible. On peut choisir les sessions auxquelles on veut assister et générer un calendrier ics pour ne rien manquer. Malheureusement je n’ai réusssi qu’à choisir une session entière et pas les présentations individuellement. Et j’aime bien changer de salle et d’ambiance en fonction des thèmes abordés ou des collègues qui présentent. Heureusement on peut récupérer le programme au format json et le trier comme on veut.

En ce moment je fais un peu de python car je m’amuse avec un peu d’IA et de RAG (oui je sais… on pourra en discuter il y a beaucoup à dire) et que c’est la lingua franca du monde de l’IA, du coup j’essaye de monter en compétences :-). (Peut-être que j’aurais dû demander à une IA de travailler à ma place…)

Écrire du python avec Emacs et nix

J’ai donc essayé d’écrire un peu de python pour trier ce fichier json et afficher les infos qui m’intéressent.

Dans un buffer org-mode d’Emacs on peut écrire du python, l’exécuter et inclure le résultat dans le buffer. Je trouve que c’est pratique pour écrire des scripts. On peut éditer dans un buffer dédié, avec toute la coloration syntaxique, le bout de code qu’on veut avec la commande C-c '.

Le contenu de ce post est l’inclusion simple du document org-mode qui m’a servi pour écrire le script. C’est facile, les posts sont déjà au format org-mode.

En utilisant nix il y a quelques petites astuces pour que ce soit plus simple.

D’abord il faut définir un fichier shell.nix qui sera appelé par la commande nix-shell et qui définira notre environnement.

#+begin_src nix :tangle /tmp/shell.nix :mkdirp t
  { pkgs ? import <nixpkgs> {} }:
  pkgs.mkShell {
    buildInputs = [ pkgs.python312 pkgs.python312Packages.datetime pkgs.python312Packages.pytz];
  }
#+end_src

Il faudra exporter (tangle) ce fichier avec la commande M-x org-babel-tangle.

Ensuite on pourra ajouter des blocs python et précister un shebang qui utilise nix-shell et notre environnement.

#+begin_src python :python "nix-shell /tmp/shell.nix --pure --run python" :results output
  print("Hello")
#+end_src
#+RESULTS:
: Hello

Le script de tri du programme

Si je veux pouvoir utiliser ce script en ligne de commande il faudra que je modifie le shebang pour ajouter python et les paquets nécessaires dans l’environnement.

#+name: shebang
#+begin_src python
    #! /usr/bin/env nix-shell
    #! nix-shell -i python3 -p python312 -p python312Packages.datetime -p python312Packages.pytz
#+end_src

Sélection des présentations par mot clef

On aura au préalable téléchargé le fichier json dans le répertoire courant.

Les présentations ont plusieurs mots clefs assignés. On peut choisir les présentations qui ont des mots clefs et un mot clef dans notre liste définie.

 1#+name: debut
 2#+begin_src python
 3  import json
 4
 5  with open('programme-jres.json') as f:
 6      data = json.load(f)
 7
 8  keywords_of_interest = ['devops','kubernetes', 'gitlab']
 9
10  def find_keywords(keywords):
11      return any(search in keyword for search in keywords_of_interest for keyword in keywords)      (comprehension)
12
13  presentations = []
14  for presentation in data:
15      if 'keywords' in presentation and find_keywords(presentation['keywords']):
16          presentations.append(presentation)
17
18  #print(presentations)
19#+end_src

Dans la list comprehension on cherche notre mot clef comme une sous chaine dans les mots clefs des présentations. Attention si on ajoute 'ci' en mot clef, cela risque de sélectionner toutes les présentations qui ont un mot clef 'sciences'.

Récupération des détails

Maintenant que nous avons toutes nos présentations nous allons récupérer les informations qui nous intéressenent pour chacune. Pour chaque élément de presentations, qu’on va appeler conf, on va récupérer les entrées voulues et mettre dans une forme humaine les heures de début et fin qui sont au format UTC. Au passage je ne suis pas cohérent dans le nommage, presentations, conferences… Ce doit être ça d’écrire des scripts sans trop réfléchir.

 1#+name: conference
 2#+begin_src python :noweb yes
 3  conferences_info = []
 4
 5  for conf in presentations:
 6
 7      session_start_time = conf['presentation']['session_start']
 8      session_end_time = conf['presentation']['session_end']
 9
10      from datetime import datetime, timezone
11      import pytz
12      session_start = datetime.fromtimestamp(session_start_time, timezone.utc).astimezone(pytz.timezone('Europe/Paris')).strftime('%Y-%m-%d %H:%M:%S') if session_start_time is not None else "NA"
13      session_end = datetime.fromtimestamp(session_end_time, timezone.utc).astimezone(pytz.timezone('Europe/Paris')).strftime('%Y-%m-%d %H:%M:%S') if session_end_time is not None else "NA"
14
15      conference_info = {
16          'title': conf['title'],
17          'keywords': conf['keywords'],
18          'type': conf['type'],
19          'theme': conf['theme'],
20          'place': conf['presentation']['place'],
21          'abstract': conf['abstract'],
22          'start': session_start,
23          'end': session_end
24      }
25      conferences_info.append(conference_info)
26
27  #print(json.dumps(conferences_info, indent=4, sort_keys=False, ensure_ascii=False))
28#+end_src

Programme final

Le programme final est déclaré comme suit. On peut l’exécuter avec un C-c C-c.

29  #+begin_src python :noweb yes :python "nix-shell /tmp/shell.nix --pure --run python" :results output
30    <<shebang>>
31
32    <<debut>>
33    <<conference>>
34
35    from operator import itemgetter
36
37    for conf in sorted(conferences_info, key=itemgetter('start')):
38        print(f"Titre : {conf['title']}")
39        print(f"   {conf['start']}")
40        print(f"   {conf['type']}")
41        print(f"   {", ".join(conf['keywords'])}")
42        print(f"   {conf['theme']}")
43        print(f"   {conf['place']}")
44        print(f"   {conf['abstract'].replace("\r\n","\r\n   ")}")
45        print()
46  #+end_src
47
48  #+RESULTS:
49  #+begin_example
50Titre : Sécurité des environnements conteneurisés et de l'orchestrateur Kubernetes
51   2024-12-11 08:40:00
52   Présentation courte
53   kubernetes, conteneurs linux, sécurité
54   Virtualisation
55   Grand Auditorium
56   **Conteneurs, c’est dans la boîte… mais n’oubliez pas le couvercle !**
57
58   Kubernetes est synonyme de développement agile, de déploiement rapide, de résilience et d’optimisation des ressources. Bien que la segmentation des applications en microservices apporte des avantages considérables, elle introduit aussi de nouveaux défis en matière de sécurité, en raison de la complexité et de la nature dynamique des environnements conteneurisés.
59
60   Nous commencerons par un rappel sur les conteneurs Linux : ce qu’ils sont et ce qu’ils ne sont pas, ainsi que leurs apports en termes de sécurité (mécanismes d’espaces de noms, groupes de contrôle, capacités Linux et filtres seccomp…), puis nous nous intéresserons aux scénarios d’échappement de conteneurs et d’élévation de privilèges, ainsi qu’aux stratégies permettant de les prévenir.
61
62   La seconde partie se concentrera sur les enjeux de sécurité spécifiques à Kubernetes : principaux vecteurs d'attaque, mauvaises configurations, failles dans les images de conteneurs, élévation de privilèges… en mettant un accent particulier sur l’importance du contrôle d'accès basé sur les rôles (RBAC), la gestion sécurisée des secrets, l'utilisation des volumes montés, l'exposition des services et la mise en œuvre de politiques de sécurité rigoureuses.
63
64   Cette présentation s’adresse aux administrateurs systèmes, aux développeurs, aux professionnels de la sécurité informatique et à toute personne intéressée par la sécurité des technologies de conteneurisation et d'orchestration.
65
66Titre : 7 choses que les gens ne vous diront pas sur la HashiStack (parce que, non, il n'y a pas que Kubernetes dans la vie !)
67   2024-12-11 08:40:00
68   Présentation longue
69   hashicorp, nomad, consul, vault, kubernetes, microservices, conteneurs
70   Virtualisation
71   Grand Auditorium
72   De nos jours, les gens s'accordent plus ou moins tous pour vous dire que [Kubernetes](https://kubernetes.io/fr/) est LE nouveau standard pour exécuter ses applications dans le cloud ou ses serveurs "on-premise" ... mais vous a-t-on déjà parlé des solutions **HashiCorp** ?? Vous savez, c'est cette société américaine qui propose depuis 2012 des solutions techniques qui visent à accélérer et simplifier la transition depuis des processus manuels vers des pratiques plutôt orientées automatisation et reposant sur les principes de DevOps ! Non ? Mais si voyons ! [Terraform](https://www.terraform.io/), [Vault](https://www.vaultproject.io/), [Consul](https://www.consul.io/), [Nomad](https://www.nomadproject.io/) ... Toujours pas ? Je vous propose de découvrir, au cours de cet exposé, comment s'articulent ces différentes applications, leur spécialisation, et surtout comment elles peuvent concourir à la mise en place d'une architecture de microservices au travers d'un exposé qui s'appuie sur 7 arguments (parce que, non, il n'y a pas QUE *Kubernetes* dans la vie !).
73[...]
74#+end_example

Programme final utilisable en ligne de commande

 1#! /usr/bin/env nix-shell
 2#! nix-shell -i python3 -p python312 -p python312Packages.datetime -p python312Packages.pytz
 3
 4import json
 5
 6with open('programme-jres.json') as f:
 7    data = json.load(f)
 8
 9keywords_of_interest = ['devops','kubernetes', 'gitlab']
10
11def find_keywords(keywords):
12    return any(search in keyword for search in keywords_of_interest for keyword in keywords)                                                                                                          (comprehension)
13
14presentations = []
15for presentation in data:
16    if 'keywords' in presentation and find_keywords(presentation['keywords']):
17        presentations.append(presentation)
18
19#print(presentations)
20
21conferences_info = []
22
23for conf in presentations:
24
25    session_start_time = conf['presentation']['session_start']
26    session_end_time = conf['presentation']['session_end']
27
28    from datetime import datetime, timezone
29    import pytz
30    session_start = datetime.fromtimestamp(session_start_time, timezone.utc).astimezone(pytz.timezone('Europe/Paris')).strftime('%Y-%m-%d %H:%M:%S') if session_start_time is not None else "NA"
31    session_end = datetime.fromtimestamp(session_end_time, timezone.utc).astimezone(pytz.timezone('Europe/Paris')).strftime('%Y-%m-%d %H:%M:%S') if session_end_time is not None else "NA"
32
33    conference_info = {
34        'title': conf['title'],
35        'keywords': conf['keywords'],
36        'type': conf['type'],
37        'theme': conf['theme'],
38        'place': conf['presentation']['place'],
39        'abstract': conf['abstract'],
40        'start': session_start,
41        'end': session_end
42    }
43    conferences_info.append(conference_info)
44
45#print(json.dumps(conferences_info, indent=4, sort_keys=False, ensure_ascii=False))
46
47from operator import itemgetter
48
49for conf in sorted(conferences_info, key=itemgetter('start')):
50    print(f"Titre : {conf['title']}")
51    print(f"   {conf['start']}")
52    print(f"   {conf['type']}")
53    print(f"   {", ".join(conf['keywords'])}")
54    print(f"   {conf['theme']}")
55    print(f"   {conf['place']}")
56    print(f"   {conf['abstract'].replace("\r\n","\r\n   ")}")
57    print()