Cisco France Blog
Partager

Introduction au SDK Python de Cisco Intersight


16 May 2022


Introduction

Dans le billet de blog précédent, nous introduisions l’API de Intersight et son utilisation via l’API Explorer. Il est également possible d’interagir avec cette API en utilisant Python grâce au SDK généré via la spécification OpenAPI : c’est l’objet de ce deuxième billet.

Pourquoi utiliser le SDK Python ?

Le SDK Python pour Intersight est un outil permettant de simplifier les interactions avec l’API d’Intersight via le langage Python. Il permet de lire, créer, modifier ou supprimer les différents objets (Managed Object) d’Intersight. En proposant un ensemble de modules Python, classes et fonctions, le SDK est en quelque sorte une « interface Python » au modèle objet de Intersight.

Le SDK Python a un périmètre d’utilisation très large et permet de nombreux cas d’usage. Il vient s’intégrer directement dans un code Python pour créer tout type d’applications. Il peut s’agir de scripts venant simplement récupérer ou configurer les objets d’Intersight pour piloter l’infrastructure Data Center. Mais ça peut être également des applications beaucoup plus poussées venant enrichir le spectre fonctionnel d’Intersight.

Certains exemples d’utilisation sont détaillés sur ce GitHub ou sur le Code Exchange de DevNet.

En contrepartie, il est conseillé d’avoir une bonne compréhension de Python afin de pouvoir interagir avec le SDK et ses objets.

Installation du SDK Python de Intersight

La première étape est d’installer le SDK Python. Le SDK et les instructions d’installation sont disponibles sur le repository du Python Package Index (pypi). Le SDK nécessite Python en version supérieure ou égale à 3.6. Pour installer le SDK, il suffit d’utiliser la commande dans le terminal :

pip install intersight

Ensuite, en se connectant sur votre instance d’Intersight, vous pouvez récupérer une clé d’API dans le menu Settings. Pour l’utilisation du SDK Python, il est recommandé d’utiliser la clé en version 3.

La clé est en deux parties : une API Key ID et une Secret Key. Cette dernière ne s’affiche qu’une seule fois à l’écran, donc pensez bien à l’enregistrer. 🙂

Vous avez maintenant tout ce qu’il faut pour commencer à utiliser l’API et son SDK.

Authentification avec le SDK Python de Intersight

Commençons par importer le module intersight installé précédemment avec pip :

import intersight

Ensuite, nous pouvons nous authentifier à Intersight grâce à la classe intersight.Configuration dans lequel on spécifie le host de destination (https://intersight.com pour la version SaaS) et les différents paramètres requis pour l’authentification : l’API key id, le path vers le fichier contenant la Secret Key, et les paramètres de configuration pour la signature HTTP (il n’est généralement pas nécessaire de modifier cette dernière partie) :

configuration = intersight.Configuration(
     host = "https://intersight.com",
     signing_info = intersight.signing.HttpSigningConfiguration(
          key_id = "enter key id here",
          private_key_path = "enter private key path here",
          signing_scheme = intersight.signing.SCHEME_HS2019,
          signing_algorithm = intersight.signing.ALGORITHM_ECDSA_MODE_DETERMINISTIC_RFC6979,
          hash_algorithm = intersight.signing.HASH_SHA256,
          signed_headers = [
               intersight.signing.HEADER_REQUEST_TARGET,
               intersight.signing.HEADER_HOST,
               intersight.signing.HEADER_DATE,
               intersight.signing.HEADER_DIGEST,
          ],
     ))

Une fois cet objet créé, on génère un client servant à se connecter à notre endpoint :

api_client = intersight.ApiClient(configuration)

Nous pouvons maintenant interagir avec le modèle objet d’Intersight !

Exemple de lecture d’objet

Débutons par un exemple basique. Imaginons que nous souhaitons récupérer toutes les alarmes remontées par Intersight.

On commence par importer le module lié aux alarmes :

from intersight.api import cond_api

Puis nous générons une instance de la classe CondApi en réutilisant notre client de connexion api_client créé plus haut :

api_instance = cond_api.CondApi(api_client)

La classe CondApi possède plusieurs méthodes qui permettent de venir récupérer ou modifier les objets de type alarme. Ici, nous souhaitons récupérer une liste des alarmes, nous utilisons donc la fonction get_cond_alarm_list().

alarm_query = api_instance.get_cond_alarm_list()

print(alarm_query.results)

La fonction nous retourne bien une liste contenant toutes les alarmes générées par Intersight, chaque alarme étant un dictionnaire (la réponse a été raccourcie pour simplifier la lecture) :

% python get_all_alarms.py

[{'acknowledge': 'None',
…
'affected_mo_display_name': 'C220-FCH2017V2EA/sys/rack-unit-1/board',
…
'class_id': 'cond.Alarm',
'code': 'F0425',
…
'description': 'P3V_BAT_V_MOIN: Battery voltage level is lower '
'non-recoverable: Replace battery',
…
'moid': '61fa69e065696e2d303e2279',
'ms_affected_object': 'sys/rack-unit-1/board',
'name': 'UCS-F0425',
'object_type': 'cond.Alarm',
'orig_severity': 'Critical',
…},
…]

ⓘ Mais comment trouve-t-on le nom de module et de classe à importer ? Voici quelques méthodes non exhaustives :

  • En naviguant sur l’interface graphique jusqu’à l’objet voulu, l’URL donne des informations utiles sur les ressources à importer. Par exemple, pour les alarmes, l’URL est : intersight.com/an/cond/alarms.
  • Alternativement, en utilisant l’API Explorer ou le Model Browser décrits dans le billet de blog précédent, on peut également retrouver des informations sur les objets d’Intersight. Ici, les alarmes sont des ressources de type cond.Alarm, et le module Python à importer est cond_api. La construction ressource_api est toujours la même quel que soit l’objet. Les modules ressource_api comportent les classes RessourceApi et ses méthodes permettant d’interagir avec l’API d’Intersight : lecture, création, modification ou suppression.

  • Il est également possible d’utiliser la fonction help() de Python dans le shell sur les différentes classes pour avoir plus d’informations sur les méthodes et paramètres supportés. Par exemple ici :
>>> help(CondApi)

Help on class CondApi in module intersight.api.cond_api:
 
class CondApi(builtins.object)
|  CondApi(api_client=None)
|
|  NOTE: This class is auto generated by OpenAPI Generator
|  Ref: https://openapi-generator.tech
|
|  Do not edit the class manually.
|
|  Methods defined here:
|
|  __init__(self, api_client=None)
|      Initialize self.  See help(type(self)) for accurate signature.
|
|  get_cond_alarm_aggregation_by_moid(self, moid, **kwargs)
|      Read a 'cond.AlarmAggregation' resource.  # noqa: E501
|
|      This method makes a synchronous HTTP request by default. To make an
|      asynchronous HTTP request, please pass async_req=True
|
|      >>> thread = api.get_cond_alarm_aggregation_by_moid(moid, async_req=True)
|      >>> result = thread.get()
|
|      Args:
|          moid (str): The unique Moid identifier of a resource instance.
…
  • Enfin, en inspectant directement le SDK Intersight dans le dossier api, on obtient les classes et les différentes méthodes liées:

Reprenons notre exemple. Plutôt qu’obtenir une liste complète des alarmes, nous souhaitons maintenant affiner la réponse pour obtenir uniquement les alarmes de type « Critical ». Nous souhaitons également uniquement avoir le nom de l’alarme, sa description et l’équipement concerné pour alléger la taille de la réponse.

De la même manière qu’on ajoute des filtres dans les requêtes avec l’API Explorer, il est possible de filtrer avec le SDK Python. Ajoutons donc les paramètres de filtre et de sélection à notre fonction :

filter = "Severity eq Critical"
select = "Name,Description,AffectedMoDisplayName"
 
alarm_query = api_instance.get_cond_alarm_list(filter=filter, select=select)
 
print(alarm_query.results)

On obtient bien uniquement les alarmes critiques et l’API retourne seulement les critères sélectionnés (la réponse a été raccourcie pour simplifier la lecture) :

% python alarm.py

[{'affected_mo_display_name': 'C220-FCH2017V2EA/sys/rack-unit-1/board',
'class_id': 'cond.Alarm',
'description': 'P3V_BAT_V_MOIN: Battery voltage level is lower '
'non-recoverable: Replace battery',
'moid': '61fa69e065696e2d303e2279',
'name': 'UCS-F0425',
'object_type': 'cond.Alarm'},
{'affected_mo_display_name': 'C220-FCH2017V2AC/sys/rack-unit-1/board',
'class_id': 'cond.Alarm',
'description': 'P3V_BAT_V_MOIN: Battery voltage level is lower '
'non-recoverable: Replace battery',
'moid': '61fa8dd465696e2d304913c4',
'name': 'UCS-F0425',
'object_type': 'cond.Alarm'},
…]

 

Exemple de création d’objet

Maintenant, créons un objet avec le SDK Python. Nous souhaitons créer une policy NTP que l’on pourrait par exemple utiliser plus tard dans des Server Profiles.

La première étape est de créer une instance de la classe NtpApi issue du module ntp_api (une policy NTP est une ressource de type ntp.Policy). Cette instance permettra d’exécuter les méthodes liées à cette classe, et notamment ici la création d’une policy NTP :

from intersight.api import ntp_api
 
api_instance = ntp_api.NtpApi(api_client)

Nous devons maintenant créer une policy NTP et lui donner des paramètres de configuration :

from intersight.model.ntp_policy import NtpPolicy
 
ntp_policy = NtpPolicy()

Nous pouvons ensuite définir les paramètres de la policy :

ntp_policy.name = "ntp-policy-1"
ntp_policy.description = "created from the python sdk"
ntp_policy.enabled = True
ntp_policy.ntp_servers = ["10.0.0.1"]
ntp_policy.timezone = "Europe/Paris"

Enfin, nous créons la policy en utilisant notre api_instance :

api_response = api_instance.create_ntp_policy(ntp_policy)

En naviguant sur l’interface graphique, on constate que la policy a bien été créée !

Au lieu de définir chaque attribut ligne par ligne, il est aussi possible de créer des objets à partir d’un JSON en input sous forme de keyword arguments (de taille variable).

Nous créons un fichier JSON comportant les paramètres de notre policy NTP :

{
     "Name": "ntp-policy-2",
     "Description": "created from the python sdk with json",
     "Enabled" : true,
     "ntp_servers" : ["10.0.0.2"],
     "Timezone" : "Europe/Paris"
}

Puis nous récupérons la donnée sous forme de dictionnaire dans le fichier Python :

import json

with open("ntp_policy.json", "r") as ntp_json_file:
     ntp_json_data=json.load(ntp_json_file)

Il ne reste plus qu’à passer la donnée sous forme de keyword argument à notre policy, et utiliser la méthode pour la création de policy NTP :

ntp_policy = NtpPolicy(**ntp_json_data)

api_response = api_instance.create_ntp_policy(ntp_policy)

La policy NTP est bien créée dans notre instance Intersight.

Conclusion

Le SDK Python permet donc d’interagir avec l’API d’Intersight en un minimum de code. Il couvre l’ensemble du modèle objet de Intersight et est fréquemment mis à jour pour être toujours synchronisé avec la dernière version OpenAPI.

Dans les prochains billets de blog, nous regarderons comment interagir avec l’API via Ansible et / ou Terraform.

Tags:
Laisser un commentaire