From f0c550a903721b9efa6bb0fe466c0820677d6870 Mon Sep 17 00:00:00 2001 From: simone-dell Date: Sat, 3 Nov 2018 20:48:06 -0700 Subject: [PATCH 01/13] adding ZTP high level design --- doc/ztp/ztp_hld.md | 135 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 doc/ztp/ztp_hld.md diff --git a/doc/ztp/ztp_hld.md b/doc/ztp/ztp_hld.md new file mode 100644 index 0000000000..4f55b4f3ab --- /dev/null +++ b/doc/ztp/ztp_hld.md @@ -0,0 +1,135 @@ + gh Level Design +# Requirements +- Build option to have ZTP enabled +- SNMP should be available through the ZTP service +- ZTP should verify, download and install SONiC image +- Updategraph handles all configuration during ZTP service +- ZTP should receive post config validation script, that collects switch info and sends it back to a remote location for processing +- ZTP status may be logged through syslog +- Interruption of ZTP service should disable the service gracefully + +# Flow +For ZTP using DHCP, provisioning initially takes place over the management network and is initiated through a DHCP hook. A DHCP option is used to specify a configuration script. This script is then requested from the Web server and executed locally on the switch. +1. Simplify installation of switch, the steps involved will be + - Rack and Stack + - Connect + - Power-on +2. Onie Boots into SONiC (with ZTP enabled) from flash + - Power-on ZTP service will take over to load the initial configuration. + - ZTP service flag $enabled is true + - ZTP service flag $post_install is false + - ZTP service flag $post_config is false +3. The switch now enters ZTP mode and does the following, + - Obtains an IP address from the DHCP server + - Obtains the URL for the SONIC image, provisioning script, and post config validation script +4. At this step, the switch will have information to reach the HTTP / TFTP server information by DHCP option 66 or Option 240. +5. ZTP service will relay to updategraph service + - Within updategraph, ztp_enabled is true, and post_install is false + - This triggers updategraph to configure the device with an default config + - Upon exiting updategraph, SNMP will start +6. ZTP service will now download the software image file. +7. ZTP service will validate image to be a SONIC image compatible with the current platform. +8. ZTP service will check remaining hard disk for space before doing image install. +9. ZTP service will install image using sonic-installer + - ZTP service flag $post_install is true +10. ZTP service will enable updategraph +11. ZTP service will call for reboot to apply new SONIC image, with option ZTP-enabled –post_install +12. Upon reboot, if ZTP service flag $post_install is true, ZTP hands off to updategraph +13. The configuration script is received and applied by updategraph, returns to ZTP service +ZTP service flag $post_config is true +14. Validation: + - SONIC device will download post config validation script through ZTP enabled DHCP option + - The script is customized based on user preference + - The script collects local info and sends it back to server using information in the script itself +15. Delete old SONIC image upon successful reimage/ ZTP status check: + - Check if $post_install is true + - Check if $post_config is true + - Set $enable to false + - Verify no errors were thrown during the service + - Output to syslog server and var/log/syslog + +### Updategraph +Needs to be updated to provide default config to the switch when ztp_enabled is true +Needs to continue as currently designed when ztp_enabled is true and post_install is true +Can be used to download config file and apply config + +### Interruption of ZTP +Through command line utility “ZTP Disable” +Sets ZTP $enabled flag to FALSE +If ZTP is interrupted mid-service, output is shown +If ZTP service receives “NA_ZTP” flag, continue updategraph with default config +ZTP service needs to have separate option for interruption than updategraph +If ZTP service is interrupted, updategraph should still be enabled and allowed to continue + +### Syslog +ZTP status should be logged to syslog server and /var/log/syslog + +### Build Option +Need to allow build time option to compile with ZTP enabled + +# Error Cases +- Case: Switch receives invalid URLs from DHCP server + - Switch should output error logs to syslog and apply default config. Kill the ZTP service, and allow other services to come up +- Case: Switch receives invalid OS image + - Switch should output error logs to syslog and apply default config. Kill the ZTP service, and allow other services to come up +- Case: Switch does not have enough memory to store the image + - Switch should output error logs to syslog and apply default config. Kill the ZTP service, and allow other services to come up +- Case: Switch receives invalid configuration from DHCP server + - Switch should output error logs to syslog, and gracefully exit the ZTP service, logging that image install completed successfully, and configuration script is invalid. +- Case: Post-validation script fails + - The success on the script is processed by a remote server. ZTP service is exited gracefully, logging with image install completed successfully. + + +# ZTP CLI +The ZTP CLI will allow the user to manually start, stop, and obtain status of the ZTP service. + +Will show the user whether ZTD is enabled, the date of the last execution of the ZTP script, and the completion status of the ZTP service + + show ztp-status +The ZTP status will show the user the current SONiC image, if the configuration was successful, and if the post-configuration script was run, as well as the time of the last successful completion of the ZTP service + + ztp reload +The user can re-enable ZTP after a failed state using the CLI. This puts the switch into “factory setting” and reloads with ZTP enabled, allowing for provisioning restart. + + ztp cancel +The user can interrupt the ZTP service: +- If cancelled before image download, ZTP service will exit +- If cancelled after image download but before reboot, ZTP service will output sonic_installer list and exit +- If cancelled after reboot, ZTP service will not apply any configuration, and exit +- If cancelled after configuration, ZTP service will not continue with the validation script, and exit + + +# Action Items + +## ZTP SERVICE +- The service needs to start immediately after boot +- If ZTP is not enabled, exit the service +- If ZTP is enabled and post_install is false, run updategraph to apply default configuration +- Acquire image and configuration script from HTTP/TFTP server +- Install the image using sonic-installer +- Reload to reimage the device +- ZTP is enabled and post_install is true, apply configurations using updategraph +- Run post_validation script +- Exit ZTP +- Test to see if Ansible server is reachable for further configuration +## Updategraph +- If ZTP is enabled but post_install is false, apply default configs to the switch and exit +- If ZTP is enabled and post_install is true, continue to apply configs based on graph_url + +# Phases +## Phase 1 +- Implement image download and install +- Implement image and config validation +## Phase 2 +- Post install script: downloaded after updategraph finishes +- Dependent on user +- Implement validation of management port +- Implement validation of neighbors +- Implement validation of config based on serial number +## Phase 3 +- Command line utility +- ZTP interrupt process +- ZTP test planif [ -n "$new_acl_url" ]; then + echo $new_acl_url > /tmp/dhcp_acl_url + fi + From a185351b78db0b3feb8e5c807694396ddcfd113b Mon Sep 17 00:00:00 2001 From: simone-dell Date: Sat, 3 Nov 2018 20:56:19 -0700 Subject: [PATCH 02/13] fixing table of contents --- doc/ztp/ztp_hld.md | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/doc/ztp/ztp_hld.md b/doc/ztp/ztp_hld.md index 4f55b4f3ab..18210b0328 100644 --- a/doc/ztp/ztp_hld.md +++ b/doc/ztp/ztp_hld.md @@ -1,5 +1,19 @@ - gh Level Design -# Requirements +# Zero Touch Provisioning (ZTP) +# High Level Design + +### Rev 1.0 + +# Table of Contents + * [Revision](#revision) + * [Requirements](#requirements) + * [Flow](#flow) + +###### Revision +| Rev | Date | Author | Change Description | +|:---:|:-----------:|:------------------:|-----------------------------------| +| 0.1 | 11/3/18 | Simone Salman | Initial version | + +###### Requirements - Build option to have ZTP enabled - SNMP should be available through the ZTP service - ZTP should verify, download and install SONiC image @@ -8,7 +22,7 @@ - ZTP status may be logged through syslog - Interruption of ZTP service should disable the service gracefully -# Flow +###### Flow For ZTP using DHCP, provisioning initially takes place over the management network and is initiated through a DHCP hook. A DHCP option is used to specify a configuration script. This script is then requested from the Web server and executed locally on the switch. 1. Simplify installation of switch, the steps involved will be - Rack and Stack From 0272dbdc0973c13731bdcd44e1213e2d05355a2d Mon Sep 17 00:00:00 2001 From: simone-dell Date: Sat, 3 Nov 2018 21:04:15 -0700 Subject: [PATCH 03/13] markdown editing --- doc/ztp/ztp_hld.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/doc/ztp/ztp_hld.md b/doc/ztp/ztp_hld.md index 18210b0328..2fc972f2d9 100644 --- a/doc/ztp/ztp_hld.md +++ b/doc/ztp/ztp_hld.md @@ -7,13 +7,17 @@ * [Revision](#revision) * [Requirements](#requirements) * [Flow](#flow) + * [Error Cases](#error-cases) + * [ZTP CLI](#ztp-cli) + * [Action Items](#action-items) + * [Phases](#phases) -###### Revision +# Revision | Rev | Date | Author | Change Description | |:---:|:-----------:|:------------------:|-----------------------------------| | 0.1 | 11/3/18 | Simone Salman | Initial version | -###### Requirements +# Requirements - Build option to have ZTP enabled - SNMP should be available through the ZTP service - ZTP should verify, download and install SONiC image @@ -22,7 +26,7 @@ - ZTP status may be logged through syslog - Interruption of ZTP service should disable the service gracefully -###### Flow +# Flow For ZTP using DHCP, provisioning initially takes place over the management network and is initiated through a DHCP hook. A DHCP option is used to specify a configuration script. This script is then requested from the Web server and executed locally on the switch. 1. Simplify installation of switch, the steps involved will be - Rack and Stack From a38a522559e8b034075a5884fa21ab1b785dc183 Mon Sep 17 00:00:00 2001 From: simone-dell Date: Sat, 3 Nov 2018 21:11:01 -0700 Subject: [PATCH 04/13] adding image --- images/ztp_hld/ztp_flow.jpg | Bin 0 -> 32705 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 images/ztp_hld/ztp_flow.jpg diff --git a/images/ztp_hld/ztp_flow.jpg b/images/ztp_hld/ztp_flow.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d4008cb076ee62c8f841b5e00e031518947db5a8 GIT binary patch literal 32705 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 literal 0 HcmV?d00001 From 2f128e40dd9216a5e1ed216e4365860ed36c4ca6 Mon Sep 17 00:00:00 2001 From: simone-dell Date: Sat, 3 Nov 2018 21:13:54 -0700 Subject: [PATCH 05/13] linking image --- doc/ztp/ztp_hld.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/ztp/ztp_hld.md b/doc/ztp/ztp_hld.md index 2fc972f2d9..7df189d64c 100644 --- a/doc/ztp/ztp_hld.md +++ b/doc/ztp/ztp_hld.md @@ -27,6 +27,7 @@ - Interruption of ZTP service should disable the service gracefully # Flow +![](https://github.com/simone-dell/SONiC/blob/ztp/images/ztp_hld/ztp_flow.jpg) For ZTP using DHCP, provisioning initially takes place over the management network and is initiated through a DHCP hook. A DHCP option is used to specify a configuration script. This script is then requested from the Web server and executed locally on the switch. 1. Simplify installation of switch, the steps involved will be - Rack and Stack From 59345d154f2f9fe240f71e2524b13669475ce178 Mon Sep 17 00:00:00 2001 From: simone-dell Date: Sat, 3 Nov 2018 21:14:45 -0700 Subject: [PATCH 06/13] text editing --- doc/ztp/ztp_hld.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/ztp/ztp_hld.md b/doc/ztp/ztp_hld.md index 7df189d64c..fa37f1dff7 100644 --- a/doc/ztp/ztp_hld.md +++ b/doc/ztp/ztp_hld.md @@ -28,6 +28,7 @@ # Flow ![](https://github.com/simone-dell/SONiC/blob/ztp/images/ztp_hld/ztp_flow.jpg) + For ZTP using DHCP, provisioning initially takes place over the management network and is initiated through a DHCP hook. A DHCP option is used to specify a configuration script. This script is then requested from the Web server and executed locally on the switch. 1. Simplify installation of switch, the steps involved will be - Rack and Stack From 3b7f6b8a191b26b7ca1cc7a59d127aca41f03ccc Mon Sep 17 00:00:00 2001 From: chitra-raghavan Date: Wed, 14 Nov 2018 19:41:30 -0800 Subject: [PATCH 07/13] addressing review comments --- doc/ztp/ztp_hld.md | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/doc/ztp/ztp_hld.md b/doc/ztp/ztp_hld.md index fa37f1dff7..ca5d5011b6 100644 --- a/doc/ztp/ztp_hld.md +++ b/doc/ztp/ztp_hld.md @@ -6,6 +6,7 @@ # Table of Contents * [Revision](#revision) * [Requirements](#requirements) + * [DHCP Options](#dhcp-options) * [Flow](#flow) * [Error Cases](#error-cases) * [ZTP CLI](#ztp-cli) @@ -13,18 +14,27 @@ * [Phases](#phases) # Revision -| Rev | Date | Author | Change Description | -|:---:|:-----------:|:------------------:|-----------------------------------| -| 0.1 | 11/3/18 | Simone Salman | Initial version | +| Rev | Date | Author | Change Description | +|:---:|:------------:|:------------------:|-----------------------------------| +| 0.1 | 11/03/18 | Simone Salman | Initial version | +|:---:|:------------:|:------------------:|-----------------------------------| +| 0.2 | 11/14/18 | Simone Salman | Addressing Review comments | # Requirements - Build option to have ZTP enabled -- SNMP should be available through the ZTP service +- SNMP should be enabled during the ZTP process (achieved through leveraging updategraph) - ZTP should verify, download and install SONiC image - Updategraph handles all configuration during ZTP service - ZTP should receive post config validation script, that collects switch info and sends it back to a remote location for processing -- ZTP status may be logged through syslog -- Interruption of ZTP service should disable the service gracefully +- ZTP status should be logged through syslog +- Interruption of ZTP service should set ZTP status as incomplete/interrupted and ZTP should be disabled. + +# DHCP Options +| DHCP Option | Information | Explanation | +|:-----------:|:-------------------:|:-------------------------------------------------:| +| 227 | ztp_image_url | URL for the SONiC image for the switch to dowload | +|:-----------:|:-------------------:|:-------------------------------------------------:| +| 228 | validation_url | URL for the validation script -- a script that runs post config and collects device info and sends it for processing to a remote location designated within the validation script | # Flow ![](https://github.com/simone-dell/SONiC/blob/ztp/images/ztp_hld/ztp_flow.jpg) @@ -41,15 +51,15 @@ For ZTP using DHCP, provisioning initially takes place over the management netwo - ZTP service flag $post_config is false 3. The switch now enters ZTP mode and does the following, - Obtains an IP address from the DHCP server - - Obtains the URL for the SONIC image, provisioning script, and post config validation script -4. At this step, the switch will have information to reach the HTTP / TFTP server information by DHCP option 66 or Option 240. -5. ZTP service will relay to updategraph service + - Obtains the URL for the SONIC image, minigraph, and post config validation script +4. At this step, the switch will have information to reach the HTTP / TFTP server information. +5. ZTP service will enable and start updategraph service - Within updategraph, ztp_enabled is true, and post_install is false - This triggers updategraph to configure the device with an default config - Upon exiting updategraph, SNMP will start 6. ZTP service will now download the software image file. -7. ZTP service will validate image to be a SONIC image compatible with the current platform. -8. ZTP service will check remaining hard disk for space before doing image install. +7. sonic_installer will validate image to be a SONIC image compatible with the current platform. +8. sonic_installer will check remaining hard disk for space before doing image install. 9. ZTP service will install image using sonic-installer - ZTP service flag $post_install is true 10. ZTP service will enable updategraph @@ -108,7 +118,7 @@ Will show the user whether ZTD is enabled, the date of the last execution of the show ztp-status The ZTP status will show the user the current SONiC image, if the configuration was successful, and if the post-configuration script was run, as well as the time of the last successful completion of the ZTP service - ztp reload + config ztp enable/disable The user can re-enable ZTP after a failed state using the CLI. This puts the switch into “factory setting” and reloads with ZTP enabled, allowing for provisioning restart. ztp cancel From b8b39705f3df89b52cc5f969bea5f851ff5b88f6 Mon Sep 17 00:00:00 2001 From: chitra-raghavan Date: Wed, 14 Nov 2018 19:43:17 -0800 Subject: [PATCH 08/13] fixing text errors --- doc/ztp/ztp_hld.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/doc/ztp/ztp_hld.md b/doc/ztp/ztp_hld.md index ca5d5011b6..bcb6e47789 100644 --- a/doc/ztp/ztp_hld.md +++ b/doc/ztp/ztp_hld.md @@ -17,7 +17,6 @@ | Rev | Date | Author | Change Description | |:---:|:------------:|:------------------:|-----------------------------------| | 0.1 | 11/03/18 | Simone Salman | Initial version | -|:---:|:------------:|:------------------:|-----------------------------------| | 0.2 | 11/14/18 | Simone Salman | Addressing Review comments | # Requirements @@ -33,7 +32,6 @@ | DHCP Option | Information | Explanation | |:-----------:|:-------------------:|:-------------------------------------------------:| | 227 | ztp_image_url | URL for the SONiC image for the switch to dowload | -|:-----------:|:-------------------:|:-------------------------------------------------:| | 228 | validation_url | URL for the validation script -- a script that runs post config and collects device info and sends it for processing to a remote location designated within the validation script | # Flow From aa41ac0ff257320ea85087ce3cac979dc8e42f48 Mon Sep 17 00:00:00 2001 From: simone-dell Date: Wed, 14 Nov 2018 19:48:45 -0800 Subject: [PATCH 09/13] latest review --- doc/ztp/ztp_hld.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/ztp/ztp_hld.md b/doc/ztp/ztp_hld.md index bcb6e47789..81100f24e6 100644 --- a/doc/ztp/ztp_hld.md +++ b/doc/ztp/ztp_hld.md @@ -16,8 +16,8 @@ # Revision | Rev | Date | Author | Change Description | |:---:|:------------:|:------------------:|-----------------------------------| -| 0.1 | 11/03/18 | Simone Salman | Initial version | -| 0.2 | 11/14/18 | Simone Salman | Addressing Review comments | +| v0.1 | 11/03/18 | Simone Salman | Initial version | +| v0.2 | 11/14/18 | Simone Salman | Addressing Review comments | # Requirements - Build option to have ZTP enabled From a17053d0f0e78a50d8e3587cfeda26f6d90ac03b Mon Sep 17 00:00:00 2001 From: simone-dell Date: Fri, 16 Nov 2018 14:38:07 -0800 Subject: [PATCH 10/13] added more information to address review comments --- doc/ztp/ztp_hld.md | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/doc/ztp/ztp_hld.md b/doc/ztp/ztp_hld.md index 81100f24e6..01658ae09e 100644 --- a/doc/ztp/ztp_hld.md +++ b/doc/ztp/ztp_hld.md @@ -14,7 +14,7 @@ * [Phases](#phases) # Revision -| Rev | Date | Author | Change Description | +| Rev | Date | Author | Change Description | |:---:|:------------:|:------------------:|-----------------------------------| | v0.1 | 11/03/18 | Simone Salman | Initial version | | v0.2 | 11/14/18 | Simone Salman | Addressing Review comments | @@ -29,10 +29,13 @@ - Interruption of ZTP service should set ZTP status as incomplete/interrupted and ZTP should be disabled. # DHCP Options -| DHCP Option | Information | Explanation | +| DHCP Option | Information | Explanation | |:-----------:|:-------------------:|:-------------------------------------------------:| -| 227 | ztp_image_url | URL for the SONiC image for the switch to dowload | -| 228 | validation_url | URL for the validation script -- a script that runs post config and collects device info and sends it for processing to a remote location designated within the validation script | +| 224 | snmp_community | usage implemented through updategraph | +| 225 | minigraph_url | usage implemented through updategraph | +| 226 | acl_url | usage implemented through updategraph | +| 227 | ztp_image_url | URL for the SONiC image for the switch to dowload | +| 228 | validation_url | URL for the validation script -- a script that runs post config and collects device info and sends it for processing to a remote location designated within the validation script | # Flow ![](https://github.com/simone-dell/SONiC/blob/ztp/images/ztp_hld/ztp_flow.jpg) @@ -50,7 +53,7 @@ For ZTP using DHCP, provisioning initially takes place over the management netwo 3. The switch now enters ZTP mode and does the following, - Obtains an IP address from the DHCP server - Obtains the URL for the SONIC image, minigraph, and post config validation script -4. At this step, the switch will have information to reach the HTTP / TFTP server information. +4. At this step, the switch will have information to reach the HTTP / TFTP server through URLs given by DHCP server. 5. ZTP service will enable and start updategraph service - Within updategraph, ztp_enabled is true, and post_install is false - This triggers updategraph to configure the device with an default config @@ -96,8 +99,12 @@ ZTP status should be logged to syslog server and /var/log/syslog Need to allow build time option to compile with ZTP enabled # Error Cases -- Case: Switch receives invalid URLs from DHCP server - - Switch should output error logs to syslog and apply default config. Kill the ZTP service, and allow other services to come up +- Case: Switch receives invalid SONiC image URL from DHCP server + - Switch should output error logs to syslog and apply default config. Kill the ZTP service with aborted status, and allow other services to come up +- Case: Switch receives invalid configuration URL from DHCP server + - Switch should output error logs to syslog and apply default config. Kill the ZTP service with aborted status, and allow other services to come up +- Case: Switch receives invalid post-config validation URL from DHCP server + - Switch should output error logs to syslog. Disable the ZTP service, and allow other services to come up - Case: Switch receives invalid OS image - Switch should output error logs to syslog and apply default config. Kill the ZTP service, and allow other services to come up - Case: Switch does not have enough memory to store the image From 74ba4ff4383d6c2d9c40dbb7191ce8e41b7d7be2 Mon Sep 17 00:00:00 2001 From: simone-dell Date: Fri, 16 Nov 2018 14:47:12 -0800 Subject: [PATCH 11/13] changes to DHCP options section --- doc/ztp/ztp_hld.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/ztp/ztp_hld.md b/doc/ztp/ztp_hld.md index 01658ae09e..c049d02f39 100644 --- a/doc/ztp/ztp_hld.md +++ b/doc/ztp/ztp_hld.md @@ -29,8 +29,9 @@ - Interruption of ZTP service should set ZTP status as incomplete/interrupted and ZTP should be disabled. # DHCP Options +The following are the private DHCP options used during the implementation of updategraph/ZTP | DHCP Option | Information | Explanation | -|:-----------:|:-------------------:|:-------------------------------------------------:| +|:-----------:|:-------------------|:-------------------------------------------------| | 224 | snmp_community | usage implemented through updategraph | | 225 | minigraph_url | usage implemented through updategraph | | 226 | acl_url | usage implemented through updategraph | From 53a6f36956a392023b2b338ae14ebf46d9f74533 Mon Sep 17 00:00:00 2001 From: simone-dell Date: Fri, 16 Nov 2018 14:48:30 -0800 Subject: [PATCH 12/13] table fix --- doc/ztp/ztp_hld.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/ztp/ztp_hld.md b/doc/ztp/ztp_hld.md index c049d02f39..9124ef79ab 100644 --- a/doc/ztp/ztp_hld.md +++ b/doc/ztp/ztp_hld.md @@ -30,6 +30,7 @@ # DHCP Options The following are the private DHCP options used during the implementation of updategraph/ZTP + | DHCP Option | Information | Explanation | |:-----------:|:-------------------|:-------------------------------------------------| | 224 | snmp_community | usage implemented through updategraph | From 9d438dbfdfdd44b21c635b35bb54d85642dffe7b Mon Sep 17 00:00:00 2001 From: simone-dell <36049136+simone-dell@users.noreply.github.com> Date: Tue, 27 Nov 2018 11:05:00 -0800 Subject: [PATCH 13/13] Update HLD for clarity --- doc/ztp/ztp_hld.md | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/doc/ztp/ztp_hld.md b/doc/ztp/ztp_hld.md index 9124ef79ab..9f5640548a 100644 --- a/doc/ztp/ztp_hld.md +++ b/doc/ztp/ztp_hld.md @@ -125,10 +125,10 @@ Will show the user whether ZTD is enabled, the date of the last execution of the show ztp-status The ZTP status will show the user the current SONiC image, if the configuration was successful, and if the post-configuration script was run, as well as the time of the last successful completion of the ZTP service - config ztp enable/disable + config ztp enable The user can re-enable ZTP after a failed state using the CLI. This puts the switch into “factory setting” and reloads with ZTP enabled, allowing for provisioning restart. - ztp cancel + config ztp disable The user can interrupt the ZTP service: - If cancelled before image download, ZTP service will exit - If cancelled after image download but before reboot, ZTP service will output sonic_installer list and exit @@ -150,23 +150,17 @@ The user can interrupt the ZTP service: - Exit ZTP - Test to see if Ansible server is reachable for further configuration ## Updategraph -- If ZTP is enabled but post_install is false, apply default configs to the switch and exit +- If ZTP is enabled and post_install is false, apply default configs to the switch and exit - If ZTP is enabled and post_install is true, continue to apply configs based on graph_url -# Phases +# Check-in Phases ## Phase 1 - Implement image download and install - Implement image and config validation ## Phase 2 - Post install script: downloaded after updategraph finishes -- Dependent on user -- Implement validation of management port -- Implement validation of neighbors -- Implement validation of config based on serial number -## Phase 3 - Command line utility +## Phase 3 - ZTP interrupt process -- ZTP test planif [ -n "$new_acl_url" ]; then - echo $new_acl_url > /tmp/dhcp_acl_url - fi +- ZTP test plan