Boîtier Python pour la sauvegarde automatique de la configuration du commutateur CE

publié il y a  2020-2-29 22:49:09 16 0 0 0

Exigences de mise en réseau

Comme le montre la figure suivante, le serveur distant est un serveur FTP. SwitchA et le serveur FTP ont des itinéraires accessibles l'un à l'autre. L'administrateur requiert que SwitchA sauvegarde automatiquement le fichier de configuration sur le serveur FTP chaque fois que la configuration est modifiée et enregistrée, ce qui réduit la charge de travail de sauvegarde manuelle.

REMARQUE:


Le protocole FTP mettra en danger la sécurité de l'appareil. Le mode SFTP est recommandé.


imgDownload? uuid = ad99e662ae8e47329baa8cf


Feuille de route de configuration

La feuille de route de configuration est la suivante:

  1. Créez un script Python qui peut obtenir et envoyer le fichier de configuration actuel à un serveur FTP.

  2. Téléchargez le script Python sur SwitchA et installez le script.

  3. Liez le script Python à un assistant de commande et définissez la condition de déclenchement de l'assistant sur l'événement de changement de configuration. L'assistant peut alors exécuter le script Python automatiquement lorsque le fichier de configuration change.

Procédure

  1. Créez un script Python.


    # Créez un script Python nommé backupconfig.py . Pour plus de détails sur le format du script, voir Exemple de script backupconfig.py. Ce script Python implémente les fonctions suivantes:


    1. Obtient la configuration actuelle à l'aide des API décrites dans la référence de l'API RESTful.

    2. Envoie le fichier de configuration actuel au serveur FTP.

  2. Téléchargez et installez le script Python.


    # Supposons que le script Python est enregistré sur le serveur FTP. Téléchargez le script Python sur SwitchA via FTP.

<HUAWEI> system-view
[~HUAWEI] sysname SwitchA
[*HUAWEI] commit
[~SwitchA] quit
<SwitchA> ftp 192.168.20.1Trying 192.168.20.1 ...
Press CTRL + K to abort
Connected to 192.168.20.1.
220 FTP Server ready.
User(192.168.20.1:(none)):ftpuser331 Password required for ftpuser.
Enter password:
230 User ftpuser logged in.
[ftp] binary200 Type set to I.
[ftp] get backupconfig.py213 3659
200 Port command successful.
150 Opening data connection for backupconfig.py.
\     100% [***********]
226 File sent ok

FTP: 3659 byte(s) received in 1.610 second(s) 2.219Kbyte(s)/sec.
[ftp] bye221 Goodbye.

# Installez le script Python sur SwitchA.

<SwitchA> ops install file backupconfig.py

# Une fois le script Python installé, lancez les ops run python   commande file-name pour exécuter manuellement le script et vérifier s'il existe un fichier de configuration de sauvegarde sur le serveur FTP. Si le fichier de configuration de sauvegarde existe, le script peut implémenter la fonction de sauvegarde du fichier de configuration.


3. Configurez un assistant de commande .


# Créez un assistant de commande et définissez la condition de déclenchement de l'assistant sur l'événement de modification du fichier de configuration (cfg_file_change). Liez le script Python backupconfig.py à l'assistant.

<SwitchA> system-view[~SwitchA] ops[~SwitchA-ops] assistant backup_config[*SwitchA-ops-assistant-backup_config] condition event feature configuration name cfg_file_change[*SwitchA-ops-assistant-backup_config] execute 1 python backupconfig.py[*SwitchA-ops-assistant-backup_config] commit[~SwitchA-ops-assistant-backup_config] return

4. Vérifiez la configuration.


# Vérifiez la configuration de l'assistant.

<SwitchA> display ops assistant verbose name backup_configAssistant information
  Name                 : backup_config
  State                : ready
  Type                 : command
  Default assistant    : no
 Running statistics
  Running times        : 0
  Queue size/(free)    : 10/(10)
  Skip for queue full  : 0
  Skip for delay       : 0
  Skip for suppression : 0
  Skip for error       : 0
 Execute information
  Task abstract        : backupconfig.py
 Trigger control
  Occurs threshold     : 1
  Period (s)           : 30
  Delay (s)            : 0
  Suppress max         : 0
  Hits in period       : 0
 Condition information
  Correlate expression :
  Condition tag        :
    Condition type     : event
    Subscribe result   : success
    Occurs threshold   : 0
    Period (s)         : 0
    Hits in period     : 0

# Une fois la configuration terminée, exécutez la commande save pour enregistrer la configuration, puis vérifiez si un fichier de configuration de sauvegarde est enregistré sur le serveur FTP.


Exemple de script backupconfig.py

#!/usr/bin/env python

import traceback
import httplib
import string

class OPSConnection(object):
    """Make an OPS connection instance."""

    def __init__(self, host, port = 80):
        self.host = host
        self.port = port
        self.headers = {
            "Content-type": "text/xml",
            "Accept":       "text/xml"
            }
        self.conn = None

    def close(self):
        """Close the connection"""
        self.conn.close()

    def create(self, uri, req_data):
        """Create operation"""
        ret = self.rest_call("POST", uri, req_data)
        return ret

    def delete(self, uri, req_data):
        """Delete operation"""
        ret = self.rest_call("DELETE", uri, req_data)
        return ret

    def get(self, uri, req_data = None):
        """Get operation"""
        ret = self.rest_call("GET", uri, req_data)
        return ret

    def set(self, uri, req_data):
        """Set operation"""
        ret = self.rest_call("PUT", uri, req_data)
        return ret

    def rest_call(self, method, uri, req_data):
        """REST call"""
        print('|---------------------------------- request: ----------------------------------|')
        print('%s %s HTTP/1.1\n' % (method, uri))
        if req_data == None:
            body = ""
        else:
            body = req_data
            print(body)
        if self.conn:
            self.conn.close()
        self.conn = httplib.HTTPConnection(self.host, self.port)

        self.conn.request(method, uri, body, self.headers)
        response = self.conn.getresponse()
        response.status = httplib.OK    # stub code
        ret = (response.status, response.reason, response.read())
        print('|---------------------------------- response: ---------------------------------|')
        print('HTTP/1.1 %s %s\n\n%s' % ret)
        print('|------------------------------------------------------------------------------|')
        return ret

def get_startup_info(ops_conn):
    """Get startup info. """

    uri = "/cfg/startupInfos/startupInfo"
    req_data = \
'''<?xml version="1.0" encoding="UTF-8"?>
<startupInfo>
</startupInfo>
'''
    ret, _, rsp_data = ops_conn.get(uri, req_data)
    if ret != httplib.OK:
        return None

    return rsp_data

def backup_file(ops_conn,cfgFileName):
	"""Copy configuration."""

	uri = "/ftpc/ftpcTransferFiles/ftpcTransferFile"
	str_temp = string.Template(
'''<?xml version="1.0" encoding="UTF-8"?>
<ftpcTransferFile>
	<serverIpv4Address>192.168.20.1</serverIpv4Address>
	<commandType>put</commandType>
	<userName>ftpuser</userName>
	<password>pwd123</password>
	<localFileName>$srcFileName</localFileName>
	<remoteFileName>$desFileName</remoteFileName>
</ftpcTransferFile>
''')

	req_data = str_temp.substitute(srcFileName = cfgFileName,desFileName = cfgFileName.strip('flash:/'))
	ret, _, rsp_data = ops_conn.create(uri, req_data)
	if ret != httplib.OK:
		return None
	return rsp_data

def main():
    """The main function."""

    host = "localhost"
    try:
        ops_conn = OPSConnection(host)
        print('+-------------------------- Open a OPS connection. ----------------------------+')
        rsp_data = get_startup_info(ops_conn)
        if rsp_data is not None:
            cfgFileName = rsp_data[rsp_data.find("curStartupFile")+15 : rsp_data.find("/curStartupFile")-1]
            backup_file(ops_conn,cfgFileName)
        ops_conn.close()
        print('+-------------------------- Close a OPS connection. ---------------------------+')
        return
    except:
        errinfo = traceback.format_exc()
        print(errinfo)
        return

if __name__ == "__main__":
    main()

Description du script backupconfig.py

#!/usr/bin/env python

import traceback
import httplib
import string

Dans la connaissance Python, le champ d' importation est utilisé pour importer des modules. Un module est un fichier de certaines fonctions et classes pour atteindre certains objectifs.

Vous pouvez importer des modules en fonction des besoins de service.

class OPSConnection(object):
    """Make an OPS connection instance."""    def __init__(self, host, port = 80):
        self.host = host
        self.port = port
        self.headers = {
            "Content-type": "text/xml",
            "Accept":       "text/xml"
            }
        self.conn = None    def close(self):
        """Close the connection"""
        self.conn.close()    def create(self, uri, req_data):
        """Create operation"""
        ret = self.rest_call("POST", uri, req_data)
        return ret    def delete(self, uri, req_data):
        """Delete operation"""
        ret = self.rest_call("DELETE", uri, req_data)
        return ret    def get(self, uri, req_data = None):
        """Get operation"""
        ret = self.rest_call("GET", uri, req_data)
        return ret    def set(self, uri, req_data):
        """Set operation"""
        ret = self.rest_call("PUT", uri, req_data)
        return ret    def rest_call(self, method, uri, req_data):
        """REST call"""
        print('|---------------------------------- request: ----------------------------------|')
        print('%s %s HTTP/1.1\n' % (method, uri))
        if req_data == None:
            body = ""
        else:
            body = req_data
            print(body)
        if self.conn:
            self.conn.close()
        self.conn = httplib.HTTPConnection(self.host, self.port)

        self.conn.request(method, uri, body, self.headers)
        response = self.conn.getresponse()
        response.status = httplib.OK    # stub code
        ret = (response.status, response.reason, response.read())
        print('|---------------------------------- response: ---------------------------------|')
        print('HTTP/1.1 %s %s\n\n%s' % ret)
        print('|------------------------------------------------------------------------------|')
        return ret

OPSConnection est une classe utilisée pour appeler l'API RESTful. Cette classe définit certaines méthodes pour effectuer les opérations de configuration d'une connexion HTTP:

  • def __init __ (): est une classe d'initialisation qui crée une connexion HTTP.

  • def close (): ferme une connexion HTTP.

  • def create (): crée des ressources de périphérique.

  • def delete (): supprime les ressources du périphérique.

  • def get (): interroge les ressources du périphérique.

  • def set (): modifie les ressources du périphérique.

  • def rest_call (): invoque les classes en interne.

Vous pouvez invoquer cette partie du script sans la modifier.

def get_startup_info(ops_conn):
    """Get startup info. """    uri = "/cfg/startupInfos/startupInfo" req_data = \
'''<?xml version="1.0" encoding="UTF-8"?>
<startupInfo>
</startupInfo>
'''
 ret, _, rsp_data = ops_conn.get(uri, req_data)
    if ret != httplib.OK:
        return None

    return rsp_data

Définit la fonction d'interrogation des informations de démarrage du périphérique.

uri = "/ cfg / startupInfos / startupInfo" indique l'identificateur de ressource uniforme (URI) de l'objet à gérer. Pour plus de détails, voir API RESTful.

req_data = indique la demande à envoyer.

ret, _, rsp_data = ops_conn.get (uri, req_data) indique une demande pour obtenir des données. Pour plus de détails, voir les méthodes de demande définies dans la classe OPSConnection .

rsp_data indique les données envoyées par le périphérique en réponse à la demande.

def backup_file(ops_conn,cfgFileName):
	"""Copy configuration."""

	uri = "/ftpc/ftpcTransferFiles/ftpcTransferFile"
	str_temp = string.Template(
'''<?xml version="1.0" encoding="UTF-8"?>
<ftpcTransferFile>
	<serverIpv4Address>192.168.20.1</serverIpv4Address>
	<commandType>put</commandType>
	<userName>ftpuser</userName>
	<password>pwd123</password>
	<localFileName>$srcFileName</localFileName>
	<remoteFileName>$desFileName</remoteFileName>
</ftpcTransferFile>
''')

	req_data = str_temp.substitute(srcFileName = cfgFileName,desFileName = cfgFileName.strip('flash:/'))
	ret, _, rsp_data = ops_conn.create(uri, req_data)
	if ret != httplib.OK:
		return None
	return rsp_data

Définissez la fonction utilisée pour sauvegarder le fichier de configuration sur un serveur. Le format de la fonction est similaire à get_startup_info () .

def main():
    """The main function."""    host = "localhost"
    try:        ops_conn = OPSConnection(host)
        print('+-------------------------- Open a OPS connection. ----------------------------+')        rsp_data = get_startup_info(ops_conn)
        if rsp_data is not None:
            cfgFileName = rsp_data[rsp_data.find("curStartupFile")+15 : rsp_data.find("/curStartupFile")-1]
            backup_file(ops_conn,cfgFileName)        ops_conn.close()
        print('+-------------------------- Close a OPS connection. ---------------------------+')
        return
    except:
        errinfo = traceback.format_exc()
        print(errinfo)
        return

if __name__ == "__main__":
    main()
  • La fonction main () définit les opérations à effectuer par ce script. Vous pouvez modifier la fonction en fonction des besoins de service.

    host = indique une adresse de boucle. Actuellement, l'API RESTful ne peut être invoquée qu'au sein de l'appareil. Autrement dit, la valeur est localhost.

    ops_conn = OPSConnection (hôte) indique l'opération de configuration d'une connexion HTTP.

    rsp_data = get_startup_info (ops_conn) indique l'opération d'invocation de fonctions.

    ops_conn.close () indique l'opération de fermeture d'une connexion HTTP.

Fichiers de configuration

  • Fichier de configuration de SwitchA

#
sysname SwitchA
#
ops
 assistant backup_config
  execute 1 python backupconfig.py
  condition event feature configuration name CFG_FILE_CHANGE
#
return

Cordialement!


  • x
  • Standard:

Commentaire

envoyer
Connectez-vous pour répondre. Se connecter | Enregistrer

Remarque Remarque : Afin de protéger vos droits et intérêts légitimes, ceux de la communauté et des tiers, ne divulguez aucun contenu qui pourrait présenter des risques juridiques pour toutes les parties. Le contenu interdit comprend, sans toutefois s'y limiter, le contenu politiquement sensible, le contenu lié à la pornographie, aux jeux d'argent, à l'abus et au trafic de drogues, le contenu qui peut divulguer ou enfreindre la propriété intellectuelle d'autrui, y compris les secrets professionnels, les marques commerciales, les droits d'auteur et les brevets, ainsi que la vie privée personnelle. Ne partagez pas votre nom d'utilisateur ou votre mot de passe avec d'autres personnes. Toutes les opérations effectuées à partir de votre compte seront considérées comme vos propres actions, et toutes les conséquences en découlant vous seront imputées. Pour plus de détails, voir « Politique de confidentialité ».
Si le bouton de la pièce-jointe n'est pas disponible, mettez à jour Adobe Flash Player à la dernière version.

My Followers

Connectez-vous pour participer à la communication et au partage

Connectez-vous pour participer à la communication et au partage

S'identifier