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
Commit fd71ec51 authored by thl-cmk's avatar thl-cmk :flag_na:
Browse files

changed '_' in cli options to '-'

parent 03f368ff
No related branches found
No related tags found
No related merge requests found
......@@ -13,3 +13,10 @@
integrated status_debug.html with status.html
2023-01-29: rework of status page, make table body scrollable
2023-02-01: added cli options, changed debug/log output
cleanup: removed global variables
2023-02-22: removed regex -> was not working with PID: ISR4451-X/K9
added PNP_SERVER_VERSION
2023-02-23: added cli option -v/--version, --default_cfg
2023-02-26: reorganized open-pnp.py in to open_pnp_classes.py and open_pnp_utils.py
2023-32-07: changed '_' in cli options to '-' -> better readable/more bash like
......@@ -30,7 +30,7 @@ should deliver the configuration files, copy them in the `configs` subdirectory.
**Hint**: you can use different HTTP servers for the images and the configuration files
**Note**: the PnP server runs on HTTP. So there is no encryption for the configuration files as the are downloaded by the new devices.
**Note**: The _**open-pnp**_ server uses HTTP. So there is no encryption for the configuration files as the are downloaded by the new devices.
---
### Install the PnP server:
......@@ -56,7 +56,7 @@ on Linux
(.venv) :~/cisco_day0_provision/pnp$pip3 install flask xmltodict requests ifaddr tomli
# run the pnp server
(.venv) :~/cisco_day0_provision/pnp$ ./open-pnp.py --config_url http://192.168.10.133:8080/configs --image_url http://192.168.10.133:8080/images
(.venv) :~/cisco_day0_provision/pnp$ ./open-pnp.py --config-url http://192.168.10.133:8080/configs --image-url http://192.168.10.133:8080/images
Running PnP server. Stop with ctrl+c
Bind to IP-address : 0.0.0.0
......@@ -78,7 +78,7 @@ c:\cisco_day0_provision\pnp>.venv\Scripts\activate.bat
(.venv)c:\cisco_day0_provision\pnp>pip install flask xmltodict requests ifaddr tomli
(.venv)c:\cisco_day0_provision\pnp>python open-pnp.py --config_url http://192.168.10.133:8080/configs --image_url http://192.168.10.133:8080/images
(.venv)c:\cisco_day0_provision\pnp>python open-pnp.py --config-url http://192.168.10.133:8080/configs --image-url http://192.168.10.133:8080/images
Running PnP server. Stop with ctrl+c
Bind to IP-address : ::
......@@ -112,7 +112,8 @@ to use the PnP server you need to configure the server by modifying the followin
- [**_open-pnp.toml_**](/pnp/open-pnp.toml)
- [**_images.toml_**](/pnp/images.toml)
**NOTE:** after changing the PnP server configuration you need to restart the PnP server.
**NOTE:** after changing the PnP server configuration you need to reload the PnP server configuration by clicking
_**Reload CFG**_ on the status page.
**NOTE:** both files need to be in valid [TOML](https://toml.io/en/) format.
......@@ -121,32 +122,32 @@ to use the PnP server you need to configure the server by modifying the followin
```
# [settings]
# bind_pnp_server = "0.0.0.0"
# bind_pnp_server = "::"
# bind-pnp-server = "0.0.0.0"
# bind-pnp-server = "::"
# port = 8080
# time_format = "%y-%m-%dt%h:%m:%s"
# status_refresh = 10
# time-format = "%y-%m-%dt%h:%m:%s"
# status-refresh = 10
# debug = false
# log_to_file = true
# log_file = "log/pnp_debug.log"
# default_cfg_file = "default.cfg"
# image_data = "images.toml"
# image_url = "http://192.168.10.133:8080/images"
# config_url = "http://192.168.10.133:8080/configs"
# default_cfg = "DEFAULT.cfg"
# log-to-file = true
# log-file = "log/pnp_debug.log"
# default-cfg-file = "default.cfg"
# image-data = "images.toml"
# image-url = "http://192.168.10.133:8080/images"
# config-url = "http://192.168.10.133:8080/configs"
# default-cfg = "DEFAULT.cfg"
```
- **bind_pnp_server**: the IP-address of your open-pnp server box. (Use `"::"` for IPv6)
- **bind-pnp-server**: the IP-address of your open-pnp server box. (Use `"::"` for IPv6)
- **port**: the TCP port the server should listen on (remember for port 80 the server needs to run as root)
- **time_format**: the time format used in the status page
- **status_refresh**: the interval in seconds the status page will automatically reload
- **time-format**: the time format used in the status page
- **status-refresh**: the interval in seconds the status page will automatically reload
- **debug**: enable debug output with `debug = true`. Can be `true` or `false`.
- **log_file**: path/name of the log file
- **log_to_console**: send debug output to stdout. Can be `true` or `false`.
- **image_data**: the file containing the data of your IOS/IOS-XE images
- **image_base_url**: the base URL for your images
- **config_base_url**: the base URL for your configuration files
- **default_cfg**: default config to use if no device specific config is found.
- **log-file**: path/name of the log file
- **log-to-console**: send debug output to stdout. Can be `true` or `false`.
- **image-data**: the file containing the data of your IOS/IOS-XE images
- **image-base-url**: the base URL for your images
- **config-base-url**: the base URL for your configuration files
- **default-cfg**: default config to use if no device specific config is found.
**Note**: you need to uncomment (remove `# `) the lines if you change the values.
......@@ -175,52 +176,54 @@ models = ["C1000-8T-2G-L", "C1000-24P-4G-L", "C1000-24T-4G-L", "C1000-24T-4X-L",
### Command Line Options
With the Command Line Options you can override the default values, and the values from the _open-pnp.toml_ config file.
With the option --config_file CONFIG_FILE you can specify a costume config file to use instead of _open-pnp.toml_.
With the option --config-file CONFIG-FILE you can specify a costume config file to use instead of _open-pnp.toml_.
```
$ ./open-pnp.py -h
usage: open-pnp.py [-h] [-b BIND_PNP_SERVER] [-p PORT] [-r STATUS_REFRESH]
[-v] [--config_file CONFIG_FILE] [--config_url CONFIG_URL]
[--image_data IMAGE_DATA] [--image_url IMAGE_URL] [--debug]
[--default_cfg DEFAULT_CFG] [--log_file LOG_FILE]
[--log_to_console] [--time_format TIME_FORMAT]
[-v] [--config-file CONFIG_FILE] [--config-url CONFIG_URL]
[--image-data IMAGE_DATA] [--image-url IMAGE_URL] [--debug]
[--default-cfg DEFAULT_CFG] [--log-file LOG_FILE]
[--log-to-console] [--time-format TIME_FORMAT]
This is a basic implementation of the Cisco PnP protocol. It is intended to
roll out image updates and configurations for Cisco IOS/IOS-XE devices on day0.
20230223.v1.0.1 | Written by: thl-cmk, for more information see: https://thl-cmk.hopto.org
20230227.v1.0.2 | Written by: thl-cmk, for more information see: https://thl-cmk.hopto.org
options:
optional arguments:
-h, --help show this help message and exit
-b BIND_PNP_SERVER, --bind_pnp_server BIND_PNP_SERVER
-b BIND_PNP_SERVER, --bind-pnp-server BIND_PNP_SERVER
Bind PnP server to IP-address. (default: 0.0.0.0)
-p PORT, --port PORT TCP port to listen on. (default: 8080)
-r STATUS_REFRESH, --status_refresh STATUS_REFRESH
-r STATUS_REFRESH, --status-refresh STATUS_REFRESH
Time in seconds to refresh PnP server status page. (default: 60)
-v, --version Print open-pnp-server version and exit
--config_file CONFIG_FILE
--config-file CONFIG_FILE
Path/name of open PnP server config file. (default: open-pnp.toml)
--config_url CONFIG_URL
--config-url CONFIG_URL
Download URL for config files. I.e. http://192.168.10.133:8080/configs
--image_data IMAGE_DATA
--image-data IMAGE_DATA
File containing the image description. (default: images.toml)
--image_url IMAGE_URL
--image-url IMAGE_URL
Download URL for image files. I.e. http://192.168.10.133:8080/images
--debug Enable Debug output send to "log_file".
--default_cfg DEFAULT_CFG
--debug Enable Debug output send to "log-file".
--default-cfg DEFAULT_CFG
default config to use if no device specific config is found. (default: DEFAULT.cfg)
--log_file LOG_FILE Path/name of the logfile. (default: log/pnp_debug.log, requires --debug)
--log_to_console Enable debug output send to stdout (requires --debug).
--time_format TIME_FORMAT
--log-file LOG_FILE Path/name of the logfile. (default: log/pnp_debug.log, requires --debug)
--log-to-console Enable debug output send to stdout (requires --debug).
--time-format TIME_FORMAT
Format string to render time. (default: %Y-%m-%dT%H:%M:%S)
Usage: python open-pnp.py --config_url http://192.168.10.133:8080/configs --image_url http://192.168.10.133:8080/images
Usage: python open-pnp.py --config-url http://192.168.10.133:8080/configs --image-url http://192.168.10.133:8080/images
```
---
### PnP server discovery
The IOS-XE device can discover a PnP server via DHCP option 43 or using DNS lookup for the hostname _pnpserver.your.domain_. Replaced _your.domain_ by the DNS domain the device receives via DHCP. With DHCP, the DHCP server needs to send the vendor option 43.
The IOS-XE device can discover a PnP server via DHCP option 43 or using DNS lookup for the hostname
_pnpserver.your.domain_. Replaced _your.domain_ by the DNS domain the device receives via DHCP. With
DHCP, the DHCP server needs to send the vendor option 43.
Structure of DHCP option 43:
......
version 17.6
event manager applet remove_inactive authorization bypass
description remove inactive firmware after reload, rest-config
event timer cron cron-entry "@reboot" maxrun 600 name REMOVE-INACTIVE
! event timer countdown time 60 maxrun 600 name REMOVE-INACTIVE
action 0000.00 cli command "enable"
action 0000.10 syslog facility "EEM" msg "remove inactive images"
action 0000.15 cli command "terminal length 0"
action 0000.20 cli command "terminal width 0"
!
action 0010.00 syslog facility "EEM" msg "reset configuration (no reload) START"
action 0010.10 cli command "pnp service reset no-reload" pattern "\[yes/no\]"
action 0010.15 cli command "y"
action 0010.99 syslog facility "EEM" msg "reset configuration (no reload) DONE"
!
action 0020.00 syslog facility "EEM" msg "remove inactive images start"
action 0020.05 cli command "install remove inactive" pattern "\[y/n\]"
action 0020.10 cli command "y"
action 0020.99 syslog facility "EEM" msg "remove inactive images done"
!
exit
end
version 17.6
event manager applet remove_inactive authorization bypass
description remove inactive firmware images
event timer countdown time 10 maxrun 600 name REMOVE-INACTIVE
! set defaults
action 0000.00 set _number_of_images 0
!
action 0005.00 cli command "enable"
action 0005.10 syslog facility "EEM" msg "remove inactive images"
action 0005.15 cli command "terminal length 0"
action 0005.20 cli command "terminal width 0"
!
action 0010.00 syslog facility "EEM" msg "Check for *.bin files START"
action 0010.05 cli command "dir /recursive | i [A-Za-z0-9]\.bin$"
action 0010.10 foreach _line $_cli_result "\n"
action 0010.15 set _match ""
action 0010.20 regexp "[A-Za-z0-9]\.bin" "$_line" _match
action 0010.25 if $_match ne ""
action 0010.30 add $_number_of_images 1
action 0010.35 set _number_of_images $_result
action 0010.40 end
action 0010.45 end
action 0010.50 syslog facility "EEM" msg "number of images found: $_number_of_images"
action 0010.99 syslog facility "EEM" msg "Check for *.bin files DONE"
!
action 0020.00 syslog facility "EEM" msg "remove inactive images START"
action 0020.05 if $_number_of_images gt 1
action 0020.10 cli command "install remove inactive" pattern "\[y/n\]"
action 0020.15 cli command "y"
action 0020.20 end
action 0020.99 syslog facility "EEM" msg "remove inactive images DONE"
!
action 0050.00 syslog facility "EEM" msg "remove EEM script remove_inactive START"
action 0050.10 cli command "conf t"
action 0050.15 cli command " no event manager applet remove_inactive"
action 0050.20 cli command "end"
! action 0050.25 cli command "write mem"
action 0050.99 syslog facility "EEM" msg "remove EEM script remove_inactive DONE"
end
......@@ -14,13 +14,13 @@ models = []
version = "17.6.4"
md5 = "2caa962f5ed0ecc52f99b90c733c54de"
size = 706565772
models = ["C1117-4PMLTEEAWE"]
models = []
["c1100-universalk9.17.10.01a.SPA.bin"]
version = "17.10.1a"
md5 = "a0cd6218c42f19bed425e3c63a11bcda"
size = 689542648
models = []
models = ["C1117-4PMLTEEAWE"]
["c3560cx-universalk9-mz.152-7.E7.bin"]
version = "15.2(7)E7"
......
......@@ -34,6 +34,8 @@
# added PNP_SERVER_VERSION
# 2023-02-23: added cli option -v/--version, --default_cfg
# 2023-02-26: reorganized open-pnp.py in to open_pnp_classes.py and open_pnp_utils.py
# 2023-32-07: changed '_' in cli options to '-' -> better readable/more bash like
#
#
# pip install flask xmltodict requests ifaddr tomli
#
......@@ -76,7 +78,7 @@ from open_pnp_utils import (
)
PNP_SERVER_VERSION = '20230223.v1.0.1'
PNP_SERVER_VERSION = '20230227.v1.0.2'
def pnp_device_info(udi: str, correlator: str, info_type: str) -> str:
......@@ -279,6 +281,7 @@ def check_update(udi: str):
device.error_code = ERROR.ERROR_NO_FREE_SPACE
device.hard_error = True
# flask
app = Flask(__name__, template_folder='./templates')
......@@ -472,10 +475,10 @@ if __name__ == '__main__':
cli.show_server_banner = lambda *args: None
if SETTINGS.image_url == '':
print(f'image_url not set, check {SETTINGS.cfg_file} or see open-pnp.py -h')
print(f'image-url not set, check {SETTINGS.cfg_file} or see open-pnp.py -h')
exit(1)
if SETTINGS.config_url == '':
print(f'config_url not set, check {SETTINGS.cfg_file} or see open-pnp.py -h')
print(f'config-url not set, check {SETTINGS.cfg_file} or see open-pnp.py -h')
exit(1)
if SETTINGS.debug:
......
......@@ -62,8 +62,7 @@ class Settings:
print(f'ERROR: Data file {cfg_file} not found! ({e})')
exit(1)
except TOMLDecodeError as e:
print(
f'ERROR: Data file {cfg_file} is not in valid toml format! ({e})')
print(f'ERROR: Data file {cfg_file} is not in valid toml format! ({e})')
exit(2)
self.__settings.update(self.__args)
......@@ -106,7 +105,7 @@ class Settings:
@property
def log_file(self) -> str:
return self.__settings['log_file']
return self.__settings['log-file']
@property
def image_url(self) -> str:
......@@ -118,7 +117,7 @@ class Settings:
@property
def default_cfg(self) -> str:
return self.__settings['default_cfg']
return self.__settings['default-cfg']
class SoftwareImage:
......@@ -315,5 +314,6 @@ class Images:
def images(self) -> Dict[str, Any]:
return self.__images
ERROR = ErrorCodes()
PNPFLOW = PnpFlow()
......@@ -60,42 +60,42 @@ def log_critical(message: str, debug: bool):
log.critical(message)
def parse_arguments(PNP_SERVER_VERSION: str) -> arg_Namespace:
def parse_arguments(pnp_server_version: str) -> arg_Namespace:
parser = ArgumentParser(
prog='open-pnp.py',
description='This is a basic implementation of the Cisco PnP protocol. It is intended to'
'\nroll out image updates and configurations for Cisco IOS/IOS-XE devices on day0.'
'\n'
f'\n{PNP_SERVER_VERSION} | Written by: thl-cmk, for more information see: https://thl-cmk.hopto.org',
f'\n{pnp_server_version} | Written by: thl-cmk, for more information see: https://thl-cmk.hopto.org',
formatter_class=RawTextHelpFormatter,
epilog='Usage: python open-pnp.py --config_url http://192.168.10.133:8080/configs '
'--image_url http://192.168.10.133:8080/images',
epilog='Usage: python open-pnp.py --config-url http://192.168.10.133:8080/configs '
'--image-url http://192.168.10.133:8080/images',
)
parser.add_argument('-b', '--bind_pnp_server', type=str,
parser.add_argument('-b', '--bind-pnp-server', type=str,
help='Bind PnP server to IP-address. (default: 0.0.0.0)')
parser.add_argument('-p', '--port', type=int,
help='TCP port to listen on. (default: 8080)')
parser.add_argument('-r', '--status_refresh', type=int,
parser.add_argument('-r', '--status-refresh', type=int,
help='Time in seconds to refresh PnP server status page. (default: 60)')
parser.add_argument('-v', '--version', default=False, action='store_const', const=True,
help='Print open-pnp-server version and exit')
parser.add_argument('--config_file', type=str,
parser.add_argument('--config-file', type=str,
help='Path/name of open PnP server config file. (default: open-pnp.toml)')
parser.add_argument('--config_url', type=str,
parser.add_argument('--config-url', type=str,
help='Download URL for config files. I.e. http://192.168.10.133:8080/configs')
parser.add_argument('--image_data', type=str,
parser.add_argument('--image-data', type=str,
help='File containing the image description. (default: images.toml)')
parser.add_argument('--image_url', type=str,
parser.add_argument('--image-url', type=str,
help='Download URL for image files. I.e. http://192.168.10.133:8080/images')
parser.add_argument('--debug', default=False, action='store_const', const=True,
help='Enable Debug output send to "log_file".')
parser.add_argument('--default_cfg', type=str,
help='Enable Debug output send to "log-file".')
parser.add_argument('--default-cfg', type=str,
help='default config to use if no device specific config is found. (default: DEFAULT.cfg)')
parser.add_argument('--log_file', type=str,
parser.add_argument('--log-file', type=str,
help='Path/name of the logfile. (default: log/pnp_debug.log, requires --debug) ')
parser.add_argument('--log_to_console', default=False, action='store_const', const=True,
parser.add_argument('--log-to-console', default=False, action='store_const', const=True,
help='Enable debug output send to stdout (requires --debug).')
parser.add_argument('--time_format', type=str,
parser.add_argument('--time-format', type=str,
help='Format string to render time. (default: %%Y-%%m-%%dT%%H:%%M:%%S)')
return parser.parse_args()
......
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