Collection of CheckMK checks (see https://checkmk.com/). All checks and plugins are provided as is. Absolutely no warranty. Send any comments to thl-cmk[at]outlook[dot]com

Skip to content
Snippets Groups Projects
Unverified Commit 421d7bc4 authored by arsakthi's avatar arsakthi Committed by GitHub
Browse files

Initial Commit

parent 65586caa
No related branches found
No related tags found
No related merge requests found
# Created by https://www.toptal.com/developers/gitignore/api/macos,windows,linux
# Edit at https://www.toptal.com/developers/gitignore?templates=macos,windows,linux
### Linux ###
*~
# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*
# KDE directory preferences
.directory
# Linux trash folder which might appear on any partition or disk
.Trash-*
# .nfs files are created when an open file is removed but is still being accessed
.nfs*
### macOS ###
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### Windows ###
# Windows thumbnail cache files
Thumbs.db
Thumbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Windows shortcuts
*.lnk
# sphinx build folder
build
# Sphinx
.doctrees
# Visual Studio Code
# End of https://www.toptal.com/developers/gitignore/api/macos,windows,linux
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [V1.0]
### Added
- Added support for additional XE models apart from C9300 (C9500's,C9800's,ASR's).
- Enhanced error handling.
- Ability to log to console when an unhandled exception is caught during execution.
### Changed
- None
### Fixed
- None
LICENSE 0 → 100644
Cisco Systems, Inc End User License Agreement 2020.
As a general rule, software is not included in our Services and must be purchased separately. For Technical Support Services
that expressly include Software Updates, your right to use the Software is covered under your original license. For any other
Software and Scripts that Cisco provides as part of the Services, it is provided as a convenience to you and incidental to the
provision of Services (“Incidental Software and Scripts”).
All Incidental Software and Scripts, in whatever form provided, are licensed to you solely for the express purposes of the
Services and in accordance with our EULA located at http://www.cisco.com/go/eula. If we provide you with Source Code for
any Incidental Software and Scripts, then the Source Code, including any copies, modifications, enhancements and derivative
works of the Source Code, is Cisco Confidential Information that you must keep secure with access given only to your
personnel who must access the Source Code to accomplish the purposes of the Services. Unless we state otherwise, the
Source Code license we grant to you for Incidental Software and Scripts includes the limited license to modify and enhance
the provided Source Code solely for your internal use and only to the extent we expressly permit. Upon our request, you must
remove and substitute, or allow us to remove and substitute, this Source Code with functionally equivalent object code,
provided the object code substitution will only occur if you continue to have an applicable license to the Incidental Software
and Scripts.
Disclaimer of Warranty and Support: Your warranties for the overall Service are provided in your Master Agreement. For
Incidental Software and Scripts, except as we otherwise expressly grant, these items are provided “AS-IS,” “With All Faults,”
and without warranties) of any kind (whether they are express, implied, or statutory). We have no obligations with respect
to support or maintenance, including without limitation, upgrades, updates, maintenance releases, or modifications, of the
Incidental Software and Scripts.
service nagle
no service pad
service tcp-keepalives-in
service tcp-keepalives-out
service timestamps debug datetime msec localtime show-timezone
service timestamps log datetime msec localtime show-timezone
service password-encryption
!
hostname autoinstall_config
!
!
aaa new-model
aaa authorization exec default local none
!
ip domain name amazon.com
!
enable secret 0 Cisco.123
username admin privilege 15 secret 0 Cisco.123
!
snmp-server community cisco RO
!
!
!### Generate RSA keys ####
crypto key generate rsa modulus 4096
ip ssh version 2
!
!
!
!### Enable Netconf ####
netconf-yang
!
!### Configure MGMT interface ###
interface GigabitEthernet0/0
ip address dhcp
!
interface GigabitEthernet0
ip address dhcp
!
!
!### change ip block size for faster tftp transfers
ip tftp blocksize 8192
!
!### Enable LLDP ####
lldp run
lldp holdtime 60
!
!
!### Enable mst ####
spanning-tree mode mst
spanning-tree extend system-id
!
!
logging buffered 51200
logging console informational
!
!### Enable iox service ###
iox
!
line con 0
login authentication default
transport preferred none
stopbits 1
password seedoflife
line vty 0 15
privilege level 15
login authentication default
transport input ssh
!
!
!
no banner exec
no banner login
!
!
end
\ No newline at end of file
ztp.py 0 → 100644
# Importing cli module
from cli import configure, cli, configurep, executep
import re
import time
import urllib
import sys
import logging
import os
from logging.handlers import RotatingFileHandler
import subprocess
software_mappings = {
'C9300-24P': {
'software_image': 'cat9k_iosxe.17.06.01.SPA.bin',
'software_version': '17.06.01',
'software_md5_checksum': 'fdb9c92bae37f9130d0ee6761afe2919'
},
'C9500-24Q': {
'software_image': 'cat9k_iosxe.17.06.01.SPA.bin',
'software_version': '17.06.01',
'software_md5_checksum': 'fdb9c92bae37f9130d0ee6761afe2919'
},
'ASR1001-HX': {
'software_image': 'asr1000-universalk9.17.05.01a.SPA.bin',
'software_version': '17.05.01a',
'software_md5_checksum': '0e4b1fc1448f8ee289634a41f75dc215'
}
}
http_server = '10.85.134.66'
log_tofile = True
release_set = ['16.06', '16.07']
def main():
try:
print ('###### STARTING ZTP SCRIPT ######\n')
# switch to enable/disbale persistent logger
if(log_tofile == True):
filepath = create_logfile()
configure_logger(filepath)
log_info('###### STARTING ZTP SCRIPT ######\n')
print ('**** Determining Device Model ****\n')
log_info('**** Determining Device Model ****\n')
model = get_model()
software_image = software_mappings[model]['software_image']
software_version = software_mappings[model]['software_version']
software_md5_checksum = software_mappings[model]['software_md5_checksum']
print ('**** Checking if upgrade is required or not ***** \n')
log_info('**** Checking if upgrade is required or not ***** \n')
update_status, current_version = upgrade_required(software_version)
if update_status:
#check if image transfer needed
if check_file_exists(software_image):
print(current_version)
if current_version[0:5] not in release_set:
if not verify_dst_image_md5(software_image, software_md5_checksum):
print ('*** Attempting to transfer image to switch.. ***')
log_info('*** Attempting to transfer image to switch.. ***')
file_transfer(http_server, software_image)
if not verify_dst_image_md5(software_image, software_md5_checksum):
log_critical('*** Failed Xfer mds hash mismatch ***')
raise ValueError('Failed Xfer')
else:
file_transfer(http_server, software_image)
if current_version[0:5] not in release_set:
if not verify_dst_image_md5(software_image, software_md5_checksum):
log_critical('XXX Failed Xfer XXX')
raise ValueError('XXX Failed Xfer XXX')
print ('*** Deploying EEM upgrade script ***')
log_info('*** Deploying EEM upgrade script ***')
deploy_eem_upgrade_script(software_image)
print ('*** Performing the upgrade - switch will reboot ***\n')
log_info('*** Performing the upgrade - switch will reboot ***\n')
cli('event manager run upgrade')
time.sleep(600)
print('*** EEM upgrade took more than 600 seconds to complete..Increase the sleep time by few minutes before retrying ***\n')
log_info('*** EEM upgrade took more than 600 seconds to reload the device..Increase the sleep time by few minutes before retrying ***\n')
else:
print ('*** No upgrade is required!!! *** \n')
log_info('*** No upgrade is required!!! *** \n')
# Cleanup any leftover install files
print ('*** Deploying Cleanup EEM Script ***')
log_info('*** Deploying Cleanup EEM Script ***')
deploy_eem_cleanup_script()
print ('*** Running Cleanup EEM Script ***')
log_info('*** Running Cleanup EEM Script ***')
cli('event manager run cleanup')
time.sleep(30)
#print config file name to download
config_file = '%s.cfg' % model
print('**** Downloading config file ****\n')
log_info('**** Downloading config file ****\n')
file_transfer(http_server, config_file)
print ('*** Trying to perform Day 0 configuration push **** \n')
log_info('*** Trying to perform Day 0 configuration push **** \n')
#configure_replace(config_file)
configure_merge(config_file)
configure('crypto key generate rsa modulus 4096')
print ('###### END OF ZTP SCRIPT ######\n')
log_info('###### END OF ZTP SCRIPT ######\n')
except Exception as e:
print('*** Failure encountered during day 0 provisioning . Aborting ZTP script execution. Error details below ***\n')
log_critical('*** Failure encountered during day 0 provisioning . Aborting ZTP script execution. Error details below ***\n' + e)
print(e)
sys.exit(e)
def configure_replace(file,file_system='flash:/' ):
config_command = 'configure replace %s%s force' % (file_system, file)
print("************************Replacing configuration************************\n")
log_info('************************Replacing configuration************************\n')
config_repl = executep(config_command)
time.sleep(120)
def configure_merge(file,file_system='flash:/'):
print("************************Merging running config with given config file************************\n")
log_info('************************Merging running config with given config file************************\n')
config_command = 'copy %s%s running-config' %(file_system,file)
config_repl = executep(config_command)
time.sleep(120)
def check_file_exists(file, file_system='flash:/'):
dir_check = 'dir ' + file_system + file
print ('*** Checking to see if %s exists on %s ***' % (file, file_system))
log_info('*** Checking to see if %s exists on %s ***' % (file, file_system))
results = cli(dir_check)
if 'No such file or directory' in results:
print ('*** The %s does NOT exist on %s ***' % (file, file_system))
log_info('*** The %s does NOT exist on %s ***' % (file, file_system))
return False
elif 'Directory of %s%s' % (file_system, file) in results:
print ('*** The %s DOES exist on %s ***' % (file, file_system))
log_info('*** The %s DOES exist on %s ***' % (file, file_system))
return True
elif 'Directory of %s%s' % ('bootflash:/', file) in results:
print ('*** The %s DOES exist on %s ***' % (file, 'bootflash:/'))
log_info('*** The %s DOES exist on %s ***' % (file, 'bootflash:/'))
return True
else:
log_critical('************************Unexpected output from check_file_exists************************\n')
raise ValueError("Unexpected output from check_file_exists")
def deploy_eem_cleanup_script():
install_command = 'install remove inactive'
eem_commands = ['event manager applet cleanup',
'event none maxrun 600',
'action 1.0 cli command "enable"',
'action 2.0 cli command "%s" pattern "\[y\/n\]"' % install_command,
'action 2.1 cli command "y" pattern "proceed"',
'action 2.2 cli command "y"'
]
results = configurep(eem_commands)
print ('*** Successfully configured cleanup EEM script on device! ***')
log_info('*** Successfully configured cleanup EEM script on device! ***')
def deploy_eem_upgrade_script(image):
install_command = 'install add file flash://' + image + ' activate commit'
eem_commands = ['event manager applet upgrade',
'event none maxrun 600',
'action 1.0 cli command "enable"',
'action 2.0 cli command "%s" pattern "\[y\/n\/q\]"' % install_command,
'action 2.1 cli command "n" pattern "proceed"',
'action 2.2 cli command "y"'
]
results = configurep(eem_commands)
print ('*** Successfully configured upgrade EEM script on device! ***')
log_info('*** Successfully configured upgrade EEM script on device! ***')
def file_transfer(http_server, file):
print('**** Start transferring file *******\n')
log_info('**** Start transferring file *******\n')
res = cli('copy http://%s/%s flash:%s' % (http_server,file,file))
print(res)
log_info(res)
print("\n")
print('**** Finished transferring device configuration file *******\n')
log_info('**** Finished transferring device configuration file *******\n')
def find_certs():
certs = cli('show run | include crypto pki')
if certs:
certs_split = certs.splitlines()
certs_split.remove('')
for cert in certs_split:
command = 'no %s' % (cert)
configure(command)
def get_serial():
print ("******** Trying to get Serial# *********** ")
log_info("******** Trying to get Serial# *********** ")
try:
show_version = cli('show version')
except Exception as e:
time.sleep(90)
show_version = cli('show version')
try:
serial = re.search(r"System Serial Number\s+:\s+(\S+)", show_version).group(1)
except AttributeError:
serial = re.search(r"Processor board ID\s+(\S+)", show_version).group(1)
return serial
def get_model():
print ("******** Trying to get Model *********** ")
log_info("******** Trying to get Model *********** ")
try:
show_version = cli('show version')
except Exception as e:
time.sleep(90)
show_version = cli('show version')
model = re.search(r"Model Number\s+:\s+(\S+)", show_version)
if model != None:
model = model.group(1)
else:
model = re.search(r"cisco\s(\w+-.*?)\s", show_version)
if model != None:
model = model.group(1)
return model
def get_file_system():
pass
def update_config(file,file_system='flash:/'):
update_running_config = 'copy %s%s running-config' % (file_system, file)
save_to_startup = 'write memory'
print("************************Copying to startup-config************************\n")
running_config = executep(update_running_config)
startup_config = executep(save_to_startup)
def upgrade_required(target_version):
# Obtains show version output
sh_version = cli('show version')
current_version = re.search(r"Cisco IOS XE Software, Version\s+(\S+)", sh_version).group(1)
print('**** Current Code Version is %s ****** \n' % current_version)
print('**** Target Code Version is %s ****** \n' % target_version)
log_info('**** Current Code Version is %s ****** \n' % current_version)
log_info('**** Target Code Version is %s ****** \n' % target_version)
# Returns False if on approved version or True if upgrade is required
if (target_version == current_version):
return False, current_version
else:
return True, current_version
def verify_dst_image_md5(image, src_md5, file_system='flash:/'):
verify_md5 = 'verify /md5 ' + file_system + image
print ('Verifying MD5 for ' + file_system + image)
#
try:
dst_md5 = cli(verify_md5)
if src_md5 in dst_md5:
print ('*** MD5 hashes match!! ***\n')
log_info('*** MD5 hashes match!! ***\n')
return True
else:
print ('**** Failed transfer due to MD5 checksum mismatch *****')
log_info('**** Failed transfer due to MD5 checksum mismatch *****')
return False
except Exception as e:
print ('**** MD5 checksum failed due to an exception *****')
print(e)
log_info('**** MD5 checksum failed due to an exception *****')
log_info(e)
return True
#output = subprocess.Popen(['md5sum', '/flash/'+image],stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)
#stdout_data, stderr_data = output.communicate()
#output.wait()
#outputdata = (stdout_data.decode('utf-8')).split()
#md5_returned = outputdata[0]
#if src_md5 == md5_returned:
# return True
#else:
# return False
def create_logfile():
try:
print ("******** Creating a persistent log file *********** ")
path = '/flash/guest-share/ztp.log'
#file_exists = os.path.isfile(path)
#if(file_exists == False):
#print ("******** ztp.log file dont exist . *********** ")
with open(path, 'a+') as fp:
pass
return path
except IOError:
print("Couldnt create a log file at guset-share .Trying to use /flash/ztp.log as an alternate log path")
path = '/flash/ztp.log'
#file_exists = os.path.isfile(path)
#if(file_exists == False):
# print ("******** ztp.log file dont exist . *********** ")
with open(path, 'a+') as fp:
pass
return path
except Exception as e:
print("Couldnt create a log file to proceed")
def configure_logger(path):
log_formatter = logging.Formatter('%(asctime)s :: %(levelname)s :: %(message)s')
logFile = path
#create a new file > 5 mb size
log_handler = RotatingFileHandler(logFile, mode='a', maxBytes=5*1024*1024, backupCount=10, encoding=None, delay=0)
log_handler.setFormatter(log_formatter)
log_handler.setLevel(logging.INFO)
ztp_log = logging.getLogger('root')
ztp_log.setLevel(logging.INFO)
ztp_log.addHandler(log_handler)
def log_info(message ):
if(log_tofile == True):
ztp_log = logging.getLogger('root')
ztp_log.info(message)
def log_critical(message ):
if(log_tofile == True):
ztp_log = logging.getLogger('root')
ztp_log.critical(message)
if __name__ == "__main__":
main()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment