Skip to content
Rémi... et pas Rémy edited this page Jun 7, 2023 · 3 revisions

Description de l'API

L'API que nous avons crée avec FastAPI interagit avec une base de données PostgreSQL. Elle permet d'effectuer des requêtes pour récupérer des informations suivantes:

  1. Servers
    • Hostname
    • IP
    • Region
    • Uptodate
    • Os
  2. Containers
    • Name
    • IP
    • UP
    • Engine
    • Image
  3. Databases
    • Name
    • Engine
    • Size
    • Uptodate

Stack utilisée

  • FastAPI : framework Python pour créer l'API.
  • psycopg2 : module Python pour la communication avec la base de données PostgreSQL.
  • uvicorn : serveur ASGI utilisé pour exécuter l'API.
  • typing.List : spécifier le type de retour des fonctions.
  • datetime.date : manipuler les dates.
  • pydantic.BaseModel : définir des modèles de données structurés.

Ces importations sont essentielles pour le bon fonctionnement de l'API.

Comment se connecter à la base de données

La classe Database est utilisée pour gérer la connexion à la base de données PostgreSQL. Voici comment cela fonctionne :

  1. La classe Database est instanciée avec les informations de connexion à la base de données :

    db = Database(
        dbname="infrastructure",
        user="postgres",
        password="MyPassword", 
        host="postgres",
        port="1324" 
    )
    • dbname : le nom de la base de données à laquelle se connecter.
    • user : le nom d'utilisateur pour la connexion.
    • password : le mot de passe pour la connexion (à changer pour votre propre mot de passe).
    • host : l'adresse IP ou le nom d'hôte du serveur de la base de données.
    • port : le numéro de port sur lequel le serveur de la base de données écoute.
  2. Lors de l'exécution de la méthode execute_query(query) de la classe Database, la connexion à la base de données est établie si elle n'existe pas déjà.

    • La méthode crée une connexion en utilisant les informations fournies lors de l'instanciation de la classe.
    • La connexion est utilisée pour exécuter la requête SQL spécifiée dans query.
  3. La méthode execute_query(query) exécute la requête SQL et retourne les résultats.

    • Un objet cursor est créé à partir de la connexion pour exécuter la requête.
    • La méthode execute(query) du curseur est utilisée pour exécuter la requête SQL.
    • Les résultats de la requête sont récupérés à l'aide de la méthode fetchall() du curseur.
    • Le curseur est ensuite fermé à l'aide de la méthode close().
    • Enfin, les résultats de la requête sont retournés.
  4. Une fois que toutes les opérations sur la base de données sont terminées, il est recommandé de fermer la connexion en appelant la méthode disconnect() de la classe Database.

Il est important de noter que les informations de connexion, y compris le mot de passe, doivent être gérées avec précaution et ne doivent pas être exposées publiquement. Vous pouvez utiliser des méthodes de gestion des secrets appropriées pour sécuriser ces informations.

Assurez-vous de remplacer les valeurs dbname, user, password, host et port par les informations de connexion appropriées pour votre propre base de données PostgreSQL.

Comment définir une route (@route)

Pour définir une route dans FastAPI, utilisez le décorateur @app.get suivi du chemin de l'URL et de la fonction qui gère la requête. Par exemple :

@app.get("/servers", response_model=List[Server])
def get_servers():
    # Code de gestion de la requête

Ici, la route /servers est définie pour la méthode HTTP GET et elle appelle la fonction get_servers() pour traiter la requête. En utilisant ce endpoint, l'API va aller chercher dans la base de donnée "Infrastructure", toutes les données de la table "servers"

Exemple concret de l'utilisation de l'API

Analysons ensemble les endpoints suivants:

@app.get("/servers", response_model=List[Server])
def get_servers():
    try:
        query = "SELECT * FROM public.servers;"
        results = db.execute_query(query)

        servers = []
        for row in results:
            server = Server(
                hostname=row[0],
                ip=row[1],
                region=row[2],
                uptodate=row[3],
                os=row[4]
            )
            servers.append(server)
        return servers
    except:
        servers = "error"


@app.get("/servers/hostname", response_model=List[str])
def get_server_hostnames():
    query = "SELECT hostname FROM public.servers;"
    results = db.execute_query(query)

    hostnames = [row[0] for row in results]
    return hostnames

Récupérer tous les serveurs

La route GET /servers permet de récupérer tous les serveurs disponibles. Lorsque cette route est appelée, la fonction get_servers() est exécutée. Voici comment cela fonctionne :

  1. La fonction exécute une requête SQL pour sélectionner tous les enregistrements de la table public.servers.
  2. Les résultats de la requête sont récupérés à l'aide de db.execute_query().
  3. Une liste vide servers est créée pour stocker les objets Server.
  4. Pour chaque ligne de résultats, un objet Server est créé en utilisant les valeurs des colonnes hostname, ip, region, uptodate, et os.
  5. L'objet Server est ajouté à la liste servers.
  6. La liste servers est renvoyée en réponse à la requête.

Récupérer les noms d'hôte des serveurs

La route GET /servers/hostname permet de récupérer les noms d'hôte de tous les serveurs disponibles. La fonction get_server_hostnames() est exécutée lors de l'appel à cette route. Voici comment cela fonctionne :

  1. La fonction exécute une requête SQL pour sélectionner la colonne hostname de la table public.servers.
  2. Les résultats de la requête sont récupérés à l'aide de db.execute_query().
  3. Les noms d'hôte sont extraits des résultats et stockés dans une liste hostnames.
  4. La liste hostnames est renvoyée en réponse à la requête.

En utilisant ces routes, vous pouvez récupérer différentes informations des serveurs. Par exemple, en appelant la route GET /servers, vous obtiendrez la liste complète des serveurs avec toutes leurs propriétés. En revanche, en appelant la route GET /servers/hostname, vous obtiendrez uniquement les noms d'hôte des serveurs.

Réponse de l'API

Route GET /servers

Si vous appelez la route GET /servers avec les données suivantes dans la base de données :

Hostname, IP, Region, Uptodate, Os
('vm_aws_501', '192.168.10.167', 'eu-west-2', '2023-05-24', 'CentOS8'),
('vm_aws_685', '192.168.10.150', 'eu-west-3', '2023-05-23', 'RHEL7'),
('vm_aws_82', '192.168.10.183', 'eu-west-2', '2023-05-23', 'Windows_server_2012'),
('vm_aws_691', '192.168.10.76', 'eu-west-2', '2023-05-29', 'RHEL7'),
('vm_aws_636', '192.168.10.173', 'eu-south-1', '2023-05-26', 'SUSE12');

La réponse de l'API sera une liste d'objets représentant chaque serveur avec leurs informations correspondantes :

Objet Hostname IP Region UpToDate OS
1 vm_aws_501 192.168.10.167 eu-west-2 2023-05-24 CentOS8
2 vm_aws_685 192.168.10.150 eu-west-3 2023-05-23 RHEL7
3 vm_aws_82 192.168.10.183 eu-west-2 2023-05-23 Windows_server_2012
4 vm_aws_691 192.168.10.76 eu-west-2 2023-05-29 RHEL7
5 vm_aws_636 192.168.10.173 eu-south-1 2023-05-26 SUSE12

Chaque objet représente un serveur avec ses propriétés, telles que le nom d'hôte, l'adresse IP, la région, la date de mise à jour et le système d'exploitation.

Route GET /servers/hostname

Si vous appelez la route GET /servers/hostname avec les mêmes données dans la base de données, la réponse de l'API sera une liste des noms d'hôte de tous les serveurs disponibles :

  • vm_aws_501
  • vm_aws_685
  • vm_aws_82
  • vm_aws_691
  • vm_aws_636

La route GET /servers/hostname renvoie uniquement le nom des hôtes des serveurs, sans les autres propriétés.

C'est ainsi que l'API vous fournira les informations demandées en fonction des routes appelée (databases, containers....) Vous avez donc la possibilité d'effectuer une requête sur la totalité des serveurs et de leurs propriétés, ou bien de ciblé vos recherche sur une propriété spécifique.

Exemple de call

Par exemple, vous pourriez parfaitement demander:

  • La totalité des serveurs, avec leurs propriétés (route /servers)

  • La totalité des IP qui appartiennent à des serveurs (route /servers/IP)