0% found this document useful (0 votes)
48 views178 pages

01-06 ZTP Configuration

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
48 views178 pages

01-06 ZTP Configuration

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 178

CloudEngine S16700 Series Switches

Configuration Guide - Basic Configuration 6 ZTP Configuration

6 ZTP Configuration

6.1 Overview of ZTP


6.2 Understanding ZTP
6.3 Configuration Precautions for ZTP
6.4 Default ZTP Settings
6.5 Configuring DHCP-based ZTP (with a Controller)
6.6 Configuring DHCP-based ZTP (Without a Controller)
6.7 Configuring USB-based Deployment

6.1 Overview of ZTP


Definition
Zero Touch Provisioning (ZTP) enables newly delivered devices or devices with
factory configurations to automatically load deployment files (including system
software, configuration files, and patch files) when they are powered on and
started.

Purpose
After devices are installed on the live network, engineers usually need to perform
onsite configurations for the devices. Typically, this requires engineers to configure
each device locally, which is inefficient and costly, especially if there are a large
number of sparsely deployed devices.
To overcome such efficiency and cost challenges, the ZTP function can be enabled
on a device. ZTP allows the device to obtain and automatically load deployment
files from the USB flash drive or file server. This ultimately frees engineers from
having to carry out onsite configuration and deployment.

6.2 Understanding ZTP

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 126


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

6.2.1 ZTP Fundamentals


Typical Networking
In Figure 6-1, the device functions as a DHCP client to periodically send DHCP
request packets to the DHCP server in order to obtain configuration information.
The DHCP server responds with DHCP reply packets that contain information
about the IP address allocated to the device, IP address of the intermediate file
server, and intermediate file server login method. After receiving the DHCP reply
packets, the device connects to the intermediate file server to obtain the
configuration information about the deployment files, based on which the device
then automatically obtains deployment files from the specified deployment file
server and sets them as the files to be loaded for the next startup. These
deployment files are then automatically loaded by the device upon restart.

Figure 6-1 Typical network diagram of ZTP

● DHCP server: allocates a temporary management IP address, default gateway


address, DNS server address, and intermediate file server address to the
device to be deployed.
● Syslog server: uploads user logs recorded during the ZTP process to the
network management system (NMS).
● DHCP relay agent: forwards packets exchanged between the device to be
deployed and the DHCP server when they are located on different network
segments.
● Intermediate file server: stores the intermediate file required for ZTP, which
can be an INI file or a Python script. By parsing the intermediate file, the
device to be deployed obtains information about the deployment file server
address and deployment files. An intermediate file server must be an SFTP file
server.
● Deployment file server: stores the deployment files to be loaded to the
device to be deployed, including the system software, configuration file, and
patch file. The deployment file server and intermediate file server can be
combined, which must be an SFTP file server.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 127


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

● DNS server: provides mappings between domain names and IP addresses,


and resolves the file server domain name to an IP address for the device to be
deployed. Based on the resolved IP address, the device can obtain requested
files from the file server.

Deployment Modes
Devices support multiple ZTP deployment modes, which are applicable to different
scenarios, as described in Table 1. You can select a proper deployment mode as
required.

Table 6-1 ZTP modes


Deployme Description Application Task
nt Mode Scenario

DHCP- If a controller is deployed, DHCP- This mode 6.5


based ZTP based ZTP can be classified into applies to Configuring
(with a DHCP option-based ZTP and batch device DHCP-based
controller) registration query center-based deployment ZTP (with a
ZTP. when a Controller)
DHCP option-based ZTP: Option controller is
148 or Option 17 is configured deployed.
on the DHCP server on the
network. This option parameter
specifies the controller address
information. Devices obtain the
information through DHCP. The
device establishes a NETCONF
connection with the controller
based on the obtained controller
information. Then you can
perform deployment
configuration on the device
through the controller.
Registration query center-based
ZTP: A device accesses the
Huawei device registration query
center through the preconfigured
domain name and port number
of the Huawei device registration
query center, and then obtains
the controller address based on
the device ESN or MAC address.
The device establishes a
NETCONF connection with the
controller based on the obtained
controller information. Then you
can perform deployment
configuration on the device
through the controller.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 128


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Deployme Description Application Task


nt Mode Scenario

DHCP- If no controller is deployed, This mode 6.6


based ZTP DHCP-based ZTP can be classified applies to Configuring
(without a into intermediate file-based ZTP batch device DHCP-based
controller) and option-based ZTP. deployment ZTP
Intermediate file-based ZTP: when no (Without a
During deployment, the device controller is Controller)
functions as a DHCP client to deployed.
periodically send DHCP request
packets to the DHCP server in
order to obtain configuration
information. The DHCP server
responds with DHCP reply
packets that contain information
about the IP address allocated to
the device, IP address of the
intermediate file server, and
intermediate file server login
method. After receiving the DHCP
reply packets, the device connects
to the intermediate file server to
obtain the configuration
information about the
deployment files, based on which
the device then automatically
obtains deployment files from
the specified deployment file
server and sets them as the files
to be loaded for the next startup.
These deployment files are then
automatically loaded by the
device upon restart.
Option-based ZTP: During
deployment, the device functions
as a DHCP client to periodically
send DHCP request packets to
the DHCP server in order to
obtain configuration information.
The DHCP server responds with
DHCP reply packets that contain
information about the IP address
allocated to the device,
deployment file server login
method, deployment file
information. After receiving the
DHCP reply packets, the device
connects to the deployment file
server to obtain the deployment
files, and sets them as the files to
be loaded for the next startup.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 129


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Deployme Description Application Task


nt Mode Scenario

These deployment files are then


automatically loaded by the
device upon restart.

USB-based In this mode, deployment files of This mode 6.7


deploymen a device are typically saved in a applies to Configuring
t USB flash drive by trained scenarios USB-based
engineers, after which untrained where devices Deployment
personnel can perform automatic are scattered
device deployment by inserting and no DHCP
the USB flash drive into the server is
device and downloading the deployed.
deployment files from the USB This mode
flash drive. lowers the
deployment
cost.

DHCP-based ZTP is simple. You can use this deployment mode as long as a DHCP
server is deployed. However, this deployment mode may cause data leakage and
interception, which poses security risks. In deployment scenarios that require high
security, you can deploy a dedicated bootstrap server and use two-way
authentication and data encryption to ensure the data reliability for DHCP-based
ZTP. For details, see 6.2.2 SZTP Fundamentals and 6.6 Configuring DHCP-based
ZTP (Without a Controller).

Deployment Process
Device deployment processes include the deployment processes for devices with
factory configurations and with non-factory configurations.

● Figure 6-2 shows the ZTP process for a device that starts with factory
configurations.
a. After the device is powered on, it checks whether a USB flash drive is
inserted. If a USB flash drive is inserted and the usb.ini file exists in the
root directory of the USB flash drive, the device starts USB-based
deployment. If no USB flash drive is available or no usb.ini file exists in
the root directory of the USB flash drive, the device goes to next step.
b. The device starts the DHCP-based ZTP or SZTP process. It functions as a
DHCP client to send a DHCP request packet to the DHCP server. If the
device receives a packet carrying DHCP option 143, the device starts the
SZTP process. Otherwise, the device starts the DHCP-based ZTP process.
You can select a deployment mode based your site requirements.
● When a device is powered on with non-factory configurations, ZTP is not
supported by default, and the device starts using the non-factory
configuration file.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 130


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Figure 6-2 Deployment process after a device is powered on with factory


configurations

NOTE

● When deploying a device with factory configurations, you are advised not to manually
deliver the same configurations as those delivered during ZTP. If the deployment fails,
the configurations will be deleted.
● ZTP processes depend on OPS. You can run the ops stop process process-id command
to stop a ZTP process. Running this command may retain the configurations that have
been delivered during ZTP on the device.

6.2.2 SZTP Fundamentals

Context
SZTP applies to scenarios that require high security. DHCP-based ZTP is easy to
implement because you only need to deploy a DHCP server. However, it may lead
to data leakage or interception, posing security risks. To mitigate the security risks,

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 131


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

you can deploy a DHCP server and a dedicated bootstrap server and use two-way
authentication and data encryption.

Basic Networking
In Figure 6-3, the device functions as a DHCP client to periodically send DHCP
request packets to the DHCP server in order to obtain configuration information.
The DHCP server responds with DHCP reply packets that contain information
about the IP address allocated to the device, as well as the IP address or domain
name of the bootstrap server. After obtaining such information, the device
establishes an HTTPS connection with the bootstrap server through two-way
authentication based on an initial certificate. The device then obtains information
about deployment files from the bootstrap server, connects to the deployment file
server, obtains the deployment files, and sets them as the files to be loaded for
the next startup. These deployment files are then automatically loaded by the
device upon restart.

Figure 6-3 SZTP networking

● DHCP server: allocates a temporary management IP address, default gateway


address, DNS server address, and bootstrap server address or domain name to
the device to be deployed through SZTP.
● DHCP relay agent: forwards packets exchanged between the device to be
deployed and the DHCP server when they are located on different network
segments.
● Bootstrap server: is used to guide SZTP. After establishing a secure
connection with the device to be deployed through SZTP, the bootstrap server

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 132


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

sends deployment file information (such as the address of the deployment file
server and deployment file version) to the device.
● Deployment file server: stores the deployment files to be loaded to the
device to be deployed, including the system software, configuration file, and
patch file.
● DNS server: provides mappings between domain names and IP addresses,
and resolves the domain name of the bootstrap server to an IP address.
● Syslog server: uploads user logs recorded during the SZTP process to the
NMS.
NOTE

A deployment file server used for SZTP must be an HTTPS server.

Trusted Connection
During SZTP, the device establishes a trusted connection with the bootstrap server
through two-way authentication and obtains deployment file information from
the server. The device then functions as an HTTPS client to establish an HTTPS
connection with the deployment file server and download deployment files.
Certificates listed in Table 6-2 are required for establishing a secure connection
between the device and bootstrap server.

Table 6-2 Certificates on which a trusted connection depends


Certificate Type Description

Device identity certificate This certificate is an initial certificate.


It is an 802.1AR certificate generated
using the Huawei CA signature before
device delivery. By default, Huawei
devices have built-in identity
certificates before delivery. The
certificate contains information such
as the public key and device SN.

Huawei root CA certificate /

Huawei level-2 CA certificate /

Ownership voucher It is a Cryptographic Message Syntax


(CMS) file, which is issued by the
device vendor to the customer. Huawei
plans to use the carrier's level-2 CA to
issue an ownership voucher to the
customer. The voucher contains the
release time, expiration time, hardware
serial number for connecting to
Huawei devices, and root certificate of
the bootstrap server.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 133


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Certificate Type Description

Owner certificate This certificate is an X.509 certificate,


which is used to identify an owner. The
device can use this certificate to verify
the signature of conveyed information.

NOTE

The ownership voucher is valid only when the Huawei level-2 CA certificate is pre-
configured on the bootstrap server.
The bootstrap server has a built-in Huawei level-2 CA certificate, an ownership voucher, and
an owner certificate. Initial device certificates include the device identity certificate, Huawei
root CA certificate, and Huawei level-2 CA certificate.
● You can configure deployment file information (such as the deployment file
server address and deployment file name) on the bootstrap server. The
deployment file information is stored in onboarding information.
● If the device does not have a built-in trust root certificate, it establishes an
untrusted connection with the bootstrap server. The bootstrap server
encapsulates the onboarding information, ownership voucher, and owner
certificate into bootstrapping data and sends the data to the device.
● After verifying the signature of the ownership voucher, the device performs
operations shown in Figure 6-4: It uses the built-in Huawei root level-2 CA
certificate to authenticate the owner certificate to form a complete trust
chain, and then verifies the signature of the onboarding information. The
device parses the deployment file information from the onboarding
information, establishes an HTTPS connection with the deployment file server,
and downloads the deployment files.

Figure 6-4 Establishing a trust chain

In practice, you can deploy one or more bootstrap servers based on security
requirements. If multiple bootstrap servers are deployed, a redirect-to
bootstrap server address may be configured on a bootstrap server. Redirection
information is stored in Redirect Information. When an untrusted connection
is established between the device and bootstrap server, the bootstrap server
encapsulates the Redirect Information, ownership voucher, and owner
certificate into bootstrapping data and sends the data to the device to
establish a trusted connection. The device then obtains the IP address of the
redirect-to bootstrap server and the trust anchor certificate from the Redirect

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 134


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Information. After the trust anchor certificate is installed, the device


establishes a trusted connection with the redirect-to bootstrap server until the
device obtains the onboarding information, which contains deployment file
information.

Deployment Process
Figure 6-5 shows the SZTP process.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 135


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Figure 6-5 SZTP process

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 136


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

The SZTP process involves the following phases:

1. Powering on and starting the device


If a non-factory configuration file is available, the device starts with that
configuration file. Otherwise, the device automatically starts the ZTP process.
2. Obtaining DHCP information
The device sends a DHCP request packet through VLANIF 1. The DHCP server
sends a DHCP reply packet to the device. If the reply packet contains the
DHCP option 143 field, the device starts the SZTP process. If the reply packet
does not contain the DHCP option 143 field, the device starts the DHCP-based
ZTP process. After entering the SZTP process, the device obtains information
such as the device IP address, default gateway address, Syslog server address,
and bootstrap server address from the DHCP server. The device obtains the
IPv4 address of the Syslog server from the DHCP reply packet to enable the
Syslog server function. Information about important phases during SZTP is
recorded in user logs, which the Syslog server will upload to the NMS.
3. Obtaining deployment file information
The device parses the bootstrap server address from the DHCP option 143
field, establishes a secure connection with the bootstrap server, and obtains
deployment file information.
4. Restarting the device
The device automatically sets the downloaded deployment files as those to be
loaded for its next startup. The device then restarts to complete automatic
deployment.

NOTE

● When deploying a device with factory configurations, you are advised not to manually
deliver the same configurations as those delivered during ZTP. If the deployment fails,
the configurations will be deleted.
● SZTP processes depend on OPS. You can run the ops stop process process-id command
to stop a ZTP process. Running this command may retain the configurations that have
been delivered during SZTP on the device.

6.3 Configuration Precautions for ZTP


Licensing Requirements
ZTP is not under license control.

Hardware Requirements

Table 6-3 Hardware requirements

Series Models

S16700 series S16700-4/S16700-8

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 137


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Feature Requirements

Table 6-4 Feature requirements


Feature Requirements Series Models

When using a USB flash drive for deployment, S16700 S16700-4/


ensure that the read and write protection series S16700-8
functions of the USB flash drive are disabled.

The file path and name for option parameter- S16700 S16700-4/
based deployment cannot contain the series S16700-8
following special characters: # & > < " ' | · $ ;
( ) [ ] { } ~ * ? ! \n # % , \

1. To ensure data security, it is recommended S16700 S16700-4/


that the device administrator use a keystroke- series S16700-8
encrypted or fingerprint-encrypted USB flash
drive and keep the USB flash drive with the
deployment configuration file properly. After
the deployment is complete, delete the
deployment configuration file in a timely
manner.
2. No security measures are available for
devices with factory configurations. Therefore,
if a deployment task is performed by a non-
professional onsite engineer, ensure that the
engineer does not perform unauthorized
operations on the device, USB flash drive, or
deployment files.
3. If a device with a configuration file needs to
be deployed using a USB flash drive, you are
advised to use encryption and compression and
HMAC integrity check to ensure file security.
4. Do not remove the USB flash drive before
the USB-based deployment is complete.
Otherwise, data in the USB flash drive may be
damaged.
5. Do not power off the device during USB-
based deployment. Otherwise, the upgrade
fails.

The devices to be deployed must meet the S16700 S16700-4/


following requirements: series S16700-8
1. The device runs with factory configurations.
That is, Startup saved-configuration file and
Next startup saved-configuration file in the
display startup command output are empty.
2. ZTP is not disabled, that is, the set ztp
disable command is not executed.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 138


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Feature Requirements Series Models

The option fields in the downloaded S16700 S16700-4/


intermediate file and script, and the user series S16700-8
name, password, and version file name
configured in the intermediate file cannot
contain the following special characters: & > <
" ' | · $ ; ( ) [ ] { } ~ * ? ! \n # % ,

Only Python 3 scripts are supported. S16700 S16700-4/


series S16700-8

The Syslog server address is obtained through S16700 S16700-4/


the Options field configured on the DHCP series S16700-8
server, but not through the intermediate file.

1. ZTP deployment suspension: During the S16700 S16700-4/


deployment, a user logs in to the device and series S16700-8
configures an IP address for the device. The
device attempts to start the ZTP process again
after 2 hours.
2. ZTP deployment exit: During the
deployment, a user logs in to the device and
sets the configuration file for the next startup
or runs the set ztp disable command.

The Python script file must use a format S16700 S16700-4/


supported by the Windows or Unix format. series S16700-8

ZTP needs to be deployed on a private network S16700 S16700-4/


because using a non-private network to deploy series S16700-8
ZTP has security risks. For example, if a service
port is used to deploy the device, the service
plane, management plane, and control plane
need to be isolated for security purposes. If
security risks are uncontrollable, use SZTP for
deployment.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 139


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Feature Requirements Series Models

1. Device configurations are modified during S16700 S16700-4/


deployment. When logging in to the device to series S16700-8
save the configurations, you need to check
whether the configurations modified during
deployment are saved by mistake.
2. During ZTP, users cannot deliver
configurations after logging in to the device.
(1) When configurations are delivered to
interfaces during ZTP, you cannot use other
configuration modes to deliver the same
configurations to the interfaces.
(2) The CLI list is verified during ZTP.
ip address dhcp-alloc
undo portswitch (default Layer 2 interface on
CE switches)
dhcp client request option-list (CE switches
involve 7, 43, 66, 67, 143, 145, 146, 148, 150,
which are delivered during the DHCP process.)
DNS server (The DNS server configured by the
user can be distinguished from that obtained
from the DHCP server during ZTP, unless the
DNS server configured by the user is the same
as that obtained from the DHCP server.)
ip route-static 0.0.0.0 0 (fixed at 0.0.0.0 0)
gateway ifname (DHCP server configuration
and deployment port)
info-center loghost [ipv6] x.x.x.x port xxx (The
DNS server configured by the user can be
distinguished from that obtained from the
DHCP server during ZTP, unless the DNS server
configured by the user is the same as that
obtained from the DHCP server.)
port description ztp (fixed at ztp)
SSL policy (fixed at sztp_policy.)

The option 148 field configured on the DHCP S16700 S16700-4/


server must comply with the following rules: series S16700-8
agilemanage-domain and agilemanage-port
must be used in pairs, and the number of IP
addresses must be the same as the number of
ports.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 140


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Feature Requirements Series Models

1. For SZTP deployment, a device identity S16700 S16700-4/


certificate must be preconfigured before series S16700-8
delivery. The certificate is used for
authentication between the device and
bootstrap server and for TLS connection
establishment.
2. The bootstrapping data sent from the
bootstrap server may be encrypted using the
public key of the device identity certificate. The
device needs to decrypt the bootstrapping data
using the private key of the device identity
certificate.

If the source file is compressed, the HMAC S16700 S16700-4/


value in the index file is the HMAC value series S16700-8
calculated for the source file.

1. For compressed files, the *FILENME_n field in S16700 S16700-4/


the index file must be named in compliance series S16700-8
with the following rules:
a. The file name extension must be .zip.
b. The file name is the name and format of the
file to be compressed into a package, for
example, tyj_cc.zip (indicating that the name
of the file to be compressed into a package is
tyj.cc) and wxc_pat.zip (indicating that the
name of the file to be compressed into a
package is wxc.pat). When the .ini file is
parsed, the verification can be performed
based on the name and the *TYPE_n field.
2. Each package can contain only one file.

If the standby MPU is installed during ZTP S16700 S16700-4/


deployment, deployment files downloaded series S16700-8
from the active MPU cannot be copied to the
standby MPU. You are advised to power on the
standby MPU and register it before ZTP.

6.4 Default ZTP Settings


The default ZTP settings are classified into settings for a device that starts with
factory configurations and those for a device that starts with non-factory
configurations.
● When a device is powered on and starts with factory configurations, it
automatically starts the ZTP process by default.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 141


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

● When a device is powered on and starts with non-factory configurations, ZTP


is not supported by default, and the device starts using the non-factory
configuration file.

6.5 Configuring DHCP-based ZTP (with a Controller)

6.5.1 Understanding DHCP-based ZTP with a Controller

Fundamentals
If a controller is deployed, DHCP-based ZTP can be classified into DHCP option-
based ZTP and registration query center-based ZTP.

In Figure 6-6, Option 148 or Option 17 is configured on the DHCP server on the
network. This option parameter contains the controller address information.
Devices obtain the information through DHCP. The device establishes a NETCONF
connection with the controller based on the obtained controller information. Then
you can perform deployment configuration on the device through the controller.

Figure 6-6 Network diagram of DHCP option-based ZTP when a controller is


deployed

● iMaster NCE-Campus: establishes NETCONF connections with devices.


● DHCP server: allocates the temporary management IP address, default
gateway address, controller's IP address and port number, DNS server's IP
address, bootstrap server's IP address and port number, and Syslog server's IP
address to the device that performs ZTP.
● DNS server: provides mappings between domain names and IP addresses,
and resolves the domain name of the bootstrap server to an IP address.
● Bootstrap server: stores CA certificates applied by users. For security
purposes, no initial certificate is available on iMaster NCE-Campus. For this
reason, the device needs to download a CA certificate from the bootstrap
server so that two-way authentication for establishing a NETCONF connection

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 142


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

between the device and iMaster NCE-Campus can be successfully performed.


Currently, iMaster NCE-Campus integrates the bootstrap server function.
● Syslog server: uploads user logs recorded during the ZTP process to the NMS.
● DHCP relay agent: forwards packets exchanged between the device to be
deployed and the DHCP server when they are located on different network
segments.
In Figure 6-7, a device accesses the Huawei device registration query center
through the preconfigured domain name and port number of the Huawei device
registration query center, and then obtains the controller address based on the
device ESN or MAC address. The device establishes a NETCONF connection with
the controller based on the obtained controller information. Then you can perform
configurations on the device through the controller.

Figure 6-7 Network diagram of registration query center-based ZTP when a


controller is deployed

● iMaster NCE-Campus: establishes NETCONF connections with devices.


● DHCP server: allocates a temporary management IP address, default gateway
address, DNS server IP address, and Syslog server IP address to the device to
be deployed.
● Registration query center: provides address information of the controller and
bootstrap server for devices to be deployed through ZTP.
● DNS server: provides mappings between domain names and IP addresses,
and resolves the domain name of the bootstrap server to an IP address.
● Bootstrap server: stores CA certificates applied by users. For security
purposes, no initial certificate is available on iMaster NCE-Campus. For this
reason, the device needs to download a CA certificate from the bootstrap
server so that two-way authentication for establishing a NETCONF connection
between the device and iMaster NCE-Campus can be successfully performed.
Currently, iMaster NCE-Campus integrates the bootstrap server function.
● Syslog server: uploads user logs recorded during the ZTP process to the NMS.
● DHCP relay agent: forwards packets exchanged between the device to be
deployed and the DHCP server when they are located on different network
segments.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 143


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

ZTP Process
Figure 6-8 shows the flowchart of DHCP option-based ZTP when a controller is
deployed.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 144


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Figure 6-8 Flowchart of DHCP option-based ZTP when a controller is deployed

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 145


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

The ZTP process involves the following phases:


1. Powering on and starting the device
If a non-factory configuration file is available, the device starts with that
configuration file. Otherwise, the device automatically starts the ZTP process.
2. Obtaining information through DHCP
The device sends a DHCP request packet through VLANIF 1. The DHCP server
sends a DHCP reply packet to the device. If the reply packet contains the
DHCP Option 148 or Option 17, the device starts the DHCP Option-based ZTP
process. After entering the DHCP option-based ZTP process with a controller,
the device obtains information such as the device IP address, default gateway
address, controller's IP address and port number, bootstrap server's IP address
and port number, and Syslog server's IP address from the DHCP server. The
device obtains the IP address of the Syslog server from the DHCP reply packet
to enable the Syslog server function. Information about important phases
during ZTP is recorded in user logs, which the Syslog server will upload to the
NMS.
3. (Optional) Downloading a CA certificate from the bootstrap server
This phase is mandatory when no initial certificate is available on the
controller and you want to use controller-based ZTP.
After receiving a DHCP reply packet carrying the DHCP option 43 field
(suboption 5) or the DHCP option 17 field (suboption 1) that carries
bootstrap server information, the device downloads a CA certificate from the
bootstrap server as follows:
a. The device establishes an HTTPS connection with the bootstrap server
based on the obtained IP address and port number of the bootstrap
server.
b. The device sends a request packet to the bootstrap server to download a
CA certificate. The request packet carries the device ESN or the IP address
of the bootstrap server. If the option parameter specifies the certificate
verification mode as ESN, the request packet carries the device ESN. If
the option parameter specifies the certificate verification mode as
DOMAIN_IP, the request packet carries the IP address of the bootstrap
server.
c. The bootstrap server searches for the CA certificate based on the ESN or
IP address in the request packet and sends a response packet carrying the
CA certificate to the device. The response packet also carries the device
ESN or the IP address of the bootstrap server.
d. After receiving the response packet from the bootstrap server, the device
terminates the HTTPS connection with the bootstrap server, parses the
response packet, and verifies the validity of the certificate. If the CA
certificate sent by the bootstrap server has been signed, the device
verifies the signature of the certificate. After the signature verification is
successful, the device verifies the certificate. If the CA certificate sent by
the bootstrap server has not been signed, the device determines whether
to trust the certificate based on the option parameter setting. If the
option parameter specifies that the certificate can be trusted, the device
verifies the certificate. Otherwise, the device verifies the signature first. In
this case, signature verification will fail.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 146


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

The device verifies the certificate based on the certificate verification


mode specified by an option parameter. If the certificate verification
mode is ESN, the device verifies the certificate based on the device ESN.
If the certificate authentication mode is DOMAIN_IP, the device verifies
the certificate based on the IP address of the bootstrap server. If the
verification fails, the device fails to obtain a CA certificate.
e. The device imports the obtained CA certificate to the default domain.
4. Establishing a NETCONF connection with the controller
After receiving a DHCP reply packet that contains the DHCP option 148 field
or DHCP option 17 field, the device enables NETCONF and proactive
NETCONF registration, creates an SSH user named huawei, and configures
VLAN 1 as the management VLAN. The device establishes a NETCONF
connection with the controller based on the obtained IP address and port
number of the controller.
Figure 6-9 shows the flowchart of registration query center-based ZTP when a
controller is deployed.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 147


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Figure 6-9 Flowchart of registration query center-based ZTP when a controller is


deployed

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 148


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

The ZTP process involves the following phases:


1. Powering on and starting the device
If a non-factory configuration file is available, the device starts with that
configuration file. Otherwise, the device automatically starts the ZTP process.
2. Obtaining information through DHCP
The device sends a DHCP request packet through VLANIF 1. The DHCP server
sends a DHCP reply packet to the device. If the reply packet contains DHCP
Option 148 or Option 17, the device starts the DHCP Option-based ZTP
process. If the reply packet does not contain the option 148 or option 17 field,
the device further determines whether the conditions for DHCP-based ZTP
without a controller are met. If none of the preceding conditions is met, the
device enters the registration query center-based ZTP process with a controller
deployed. After entering the registration query center-based ZTP process with
a controller, the device uses a physical interface to obtain information such as
the device IP address, default gateway address, DNS server IP address, and
Syslog server IP address from the DHCP server. The device connects to the
DNS server based on the server's IP address to resolve the preconfigured
domain name of the registration query center. The device obtains the IP
address of the Syslog server from the DHCP reply packet to enable the Syslog
server function. Information about important phases during ZTP is recorded in
user logs, which the Syslog server will upload to the NMS.
3. Obtaining information from the registration query center
The device accesses the registration query center based on the obtained
registration query center IP address and preconfigured port number, obtains
the controller address based on the device ESN or MAC address, and obtains
the IP address and port number of the bootstrap server.
4. (Optional) Downloading a CA certificate from the bootstrap server
This phase is mandatory when no initial certificate is available on the
controller and you want to use controller-based ZTP.
After obtaining the IP address and port number of the bootstrap server from
the registration query center, the device downloads the CA certificate from the
bootstrap server as follows:
a. The device establishes an HTTPS connection with the bootstrap server
based on the obtained IP address and port number of the bootstrap
server.
b. The device sends a request packet to the bootstrap server to download a
CA certificate. The request packet carries the device ESN or the IP address
of the bootstrap server. If the option parameter specifies the certificate
verification mode as ESN, the request packet carries the device ESN. If
the option parameter specifies the certificate verification mode as
DOMAIN_IP, the request packet carries the IP address of the bootstrap
server.
c. The bootstrap server searches for the CA certificate based on the ESN or
IP address in the request packet and sends a response packet carrying the
CA certificate to the device. The response packet also carries the device
ESN or the IP address of the bootstrap server.
d. After receiving the response packet from the bootstrap server, the device
terminates the HTTPS connection with the bootstrap server, parses the
response packet, and verifies the validity of the certificate. If the CA

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 149


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

certificate sent by the bootstrap server has been signed, the device
verifies the signature of the certificate. After the signature verification is
successful, the device verifies the certificate. If the CA certificate sent by
the bootstrap server has not been signed, the device determines whether
to trust the certificate based on the option parameter setting. If the
option parameter specifies that the certificate can be trusted, the device
verifies the certificate. Otherwise, the device verifies the signature first. In
this case, signature verification will fail.
The device verifies the certificate based on the certificate verification
mode specified by an option parameter. If the certificate verification
mode is ESN, the device verifies the certificate based on the device ESN.
If the certificate authentication mode is DOMAIN_IP, the device verifies
the certificate based on the IP address of the bootstrap server. If the
verification fails, the device fails to obtain a CA certificate.
e. The device imports the obtained CA certificate to the default domain.
5. Establishing a NETCONF connection with the controller
After receiving a packet carrying the controller address from the registration
query center, the device enables NETCONF, enables proactive NETCONF
registration, and creates an SSH user (huawei) and VLAN1 for management.
The device establishes a NETCONF connection with the controller based on
the obtained IP address and port number of the controller.

6.5.2 Configuring a DHCP Server

Context
The DHCP server uses Option parameters to carry network configuration
parameters that are required for ZTP. The device can function as a DHCP server. If
a controller is deployed, you can enable the built-in DHCP function of iMaster
NCE-Campus or deploy an independent DHCP server.

The device sends a DHCP Discover message that carries DHCP Option parameters
when the DHCP discover phase starts in DHCPv4 scenarios. Table 6-5 describes
the DHCP Option parameters.

Table 6-6 describes the DHCPv4 Option parameters used for DHCP Option-based
ZTP, and Table 6-7 describes the DHCPv6 Option parameters.

Table 6-8 describes the DHCPv4 Option parameters used for registration query
center-based ZTP.

If the device to be deployed and DHCP server are on different network segments,
configure a DHCP relay agent to forward DHCP packets exchanged between them.

CAUTION

● The DHCP server does not support authentication and may be spoofed. You are
advised to use a trusted DHCP server for deployment on a secure network.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 150


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Table 6-5 DHCPv4 Option parameters in a request


Optio Function Example
n

Optio Vendor ID, which "huawei CloudEngine S16700-4"


n 60 indicates the vendor
and model of a
device.

Optio Client ID, which "00e0-fc12-3456"


n 61 indicates the MAC
address of a device.

Table 6-6 DHCPv4 Option parameters for DHCP Option-based ZTP


Option Mandatory or Not Function

Option 1 Yes Specifies the subnet


mask of the IP address.

Option 3 Yes Specifies the egress


gateway of the DHCP
client.

Option 6 No Specifies the IP address


of the DNS server.
A DNS server is required
if a domain name (for
example, www.ztp.com),
instead of an IP address,
is specified as the host
name of the bootstrap
server.

Option 7 No Specifies the IPv4


address of the Syslog
server.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 151


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Option Mandatory or Not Function

Option 43 (suboption 5) No Specifies the IP address


and port number of the
bootstrap server, from
which the device can
download a CA
certificate.
The value format is as
follows: bootstrap-
domain=https://ip-
address-or-
hostname:port;bootstrap
-trust=xxx;bootstrap-
voucher=xxx.
● bootstrap-domain:
specifies the IPv4
address or domain
name and port
number of the
bootstrap server. port
is optional, and its
default value is 443.
● bootstrap-trust:
indicates whether to
trust the downloaded
CA certificate. The
value can be true or
false. The value true
indicates that the
device trusts the CA
certificate and will
verify the signature of
the CA certificate only
when the CA
certificate sent by the
bootstrap server is
signed. The value
false indicates that
the device does not
trust the CA
certificate and will
always verify the
signature of the CA
certificate. If
bootstrap-trust is not
specified, the default
value false is used.
● bootstrap-voucher:
specifies the CA
certificate verification

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 152


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Option Mandatory or Not Function

mode. The value can


be DOMAIN_IP or
ESN. The value
DOMAIN_IP indicates
that the IP address is
used to verify the
validity of the
certificate, and the
value ESN indicates
that the device ESN is
used to verify the
validity of the
certificate. The CA
certificate can be
obtained only after
being successfully
verified.
NOTE
The ESN of the device
cannot contain spaces.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 153


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Option Mandatory or Not Function

Option 148 Yes Specifies the IP address


and port number of the
iMaster NCE-Campus
server so that devices
can register with iMaster
NCE-Campus.
The format is as follows:
agilemanage-
domain=ipv41&ipv42;agil
emanage-
port=port1&port2;sitecod
e=sitecode-value
● agilemanage-domain:
IPv4 address of the
iMaster NCE-Campus
server. You can
configure one or more
IPv4 addresses. Use
ampersands (&) to
separate multiple IPv4
addresses.
● agilemanage-port:
port number of the
iMaster NCE-Campus
server. You can
configure one or more
port numbers. Use
ampersands (&) to
separate multiple port
numbers.
● (Optional) sitecode:
site authentication
code generated by the
iMaster NCE-Campus
server. When a device
registers with iMaster
NCE-Campus, the
controller uses the
site authentication
code for verification,
implementing ESN-
free verification.
NOTE
● agilemanage-domain
and agilemanage-port
must be used together
and have the same
number of values.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 154


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Table 6-7 DHCPv6 Option parameters for DHCP Option-based ZTP


Option Mandatory or Not Function

Option 5 Yes Specifies the subnet


mask of the IPv6
address.

Option 23 No Specifies the IPv6


address of the DNS
server.
A DNS server is required
if a domain name (for
example, www.ztp.com),
instead of an IP address,
is specified as the host
name of the bootstrap
server.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 155


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Option Mandatory or Not Function

Option 17 (suboption 1) Yes Specifies the IPv6


address and port number
of iMaster NCE-Campus
and IPv6 address of the
bootstrap server so that
devices can register with
iMaster NCE-Campus
and download CA
certificates from the
bootstrap server.
The value format is
agilemanage-
domain=ipv61&ipv62;agil
emanage-
port=port1&port2;bootstr
ap-domain=https://ip-
address-or-
hostname:port;bootstrap
-trust=xxx;bootstrap-
voucher=xxx.
● agilemanage-
domain: IPv6 address
of the iMaster NCE-
Campus server. You
can configure one or
more IPv6 addresses.
Use ampersands (&)
to separate multiple
IPv6 addresses.
● agilemanage-port:
port number of the
iMaster NCE-Campus
server. You can
configure one or more
port numbers. Use
ampersands (&) to
separate multiple port
numbers.
● bootstrap-domain:
specifies the IPv6
address or domain
name and port
number of the
bootstrap server. port
is optional, and its
default value is 443. If
an IP address is used,
the format is [ip-
address]:port, for

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 156


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Option Mandatory or Not Function

example, https://
[2001:db8:1::2]:200.
● bootstrap-trust:
indicates whether to
trust the downloaded
CA certificate. The
value can be true or
false. The value true
indicates that the
device trusts the CA
certificate and will
verify the signature of
the CA certificate only
when the CA
certificate sent by the
bootstrap server is
signed. The value
false indicates that
the device does not
trust the CA
certificate and will
always verify the
signature of the CA
certificate. If
bootstrap-trust is not
specified, the default
value false is used.
● bootstrap-voucher:
specifies the CA
certificate verification
mode. The value can
be DOMAIN_IP or
ESN. The value
DOMAIN_IP indicates
that the IP address is
used to verify the
validity of the
certificate, and the
value ESN indicates
that the device ESN is
used to verify the
validity of the
certificate. The CA
certificate can be
obtained only after
being successfully
verified.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 157


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Option Mandatory or Not Function


NOTE
agilemanage-domain
and agilemanage-port
must be used together
and have the same
number of values.

Option 17 (suboption 2) No Specifies the IPv6


address of the Syslog
server.

Table 6-8 DHCPv4 Option parameters for registration query center-based ZTP
Option Mandatory or Not Function

Option 1 Yes Specifies the subnet


mask of the IP address.

Option 3 Yes Specifies the egress


gateway of the DHCP
client.

Option 6 Yes Specifies the IP address


of the DNS server.
This parameter is used to
resolve the preconfigured
domain name of the
registration query center.

Option 7 No Specifies the IPv4


address of the Syslog
server.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 158


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Option Mandatory or Not Function

Option 43 (suboption 5) No Specifies the IP address


and port number of the
bootstrap server, from
which the device can
download a CA
certificate.
The value format is as
follows: bootstrap-
domain=https://ip-
address-or-
hostname:port;bootstrap
-trust=xxx;bootstrap-
voucher=xxx.
● bootstrap-domain:
specifies the IPv4
address or domain
name and port
number of the
bootstrap server. port
is optional, and its
default value is 443.
● bootstrap-trust:
indicates whether to
trust the downloaded
CA certificate. The
value can be true or
false. The value true
indicates that the
device trusts the CA
certificate and will
verify the signature of
the CA certificate only
when the CA
certificate sent by the
bootstrap server is
signed. The value
false indicates that
the device does not
trust the CA
certificate and will
always verify the
signature of the CA
certificate. If
bootstrap-trust is not
specified, the default
value false is used.
● bootstrap-voucher:
specifies the CA
certificate verification

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 159


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Option Mandatory or Not Function

mode. The value can


be DOMAIN_IP or
ESN. The value
DOMAIN_IP indicates
that the IP address is
used to verify the
validity of the
certificate, and the
value ESN indicates
that the device ESN is
used to verify the
validity of the
certificate. The CA
certificate can be
obtained only after
being successfully
verified.
NOTE
The ESN of the device
cannot contain spaces.

Procedure
Step 1 Configure the DHCP server.
Step 2 (Optional) Configure the DHCP relay agent.
NOTE

If a Huawei device is used as the DHCP relay agent, see "DHCPv4 Configuration" or
"DHCPv6 Configuration" in CLI Configuration Guide > IP Address and Service Configuration.
If a third-party device is used as the DHCP relay agent, see the operation guide of the third-
party DHCP server and DHCP relay agent.

----End

6.5.3 Starting DHCP-based ZTP with a Controller

Prerequisites
To implement ZTP through iMaster NCE-Campus, you need to log in to iMaster
NCE-Campus and import the ESN, device type, and CA certificate of each device in
advance. If the registration query center is used for deployment, you need to
connect iMaster NCE-Campus to the registration query center. For details about
how to configure iMaster NCE-Campus, see the iMaster NCE-Campus product
documentation.

Context
A device with factory configurations has never started ZTP before. In its factory
configurations, the ZTP function is enabled by default. To start ZTP, you only need

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 160


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

to power on the device. The ZTP function can be disabled on a device. If you log in
to a device through the console port and disable the ZTP function when the device
starts with factory configurations, the ZTP process is terminated. To enable the
device to execute the ZTP process when it starts with factory configurations next
time, you need to enable the ZTP function.

Procedure
Step 1 Power on the device.
Step 2 (Optional) Enable the ZTP function on the device.
set ztp enable

By default, the ZTP function is enabled on a device.


To disable a device from running the ZTP process upon startup with factory
configurations, run the set ztp disable command on the device.
Step 3 (Optional) Restart the device with factory configurations.
reboot fast

----End

6.5.4 Verifying DHCP-based ZTP with a Controller

Context
During DHCP-based ZTP with a controller, you can perform the following
operations to check whether ZTP is complete:
● Configure a Syslog server to upload user logs recorded during the ZTP process
to the NMS.
● Check the device management status on the controller.

Procedure
Step 1 The device completes the ZTP process in about 15 minutes after it is powered on.
You can then log in to the device to check the status of the NETCONF connection
between the device and iMaster NCE-Campus.
display netconf session

----End

Follow-up Procedure
If deployment fails, analyze ZTP logs on the device to determine the cause. ZTP
logs are saved in the file named ztp_YYYYMMHHMMSS.log in the flash:/
directory.

6.5.5 Example for Configuring DHCP Option-based ZTP


Networking Requirements
In Figure 6-10, DeviceA and DeviceB are two unconfigured devices on the
network, and both are connected to DeviceC, which functions as the egress

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 161


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

gateway of DeviceA and DeviceB. There are reachable routes between DeviceC
and the DHCP server, and between DeviceC and the controller.
The customer requires that DeviceA and DeviceB automatically load the system
software and configuration files after they are powered on to reduce labor costs
and device deployment time.

Figure 6-10 Network diagram of DHCP option-based ZTP


NOTE

In this example, interface1, interface2, and interface3 represent 10GE1/0/1, 10GE1/0/2, and
10GE1/0/3, respectively.

Configuration Roadmap
The configuration roadmap is as follows:
1. Add DeviceA and DeviceB to be deployed on the controller.
2. Configure the DHCP server.
3. Configure the DHCP relay agent.
4. Power on DeviceA and DeviceB to start the ZTP process.

Procedure
Step 1 Add DeviceA and DeviceB to be deployed on the controller. For details, see the
controller product documentation.
Step 2 Configure the DHCP server.
# Configure the IP address pool that the DHCP server uses to allocate IP addresses
to DeviceA and DeviceB and set DHCP options by referring to Table 6-9. In this
example, a Huawei device is used as the DHCP server.

Table 6-9 DHCP server options

Option Description Value

Option 1 Subnet mask of an IP 255.255.255.0


address

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 162


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Option Description Value

Option 3 Egress gateway of a 10.1.1.1


DHCP client

Option 148 IP address and port agilemanage-


number of the controller. domain=10.1.3.2;agilema
nage-port=10020

<HUAWEI> system-view
[HUAWEI] sysname dhcp_server
[dhcp_server] dhcp enable
[dhcp_server] ip pool pool1
[dhcp_server-ip-pool-pool1] gateway-list 10.1.1.1
[dhcp_server-ip-pool-pool1] network 10.1.1.0 mask 255.255.255.0
[dhcp_server-ip-pool-pool1] option 148 ascii agilemanage-domain=10.1.3.2;agilemanage-port=10020
[dhcp_server-ip-pool-pool1] quit
[dhcp_server] vlan batch 10
[dhcp_server] interface 10ge 1/0/3
[dhcp_server-10GE1/0/3] portswitch
[dhcp_server-10GE1/0/3] port link-type trunk
[dhcp_server-10GE1/0/3] port trunk allow-pass vlan 10
[dhcp_server-10GE1/0/3] quit
[dhcp_server] interface vlanif 10
[dhcp_server-Vlanif10] ip address 10.1.2.2 24
[dhcp_server-Vlanif10] quit

Step 3 Configure the DHCP relay agent.


# Configure the DHCP relay function on DeviceC. Set the IP address of the
interface connecting DeviceC to DeviceA and DeviceB to 10.1.1.1 to configure
DeviceC as the default gateway of DeviceA and DeviceB.
<HUAWEI> system-view
[HUAWEI] sysname DeviceC
[DeviceC] vlan batch 10
[DeviceC] interface 10ge 1/0/1
[DeviceC-10GE1/0/1] portswitch
[DeviceC-10GE1/0/1] port link-type trunk
[DeviceC-10GE1/0/1] port trunk allow-pass vlan 10
[DeviceC-10GE1/0/1] port trunk pvid vlan 10
[DeviceC-10GE1/0/1] quit
[DeviceC] interface 10ge 1/0/2
[DeviceC-10GE1/0/2] portswitch
[DeviceC-10GE1/0/2] port link-type trunk
[DeviceC-10GE1/0/2] port trunk allow-pass vlan 10
[DeviceC-10GE1/0/2] port trunk pvid vlan 10
[DeviceC-10GE1/0/2] quit
[DeviceC] interface vlanif 10
[DeviceC-Vlanif10] ip address 10.1.1.1 24
[DeviceC-Vlanif10] quit
[DeviceC] dhcp enable
[DeviceC] interface vlanif 10
[DeviceC-Vlanif10] dhcp select relay
[DeviceC-Vlanif10] dhcp relay server-ip 10.1.2.2

Step 4 Power on DeviceA and DeviceB to start the ZTP process.


----End

Verifying the Configuration


The devices complete the ZTP process in about 15 minutes after they are powered
on. Log in to the devices and run the display startup command to check whether

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 163


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

the current system software and configuration files are the required ones. The
following shows the command output of DeviceA.
<DeviceA> display startup
MainBoard:
Configured startup system software: flash:/software_file.cc
Startup system software: flash:/software_file.cc
Next startup system software: flash:/software_file.cc
Startup saved-configuration file: flash:/conf_file.cfg
Next startup saved-configuration file: flash:/conf_file.cfg
Startup paf file: default
Next startup paf file: default
Startup patch package: NULL
Next startup patch package: NULL
Startup feature software: NULL
Next startup feature software: NULL

Configuration Scripts
● DeviceC
#
sysname DeviceC
#
vlan batch 10
#
dhcp enable
#
interface Vlanif10
ip address 10.1.1.1 255.255.255.0
dhcp select relay
dhcp relay server-ip 10.1.2.2
#
interface 10GE1/0/1
port link-type trunk
port trunk pvid vlan 10
port trunk allow-pass vlan 10
#
interface 10GE1/0/2
port link-type trunk
port trunk pvid vlan 10
port trunk allow-pass vlan 10
#
return

● DHCP server
#
sysname dhcp_server
#
dhcp enable
#
vlan batch 10
#
ip pool pool1
gateway-list 10.1.1.1
network 10.1.1.0 mask 255.255.255.0
option 148 ascii agilemanage-domain=10.1.3.2;agilemanage-port=10020
#
interface Vlanif10
ip address 10.1.2.2 255.255.255.0
#
interface 10GE1/0/3
port link-type trunk
port trunk allow-pass vlan 10
#
return

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 164


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

6.5.6 Example for Configuring Registration Query Center-


based ZTP
Networking Requirements
In Figure 6-11, DeviceA and DeviceB are two unconfigured devices on the
network, and both are connected to DeviceC, which functions as the egress
gateway of DeviceA and DeviceB. There are reachable routes between DeviceC
and the DHCP server, DNS server, registration query center, and controller.
The customer requires that DeviceA and DeviceB automatically load the system
software and configuration files after they are powered on to reduce labor costs
and device deployment time.

Figure 6-11 Network diagram of registration query center-based ZTP


NOTE

In this example, interface1, interface2, and interface3 represent 10GE1/0/1, 10GE1/0/2, and
10GE1/0/3, respectively.

Configuration Roadmap
The configuration roadmap is as follows:
1. Add DeviceA and DeviceB to the controller, ensure that the devices have been
added to a site and their ESNs have been entered, and synchronize device
information to the registration query center.
1. Configure the DHCP server.
2. Configure the DHCP relay agent.
3. Power on DeviceA and DeviceB to start the ZTP process.

Procedure
Step 1 Add DeviceA and DeviceB to the controller, ensure that the devices have been
added to a site and their ESNs have been entered, and synchronize device
information to the registration query center. For details, see the iMaster NCE-
Campus product documentation.
Step 2 Configure the DHCP server.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 165


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

# Configure the IP address pool that the DHCP server uses to allocate IP addresses
to DeviceA and DeviceB and set DHCP options by referring to Table 6-10. In this
example, a Huawei device is used as the DHCP server.

Table 6-10 DHCP server options


Option Description Value

Option 1 Subnet mask of an IP 255.255.255.0


address

Option 3 Egress gateway of a 10.1.1.1


DHCP client

Option 6 IP address of the DNS 10.1.2.1


server

<HUAWEI> system-view
[HUAWEI] sysname dhcp_server
[dhcp_server] dhcp enable
[dhcp_server] ip pool pool1
[dhcp_server-ip-pool-pool1] gateway-list 10.1.1.1
[dhcp_server-ip-pool-pool1] network 10.1.1.0 mask 255.255.255.0
[dhcp_server-ip-pool-pool1] dns-list 10.1.2.1
[dhcp_server-ip-pool-pool1] quit
[dhcp_server] vlan batch 10
[dhcp_server] interface 10ge 1/0/3
[dhcp_server-10GE1/0/3] portswitch
[dhcp_server-10GE1/0/3] port link-type trunk
[dhcp_server-10GE1/0/3] port trunk allow-pass vlan 10
[dhcp_server-10GE1/0/3] quit
[dhcp_server] interface vlanif 10
[dhcp_server-Vlanif10] ip address 10.1.2.2 24
[dhcp_server-Vlanif10] quit

Step 3 Configure the DHCP relay agent.


# Configure the DHCP relay function on DeviceC. Set the IP address of the
interface connecting DeviceC to DeviceA and DeviceB to 10.1.1.1 to configure
DeviceC as the default gateway of DeviceA and DeviceB.
<HUAWEI> system-view
[HUAWEI] sysname DeviceC
[DeviceC] vlan batch 10
[DeviceC] interface 10ge 1/0/1
[DeviceC-10GE1/0/1] portswitch
[DeviceC-10GE1/0/1] port link-type trunk
[DeviceC-10GE1/0/1] port trunk allow-pass vlan 10
[DeviceC-10GE1/0/1] port trunk pvid vlan 10
[DeviceC-10GE1/0/1] quit
[DeviceC] interface 10ge 1/0/2
[DeviceC-10GE1/0/2] portswitch
[DeviceC-10GE1/0/2] port link-type trunk
[DeviceC-10GE1/0/2] port trunk allow-pass vlan 10
[DeviceC-10GE1/0/2] port trunk pvid vlan 10
[DeviceC-10GE1/0/2] quit
[DeviceC] interface vlanif 10
[DeviceC-Vlanif10] ip address 10.1.1.1 24
[DeviceC-Vlanif10] quit
[DeviceC] dhcp enable
[DeviceC] interface vlanif 10
[DeviceC-Vlanif10] dhcp select relay
[DeviceC-Vlanif10] dhcp relay server-ip 10.1.2.2

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 166


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Step 4 Power on DeviceA and DeviceB to start the ZTP process.


----End

Verifying the Configuration


The devices complete the ZTP process in about 15 minutes after they are powered
on. Log in to the devices and run the display startup command to check whether
the current system software and configuration files are the required ones. The
following shows the command output of DeviceA.
<DeviceA> display startup
MainBoard:
Configured startup system software: flash:/software_file.cc
Startup system software: flash:/software_file.cc
Next startup system software: flash:/software_file.cc
Startup saved-configuration file: flash:/conf_file.cfg
Next startup saved-configuration file: flash:/conf_file.cfg
Startup paf file: default
Next startup paf file: default
Startup patch package: NULL
Next startup patch package: NULL
Startup feature software: NULL
Next startup feature software: NULL

Configuration Scripts
● DeviceC
#
sysname DeviceC
#
vlan batch 10
#
dhcp enable
#
interface Vlanif10
ip address 10.1.1.1 255.255.255.0
dhcp select relay
dhcp relay server-ip 10.1.2.2
#
interface 10GE1/0/1
port link-type trunk
port trunk pvid vlan 10
port trunk allow-pass vlan 10
#
interface 10GE1/0/2
port link-type trunk
port trunk pvid vlan 10
port trunk allow-pass vlan 10
#
return
● DHCP server
#
sysname dhcp_server
#
dhcp enable
#
vlan batch 10
#
ip pool pool1
gateway-list 10.1.1.1
network 10.1.1.0 mask 255.255.255.0
dns-list 10.1.2.1
#
interface Vlanif10
ip address 10.1.2.2 255.255.255.0
#

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 167


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

interface 10GE1/0/3
port link-type trunk
port trunk allow-pass vlan 10
#
return

6.6 Configuring DHCP-based ZTP (Without a


Controller)

6.6.1 Understanding DHCP-based ZTP Without a Controller


Basic Networking
DHCP-based ZTP can be further classified into intermediate file-based ZTP and
option-based ZTP.
In Figure 6-12, the device functions as a DHCP client to periodically send DHCP
request packets to the DHCP server in order to obtain configuration information.
The DHCP server responds with DHCP reply packets that contain information
about the IP address allocated to the device, IP address of the intermediate file
server, and intermediate file server login method. After receiving the DHCP reply
packets, the device connects to the intermediate file server to obtain the
configuration information about the deployment files, based on which the device
then automatically obtains deployment files from the specified deployment file
server and sets them as the files to be loaded for the next startup. These
deployment files are then automatically loaded by the device upon restart.

Figure 6-12 DHCP-based ZTP (intermediate file mode)

● DHCP server: allocates a temporary management IP address, default gateway


address, DNS server address, and intermediate file server address to the
device to be deployed.
● Syslog server: uploads user logs recorded during the ZTP process to the NMS.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 168


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

● DHCP relay agent: forwards packets exchanged between the device to be


deployed and the DHCP server when they are located on different network
segments.
● Intermediate file server: stores the intermediate file required for ZTP, which
can be an INI file or a Python script. By parsing the intermediate file, the
device to be deployed obtains information about the deployment file server
address and deployment files. An intermediate file server must be an SFTP file
server.
● Deployment file server: stores the deployment files to be loaded to the
device to be deployed, including the system software, configuration file, and
patch file. The deployment file server and intermediate file server can be
combined, which must be an SFTP file server.
● DNS server: provides mappings between domain names and IP addresses,
and resolves the file server domain name to an IP address for the device to be
deployed. Based on the resolved IP address, the device can obtain requested
files from the file server.

In Figure 6-13, the device functions as a DHCP client to periodically send DHCP
request packets to the DHCP server in order to obtain configuration information.
The DHCP server responds with DHCP reply packets that contain information
about the IP address allocated to the device, deployment file server login method,
deployment file information. After receiving the DHCP reply packets, the device
connects to the deployment file server to obtain the deployment files, and sets
them as the files to be loaded for the next startup. These deployment files are
then automatically loaded by the device upon restart.

Figure 6-13 DHCP-based ZTP (option parameter mode)

● DHCP server: allocates a temporary management IP address, default gateway


address, DNS server address, and deployment file server address to the device
to be deployed.
● Syslog server: uploads user logs recorded during the ZTP process to the NMS.
● DHCP relay agent: forwards packets exchanged between the device to be
deployed and the DHCP server when they are located on different network
segments.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 169


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

● Deployment file server: stores the deployment files to be loaded to the


device to be deployed, including the system software, configuration file, and
patch file. A deployment file server must be an SFTP server.
● DNS server: provides mappings between domain names and IP addresses,
and resolves the file server domain name to an IP address for the device to be
deployed. Based on the resolved IP address, the device can obtain requested
files from the file server.

Deployment Process
● Figure 6-14 shows the intermediate file-based ZTP process.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 170


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Figure 6-14 Intermediate file-based ZTP process

The ZTP process involves the following phases:

1. Powering on and starting the device


If a non-factory configuration file is available, the device starts with that
configuration file. Otherwise, the device automatically starts the ZTP process.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 171


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

2. Obtaining DHCP information


The device sends a DHCP request packet through VLANIF 1. After receiving
the DHCP request packet, the DHCP server sends a DHCP reply packet to the
device. Options in the packet contain the device-requested information,
including the IP address allocated to the device, default gateway address, IP
address of the intermediate file server, IP address of the Syslog server, and
intermediate file name. The device obtains the IPv4 address of the Syslog
server from the DHCP reply packet to enable the Syslog server function.
Information about important phases during ZTP is recorded in user logs,
which the Syslog server will upload to the NMS.
3. Enabling the Syslog server
The device obtains the IPv4 address of the Syslog server from the DHCP reply
packet to enable the Syslog server function. Information about important
phases during ZTP is recorded in user logs, which the Syslog server will upload
to the NMS.
4. Obtaining the intermediate file and deployment files
The device downloads the intermediate file from the intermediate file server
according to the information carried in the DHCP reply packet, and then
downloads deployment files from the deployment file server according to the
intermediate file.
If the intermediate file is an INI file, the device downloads deployment files
based on the deployment file server address and deployment file names
contained in the intermediate file. If the intermediate file is a Python script,
the device automatically runs the script to download deployment files from
the deployment file server.
5. Restarting the device
The device automatically sets the downloaded deployment files as those to be
loaded for its next startup. The device then restarts to complete automatic
deployment.
● Figure 6-15 shows the option-based ZTP process.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 172


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Figure 6-15 Option-based ZTP process

The ZTP process involves the following phases:


1. Powering on and starting the device
If a non-factory configuration file is available, the device starts with that
configuration file. Otherwise, the device automatically starts the ZTP process.
2. Obtaining DHCP information
The device sends a DHCP request packet through VLANIF 1. The DHCP server
sends a DHCP reply packet to the device. Options in the packet contain the
device-requested information, including the IP address allocated to the device,
default gateway address, IP address of the file server, IP address of the Syslog
server, and deployment file information. The device obtains the IPv4 address

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 173


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

of the Syslog server from the DHCP reply packet to enable the Syslog server
function. Information about important phases during ZTP is recorded in user
logs, which the Syslog server will upload to the NMS.
3. Enabling the Syslog server
The device obtains the IPv4 address of the Syslog server from the DHCP reply
packet to enable the Syslog server function. Information about important
phases during ZTP is recorded in user logs, which the Syslog server will upload
to the NMS.
4. Obtaining deployment files
The device downloads deployment files from the deployment file server based
on the information obtained from the DHCP reply packet.
5. Restarting the device
The device automatically sets the downloaded deployment files as those to be
loaded for its next startup. The device then restarts to complete automatic
deployment.

6.6.2 Preparing Deployment Files


Context
Before DHCP-based ZTP, you need to prepare deployment files, including the
configuration file and intermediate file.
The configuration file name is a string of 5 to 64 characters and suffixed with *.zip
or *.cfg. The configuration file is used for the next startup. The configuration file
can be manually edited or copied from other devices. You can use either of the
following methods to obtain the configuration file:
● Saving the configuration file: Run the save shareable-configuration
command on the device that provides the configuration file to save the
configuration file, and then export the configuration file using SFTP or other
methods.
● Changing the system master key: Run the set master-key command to
change the system master key, save the configuration file, and export the
configuration file using SFTP or other methods.
NOTE

To ensure security, you are advised to perform the following operations to export the
configuration file and not advised to manually edit the configuration file.
Ensure that the configuration file for deployment contains the console password or an
AAA user name that can be used to log in to the device remotely. Otherwise, the
configuration file cannot be successfully set, causing a deployment failure.

For intermediate file-based ZTP:


The name extension of the intermediate file is .ini or .python. By parsing the
intermediate file, the device to be deployed obtains information about the
deployment file server address and deployment files. The intermediate file needs
to be manually edited.
● The intermediate file in .ini format is used to save information about the
device and its deployment files. 6.6.3 Intermediate File in the INI Format
provides a file example.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 174


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

● The intermediate file in Python format (known as a Python script) is used to


download deployment files. For details about the file example, see 6.6.4
Intermediate File in the Python Format.
For option parameter-based ZTP:
The password in the intermediate file is used to decrypt the ciphertext in the
configuration file so that the device can identify the ciphertext at next startup. The
file name extension is .ini, and the file name contains 5 to 64 characters.

Procedure
Step 1 Prepare the configuration file.
● Configuration file saving mode
1. Save the configuration file on the device that provides the configuration file.
save shareable-configuration configuration-file [ password ]

If the password parameter is not specified, the configuration file uses the
default key information. If the password parameter is specified, the device
generates key information in the configuration file based on the password
entered in interactive mode.
2. Export the configuration file using SFTP.
● System master key changing mode
1. Change the system master key.
<HUAWEI> set master-key
Enter the user password: //Password of the current user, not the master key of the current system
Warning: This operation will automatically save configurations. Are you sure you want to perform it?
[Y/N]:y
Do you want to enter the master key? (If you enter Y, you need to manually enter the master key and
automatic key update stops. If you enter N, the system automatically generates a master key. If you
enter D, the system will change the current master key to the default master key.) [Y/N/D]:y
Enter a new master key: //System master key
Confirm the new master key:
Info: Keep the new master key well.
Info: Operating, please wait for a moment......
Info: Operation success.

For details, see "System Master Key Configuration" in CLI Configuration Guide
> User Access and Authentication Configuration.
2. Export the configuration file using SFTP.
Step 2 Prepare the intermediate file.
For intermediate file-based ZTP:
The intermediate file can be an .ini file or a Python script. You can select either
format to configure related fields. In addition, the configuration of some fields in
the intermediate file is related to the method of obtaining the configuration file.
For details, see Table 6-11 and Table 6-12. For more information about the fields
in an intermediate file, see 6.6.3 Intermediate File in the INI Format and 6.6.4
Intermediate File in the Python Format.
For option parameter-based ZTP:
1. Create a .txt file and change the file name to *.ini, for example, masterkey.ini.
[BEGIN]
EXPORTCFG=
SET_MASTER=

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 175


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

CLEAR_MASTER=
[END]

2. Set fields in the intermediate file. For details about the fields, see Table 6-11.

Table 6-11 Fields in an intermediate file in .ini format


Field Mandatory or Not Description Value Range

[BEGIN] Yes Start field of -


the
intermediate
file.

EXPORTCF ● This field is Password used ● If the password


G mandatory for saving the parameter is not
when the configuration specified when the save
configuration file. shareable-
file saving configuration
mode is used. command is executed to
● The field is save the configuration
optional when file, leave the
the system EXPORTCFG field
master key empty.
changing mode ● If the password
is used. parameter is specified
when the save
shareable-
configuration
command is executed to
save the configuration
file, set the EXPORTCFG
field to a value that is
the same as that of
password.

SET_MAST ● This field is System master The value must be the


ER optional when key. same as the system master
the key of the device that
configuration provides the configuration
file saving file.
mode is used.
● The field is
mandatory
when the
system master
key changing
mode is used.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 176


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Field Mandatory or Not Description Value Range

CLEAR_MA ● This field is Whether to ● The value 1 indicates


STER optional when clear the that the device restores
the system master the random master key
configuration key. after the device
file saving deployment is complete.
mode is used. ● The value 0 indicates
● The field is that the device still uses
mandatory the value of
when the SET_MASTER as the
system master master key after the
key changing device deployment is
mode is used. complete.

[END] Yes End field of the -


intermediate
file.

Table 6-12 Fields in an intermediate file in Python format


Field Mandatory or Not Description Value Range

master_ex ● This field is Password used ● If the password


portcfg mandatory for saving the parameter is not
when the configuration specified when the save
configuration file. shareable-
file saving configuration
mode is used. command is executed to
● The field is save the configuration
optional when file, set the
the system master_exportcfg field
master key to None.
changing mode ● If the password
is used. parameter is specified
when the save
shareable-
configuration
command is executed to
save the configuration
file, set the
master_exportcfg field
to a value that is the
same as that of
password.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 177


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Field Mandatory or Not Description Value Range

is_set_mas ● This field is System master The value must be the


ter optional when key. same as the system master
the key of the device that
configuration provides the configuration
file saving file.
mode is used.
● The field is
mandatory
when the
system master
key changing
mode is used.

is_clear_m ● This field is Whether to ● The value 1 indicates


aster optional when clear the that the device restores
the system master the random master key
configuration key. after the device
file saving deployment is complete.
mode is used. ● The value 0 indicates
● The field is that the device still uses
mandatory the value of
when the SET_MASTER as the
system master master key after the
key changing device deployment is
mode is used. complete.

----End

6.6.3 Intermediate File in the INI Format


The intermediate file in .ini format is used to save information about the device
and its deployment files. The file name must be ***.ini, and the following is an
example of such a file. For details about the fields included in this file, see Table
6-13.
#sha256="676a306a0c22d46ed975633de9d05af4b1ebb94879ed1dd1d1e34de2a72c4e7e"
;BEGIN ZTP CONFIG
[GLOBAL CONFIG]
*FILESERVER=sftp://sftp_user:Hyx_Hy1234@10.1.3.2
*TIME_SN=20200526120159
*DEVICE_TYPE_NUM=1
SET_MASTER=Root@123456789123456
CLEAR_MASTER=1
EXPORTCFG=

[DEVICE_TYPE_1 DESCRIPTION]
DEVICE_TYPE=S16700
ESN=
MAC=
VRPVER=
SYSLOG_INFO=UDP
SPACE_CLEAR=1
DIRECTORY=folder/
ACTIVE_DELAYTIME=60
ACTIVE_INTIME=

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 178


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

*FILETYPENUM=5
*FILENAME_1=software_file1.cc
*TYPE_1=SOFTWARE
*EFFECTIVE_MODE_1=0
ISBATCHPROCESS_1=0
SHA256_1=a7638ea0a69933ac20df66ea9bf6ea301de8155684d81fbcdf00f6ca07261d7c
*FILENAME_2=cfg_file1.cfg
*TYPE_2=CFG
*EFFECTIVE_MODE_2=0
ISBATCHPROCESS_2=0
SHA256_2=a7638ea0a69933ac20df66ea9bf6ea301de8155684d81fbcdf00f6ca07261d7c
*FILENAME_3=pat_file1.pat
*TYPE_3=PAT
*EFFECTIVE_MODE_3=1
ISBATCHPROCESS_3=0
SHA256_3=a7638ea0a69933ac20df66ea9bf6ea301de8155684d81fbcdf00f6ca07261d7c
*FILENAME_4=lic_file1.xml
*TYPE_4=LIC
*EFFECTIVE_MODE_4=1
ISBATCHPROCESS_4=0
SHA256_4=a7638ea0a69933ac20df66ea9bf6ea301de8155684d81fbcdf00f6ca07261d7c
*FILENAME_5=user_file1.txt
*TYPE_5=USER
*EFFECTIVE_MODE_5=2
ISBATCHPROCESS_5=0
SHA256_5=a7638ea0a69933ac20df66ea9bf6ea301de8155684d81fbcdf00f6ca07261d7c

;END ZTP CONFIG

Table 6-13 Fields in an INI file


Field Mandatory or Not Description

sha256 No SHA256 verification code


of the script, which is
used to check the
integrity of the
downloaded script.
NOTE
Before an SHA256
verification code is
generated, do not add the
#sha256= field to the
script. Instead, #sha256=
should be added to the
beginning of the script
after the SHA256
verification code is
generated.
A script without an
SHA256 verification code
can still be executed.

;BEGIN ZTP CONFIG Yes Start flag of the file. This


field cannot be modified.

[GLOBAL CONFIG] Yes Start flag of the global


configuration. This field
cannot be modified.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 179


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Field Mandatory or Not Description

FILESERVER Yes Address of the


deployment file server.
Files can be obtained
only in SFTP mode.
In the IPv4 scenario, the
value format is as
follows:
● The address is in
sftp://
username:password@
hostname:port/path
format.
In this format, port is
optional and path
specifies the directory
where deployment files
are stored on the file
server.
In the IPv6 scenario, the
value format is as
follows:
sftp://
username:password@hos
tname:port/path
The value of hostname
can be a domain name
or an IP address.
● If the value is a
domain name, the
format is sftp://
username:password@
hostname:port/path.
● If the value is an IP
address, the format is
sftp://
username:password
@[address]:port/path.
In this format, port is
optional and path
specifies the directory
where deployment files
are stored on the file
server.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 180


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Field Mandatory or Not Description

TIME_SN Yes Uniquely identifies a


deployment in order to
prevent repeated
deployment. The value
format is
yyyymmddhhmmss.
For example, this field
can be set to
20200526120159,
indicating 12:01:59 on
2020-05-26.

DEVICE_TYPE_NUM Yes Number of device types.


The value 1 indicates
that only one type of
device can be deployed.

SET_MASTER No Master key of a


configuration file for
deployment. The value is
a string of 20 to 32
characters. It must
contain uppercase
letters, lowercase letters,
digits, and special
characters.
NOTE
● This field takes effect
only when the
configuration file for
deployment exists.
● The configuration file is
exported from a device,
which has a master key
configured. This master
key is used as the value
of this field.
● Because this field is
configured, the
intermediate file
contains the key in
plaintext. Therefore,
you need to ensure the
security of the
intermediate file.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 181


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Field Mandatory or Not Description

CLEAR_MASTER No Whether to clear the


master key configured in
the intermediate file for
deployment. This field
takes effect only when
the SET_MASTER field
exists.
● 1: After ZTP is
complete, the device
clears the master key
configured in the .ini
file, and restores the
master key to the
random master key.
● 0: After ZTP
deployment, the
device continues to
use the master key
configured in the .ini
file. This value is used
by default.
If the CLEAR_MASTER
field is not set or is not
set to 1, the value 0 is
used.

EXPORTCFG No Value of password in the


save shareable-
configuration
configuration-file
password command. For
details, see 6.6.2
Preparing Deployment
Files.
NOTE
If both SET_MASTER and
EXPORTCFG exist in
the .ini file, EXPORTCFG
takes effect.
This field takes effect only
for the configuration file
for deployment.

[DEVICE_TYPE_n Yes Start tag of the device


DESCRIPTION] description. n indicates
the device number. The
value is an integer
starting from 1.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 182


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Field Mandatory or Not Description

DEVICE_TYPE When Device type.


DEVICE_TYPE_NUM is The value of
set to 1, DEVICE_TYPE, DEVICE_TYPE can be
ESN, and MAC can all be queried using the
set to DEFAULT or left display version
empty. command. In the
When command output,
DEVICE_TYPE_NUM is S16700 in "Version xxx
greater than 1, (S16700 xxx)" is the
DEVICE_TYPE, ESN, and value of DEVICE_TYPE.
MAC must be specified If this field is left empty
and only one of them or set to DEFAULT, the
can be specified. device type is not
NOTE checked. The default
● To upgrade devices in value is DEFAULT.
batches, set
ESN DEVICE_TYPE. ESN of the device, which
● To upgrade a single can be queried using the
device, you can set the display device esn
ESN or MAC address of command.
the device.
If this field is left empty
or set to DEFAULT, the
device does not check
the value. If this field is
set to another value, the
device checks whether
that value is the same as
its ESN. The default
value is DEFAULT.

MAC MAC address of a device,


in the XXXX-XXXX-XXXX
format, in which X is a
hexadecimal number.
You can run the display
bridge mac-address
command to query the
MAC address.
If this field is set to
DEFAULT, the MAC
address does not need to
be matched. If this field
is set to another value,
the MAC address needs
to be matched. The
entered value must be in
lowercase. The default
value is DEFAULT.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 183


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Field Mandatory or Not Description

VRPVER No System software version


number.
If the current system
software version of the
device is the same as the
value specified here, the
device does not
download the system
software from the
deployment file server.
If the current system
software package is that
required for deployment,
you are advised to set
this field.

SYSLOG_INFO No Transport protocol used


by the Syslog server.
● TCP: Logs are
transmitted using TCP.
● UDP: Logs are
transmitted using
UDP.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 184


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Field Mandatory or Not Description

SPACE_CLEAR No Whether to
automatically clean up
the system storage space
in the case of space
insufficiency. The value is
of the enumerated type.
● 0: The system storage
space is not cleaned
up.
● 1: Only system
software among
deployment files is
deleted.
● 2: In-depth cleanup is
performed. System
software among
deployment files is
deleted first. If the
available space is still
insufficient, all
unnecessary files are
deleted from the flash
directory.
If this field is left empty
or set to DEFAULT, the
space is not cleaned up.
The default value is
DEFAULT.
NOTE
In-depth cleanup involves
some inherent risks. As
such, you are advised to
back up required files
locally before performing
in-depth cleanup.

DIRECTORY No Relative directory where


deployment files are
stored on the file server.
If this field is left empty
or set to DEFAULT,
deployment files are
stored in the root
directory. The default
value is DEFAULT.
NOTE
The relative directory must
start with a folder name
and cannot start with a
slash (/).

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 185


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Field Mandatory or Not Description

ACTIVE_DELAYTIME No Delay for deployment to


NOTE be performed. The value
If both is an integer that ranges
ACTIVE_DELAYTIME and from 0 to 86400, in the
ACTIVE_INTIME are set, unit of seconds. If the
ACTIVE_DELAYTIME is
value is greater than
preferentially used.
86400, the value 86400
is used.

ACTIVE_INTIME Scheduled time for


deployment to be
performed within 24
hours. The value format
is HH:MM, where HH
indicates the 24-hour
format, and MM
indicates the 60-minute
format. For example, the
value 20:10 indicates
that the deployment will
be performed at 20:10.
NOTE
If the configured time is
earlier than the system
time of the device, the
actual deployment time is
the configured time plus
24 hours minus the current
system time. For example,
if the configured time is
10:00 and the device
system time is 11:00, the
deployment will be
performed at 23:00.

FILETYPENUM Yes Number of deployment


files to be loaded.
NOTE
The total number of
deployment files must not
exceed 9.
The value of this field must
be the same as the actual
number of deployment
files, and the value is the
same as n in FILENAME_n.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 186


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Field Mandatory or Not Description

FILENAME_n Yes Name of a deployment


file, which can be the
name of a system
software file,
configuration file, license
file, patch file,
customized file, or
feature package file.
NOTE
If the length of a
deployment file name
exceeds the limit, it will fail
to be downloaded. The
length limits for different
deployment files are as
follows:
● System software: 4 to
127 characters
● Configuration file: 5 to
64 characters
● License file: 5 to 127
characters
● Patch file: 5 to 63
characters
● Module file: 5 to 63
characters
● Customized file: 3 to 64
characters
● Feature package file: 4
to 127 characters

TYPE_n Yes Type of a deployment


file. The value is of the
enumerated type.
● SOFTWARE: system
software
● CFG: configuration file
● LIC: license file
● PAT: patch file
● MOD: module file
● USER: customized file
● FEATURE-PLUGIN:
feature package file

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 187


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Field Mandatory or Not Description

EFFECTIVE_MODE_n Yes Activation mode. The


value is of the
enumerated type.
● 0: effective upon
restart, which applies
to the system
software,
configuration file,
patch file, module file,
and feature package
file.
● 1: effective
immediately, which
applies to the license
file, patch file, module
file, and feature
package file.
● 2: Activation is not
required, which
applies to the
customized file.
The default activation
mode of the system
software and
configuration file is 0.
The default activation
mode of the patch file,
module file, license file,
and feature package file
is 1.
The default activation
mode of the customized
file is 2.
If EFFECTIVE_MODE_ n is
not an enumerated value
supported by each type
of file and not empty,
the default activation
mode of each type of file
is used.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 188


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Field Mandatory or Not Description

ISBATCHPROCESS_n No Whether to perform


batch processing for the
license list file. The value
is of the enumerated
type.
● 0: no
● 1: yes
If this field is left empty
or set to DEFAULT or a
value not 1, batch
processing is not
performed. The default
value is DEFAULT.
NOTE
Devices can use the license
list file, which contains
mappings between licenses
and device ESNs, to
automatically load license
files. A device first
downloads the license list
file and then downloads
the corresponding license
file based on the mappings
to load it. The license list
file is in XML format and
its name must be
ztp_license_list. An
example of such a file is as
follows:
<?xml version="1.0"
encoding="utf-8"
standalone="yes"?>
<Index formatVersion="1.0">
<Lic name="LIC_file1.xml"
sha256="d27305447dbb1e76e
a9c6f27e19be2986503b91d82
40612f9ebde708e7d1019e">

<LSN>LIC202005183TCG5M</
LSN>
<Esn>102050157695</
Esn>
</Lic>
<Lic name="LIC_file2.dat"
sha256="6a2690e7a08e3df844
ba86e1f48dc3c504af3b760dd0
e38134771e1024fe1a5f">

<LSN>LIC202005183TCI50</
LSN>

<Esn>2102311LDL0000000805
</Esn>
</Lic>
</Index>

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 189


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Field Mandatory or Not Description

SHA256_n No Verification code


corresponding to the
SHA256 encryption
algorithm, which is used
to verify the integrity of
a deployment file.
If this field is left empty,
the deployment file
integrity is not verified.

;END ZTP CONFIG Yes End flag of the file. This


field cannot be modified.

6.6.4 Intermediate File in the Python Format


The intermediate file in Python format (known as a Python script) is used to
download deployment files. The file name must be ***.py, and the following is a
file example. For details about the content to be modified in the script, see Table
6-14.

NOTE

The Python script can invoke the script defined using open programmability system (OPS)
APIs. The invoked script defines automatic service deployment upon device startup. To
configure more service functions for ZTP, edit the Python script by referring to the following
file example and "Writing an OPS API-based Script" in CLI Configuration Guide > System
Management Configuration.
#sha256="cb203b72b6070f535eaff14c7c7d984cf28c58052fadf1b484f80258b07fc8c9"
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright (C) Huawei Technologies Co., Ltd. 2020-2030. All rights reserved.
# ----------------------------------------------------------------------------------------------------------------------
# History:
# Date Author Modification
# 202005
"""
Zero Touch Provisioning (ZTP) enables devices to automatically load version files including system software,
patch files, configuration files when the device starts up, the devices to be configured must be new devices
or have no configuration files.

This is a sample of a Zero Touch Provisioning user script. You can customize it to meet the requirements of
your network environment.
"""
import http.client
import string
import re
import os
import sys
import xml.etree.ElementTree as etree
import stat
import logging
import traceback
import glob
import ops
import ipaddress

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 190


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

from hashlib import sha256


from urllib.request import urlretrieve
from urllib.parse import urlparse, urlunparse
from urllib.error import URLError, HTTPError, ContentTooShortError
from time import sleep, time, mktime, strptime

#
======================================================================================
================================
# Script configuration information start

# error code
OK = 0
ERR = 1

# Maximum number of device startup retries when there is no query result.


GET_STARTUP_INTERVAL = 15 # The unit is second.
MAX_TIMES_GET_STARTUP = 120 # Maximum number of retries.

# Maximum number of file downloading retries.


MAX_TIMES_RETRY_DOWNLOAD = 3
MAX_TIMES_RETRY = 5
DELAY_INTERVAL = 10

# Define the file length.


FELMNAMME_127 = 127
FELMNAMME_64 = 64
FELMNAMME_4 = 4
FELMNAMME_5 = 5

# Mode for activating the device deployment file


EFFECTIVE_MODE_REBOOT = '0'
EFFECTIVE_MODE_NO_REBOOT = '1'
EFFECTIVE_MODE_NO_NEED = '2'

FILE_TYPE_SOFTWARE = 'software'
FILE_TYPE_CFG = 'cfg'
FILE_TYPE_PAT = 'pat'
FILE_TYPE_MOD = 'mod'
FILE_TYPE_LIC = 'lic'
FILE_TYPE_USER = 'user'
FILE_TYPE_FEATURE_PLUGIN = 'feature-plugin'

# Log level.
LOG_INFO_TYPE = 'INFO'
LOG_WARN_TYPE = 'WARNING'
LOG_ERROR_TYPE = 'ERROR'

# Configure the default mode for activating the deployment file.


FILE_DEFAULT_EFFECTIVE_MODE = {
FILE_TYPE_SOFTWARE: EFFECTIVE_MODE_REBOOT, # cc package
FILE_TYPE_CFG: EFFECTIVE_MODE_REBOOT, # configuration file
FILE_TYPE_PAT: EFFECTIVE_MODE_NO_REBOOT, # patch
FILE_TYPE_MOD: EFFECTIVE_MODE_NO_REBOOT, # mod plug-in
FILE_TYPE_LIC: EFFECTIVE_MODE_NO_REBOOT, # license
FILE_TYPE_USER: EFFECTIVE_MODE_NO_NEED, # User-defined file
FILE_TYPE_FEATURE_PLUGIN: EFFECTIVE_MODE_NO_REBOOT # Feature package
}

# File name extension of the deployment file, which is used for file name verification
FILE_EXTENSION = {
FILE_TYPE_SOFTWARE: ('.cc', ),
FILE_TYPE_CFG: ('.cfg', '.zip', '.dat'),
FILE_TYPE_PAT: ('.pat', ),
FILE_TYPE_MOD: ('.mod', ),
FILE_TYPE_LIC: ('.xml', '.dat', '.zip'),
FILE_TYPE_FEATURE_PLUGIN : ('.ccx', ),
FILE_TYPE_USER: (None, )

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 191


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

FLASH_HOME_PATH = '{}'.format('/opt/vrpv8/home')
# Record the name of the startup information file.
STARTUP_INFO_FILE_NAME = 'ztp_startupInfo.txt'
# License list file used for batch license deployment.
LICENSE_LIST_FILE_NAME = 'ztp_license_list.xml'

SET_MASTER_FILE_NAME = 'ztp_master.txt'
# One hour
ONEHOUR = 3600
#One minute
ONEMINUTE = 60

# ZTP status
ZTP_STATUS_RUNNING = 'false'
ZTP_STATUS_END = 'true'

# Space clearance strategy


ZTP_SPACE_CLEAR_NO_NEED = '0' # Not cleared
ZTP_SPACE_CLEAR_NORMAL = '1' # Common clearance (Only the software package is deleted.)
ZTP_SPACE_CLEAR_DEEP = '2' # In-depth clearance

# List of downloaded files


ZTP_DOWNLOAD_FILE_LIST = []

# Script configuration information end


#
======================================================================================
================================

#
======================================================================================
================================
# User configuration information start

# Remote file paths:


# (1) The path may include the directory name and file name.
# (2) If no file name is specified, this procedure can be skipped.
# File information of the system software on the file server. The file name extension is '.cc'.
REMOTE_IMAGE = {
'product-name': {
'S16700' : {
'path': '/image/software_file_name.cc',
'sha256': '',
},
},
'esn': {},
'mac': {}
}
# File information of the configuration file on the file server. The file name extension is '.cfg', '.zip', or '.dat.'
REMOTE_CONFIG = {
'product-name': {},
'esn': {
'BARCODETEST20200620' : {
'path': '/config/conf_S16700.cfg',
'sha256': '',
},
},
'mac': {}
}
# File information of the patch file on the file server. The file name extension is '.pat.'
REMOTE_PATCH = {
'product-name': {},
'esn': {},
'mac': {
'xxxx-xxxx-xxxx' : {
'path': '/patch/S16700.pat',

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 192


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

'effective_mode': EFFECTIVE_MODE_NO_REBOOT,
'sha256': '',
},
}
}
# File information of the patch file on the file server. The file name extension is '.mod.'
REMOTE_MOD = {
'product-name': {},
'esn': {},
'mac': {
'xxxx-xxxx-xxxx' : {
'path': '/patch/S16700.MOD',
'effective_mode': EFFECTIVE_MODE_NO_REBOOT,
'sha256': '',
},
}
}
# File information of the patch file on the file server. The file name extension is '.ccx.'
REMOTE_FEATURE_PLUGIN = {
'product-name': {
'S16700' : {
'path': 'S16700_url.ccx',
'effective_mode': EFFECTIVE_MODE_REBOOT,
'sha256': '',
},
},
'esn': {},
'mac': {},
}

# File information of the license list file. The file name extension is '.xml.'
REMOTE_LICLIST = {
'path': '/license/{}'.format(LICENSE_LIST_FILE_NAME),
'sha256': 'a7638ea0a69933ac20df66ea9bf6ea301de8155684d81fbcdf00f6ca07261d7c',
}
# File information of the user file on the file server.
REMOTE_USER = {
'product-name': {},
'esn': {
'BARCODETEST20200620' : [
{
'path': '',
'sha256': '',
},
],
'BARCODETEST20200000' : [
{
'path': '/user/ztp_user.txt',
'sha256': '',
},
{
'path': '/user/ztp_user1.txt',
'sha256': '',
},
],
},
'mac': {}
}

# File server that stores the necessary system software, configuration and patch files.
# (1) Specify the file server that supports the following format.
# sftp://[username[:password]@]hostname[:port]
# (2) Do not add a trailing slash at the end of the file server path.
FILE_SERVER = 'sftp://sftp_user:sftp_pwd@xx.xx.xx.xx'

# TIME_SN is a string consisting of the year, month, day, hour, minute, and second.
TIME_SN = '20200526120159'
# device info
SYSLOG_INFO = 'UDP'

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 193


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

SPACE_CLEAR = ZTP_SPACE_CLEAR_NO_NEED
ACTIVE_DELAYTIME = '60'
#ACTIVE_INTIME is a string consisting of hour and minute
ACTIVE_INTIME = None
#VRPVER indicates the software version
VRPVER = None
#DHCP_TYPE means using dhcpv4 or v6 to download file
DHCP_TYPE = 'DHCPv4'
# User configuration information end
#
======================================================================================
================================

# 25 Author created file.


# ----------------------------------------------------------------------------------------------------------------------

# OPS objects
slog = ops.ops()
# Log file name
LOG_FILE = ''
# python file name
PYTHON_FILE = os.path.basename(__file__)

SYSTEM_FILE_INIT =0
SYSTEM_FILE_SETTING_END = 1
system_file_state = SYSTEM_FILE_INIT

SYSTEM_STARUPINFO_INIT = 0
SYSTEM_STARUPINFO_END = 1
system_startupInfo_state = SYSTEM_STARUPINFO_INIT

system_reboot_needed = True

SFTP_DEFAULT_PORT = 22
HTTP_DEFAULT_PORT = 80

SET_SOFTWARE = 'SET_SOFTWARE'
SET_CFG = 'SET_CFG'
SET_PATCH = 'SET_PATCH'
SET_MOD_PATCH = 'SET_MOD_PATCH'
SET_FEATURE_PLUGIN = 'SET_FEATURE_PLUGIN'

TIMES_STARTUP_RETRY = 60
DELAY_INTERVAL_SET_INFO = 2

CLI_TYPE_YANG = 'YANG'

is_set_master = None
is_clear_master = False
master_exportcfg = None
flash_home_path_master = None
flash_home_path_slave = None
item_str = lambda key, value: f'<{key}>{value}</{key}>'

log_info_dict = {LOG_INFO_TYPE : logging.info,


LOG_WARN_TYPE : logging.warning,
LOG_ERROR_TYPE : logging.error}

class OPIExecError(Exception):
"""OPI executes error."""
pass

class ZTPErr(Exception):
"""ZTP error."""
pass

class ExecFileErr(Exception):
"""Execute file error."""
pass

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 194


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

class ZTPAbort(Exception):
"""Abort ZTP automatically."""
pass

class ZTPRollback(Exception):
"""ZTP startup info rollback."""
pass

def ops_conn_operation(func):
def wapper(*args, **kwargs):
ops_conn = ops.OPSConnection("localhost")
kwargs.update({"ops_conn": ops_conn})
try:
ret = func(*args, **kwargs)
return ret
except OPIExecError as reason:
raise OPIExecError(reason)
except Exception as reason:
exception_info = \
"{} failed, reason = {}".format(func.__name__, reason)
raise Exception(exception_info)
finally:
ops_conn.close()

return wapper

def print_ztp_log(ztp_info, log_type):


"""
ZTP log printing mode: console port log printing and logging log printing
"""
log_info_dict.get(log_type)(ztp_info)
# log_level = log_type.upper()
# slog.terminal.write(f"\n{log_level}:{ztp_info}", None, fgrd = True)

def cli_operation(func):
def wapper(*args, **kwargs):
ops_obj = ops.ops()
ops_obj.set_model_type(CLI_TYPE_YANG)
handle, result = ops_obj.cli.open()
if handle is None or result != "Success":
return ERR, result
kwargs.update({"ops_obj": ops_obj})
kwargs.update({"handle": handle})
try:
return func(*args, **kwargs)
except Exception as reason:
return ERR, str(reason)
finally:
ret, result = ops_obj.cli.close(handle)
if ret != OK:
logging.warning(f"Failed to close cli channel, handle = {handle}.")
return wapper

class cli():
""" Command operations """

@staticmethod
@cli_operation
def patch_delete_all(ops_obj=None, handle=None):
ops_obj.cli.execute(handle, "return")
choice = {"[Y/N]": "y"}
ret, _, result = ops_obj.cli.execute(handle, f'patch delete all', choice)
if ret is None:
return ERR, result

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 195


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

return OK, ret

@staticmethod
@cli_operation
def reset_next_feature_plugin(file_path, ops_obj=None, handle=None):
ops_obj.cli.execute(handle, "return")
ret, _, result = ops_obj.cli.execute(handle, f'reset feature-software next-startup {file_path}')
if ret is None:
return ERR, result
return OK, ret

def ops_return_result(ret):
return ((ret != http.client.OK) and \
(ret != http.client.CREATED) and \
(ret != http.client.NO_CONTENT))

@ops_conn_operation
def file_exist_on_slave(file_path='', ops_conn=None):

file_dir, file_name = os.path.split(file_path)


file_dir = file_dir + "/"
file_dir = file_dir.replace('/', '%2F')
uri = '{}'.format(f'/restconf/data/huawei-file-operation:file-operation/dirs/dir={file_name},{file_dir}')
req_data = None
ret, _, rsp_data = ops_conn.get(uri, req_data)
if ops_return_result(ret) or rsp_data == '':
return False
return True

@ops_conn_operation
def get_home_path(ops_conn=None):
""" Get the full filename of the home directory """
uri = '{}'.format('/restconf/data/huawei-file-operation:file-operation/disk-usages')
req_data = None
ret, _, rsp_data = ops_conn.get(uri, req_data)
if ops_return_result(ret) or rsp_data == '':
logging.error('Failed to get the current working directory.')
raise OPIExecError('Failed to get the home directory.')

root_elem = etree.fromstring(rsp_data)
namespaces = {'file-operation': 'urn:huawei:yang:huawei-file-operation'}
usb_dirs = []
slave_dir_list = []
master_dir = None
for disk_usage in root_elem.findall('file-operation:disk-usage', namespaces):
elem = disk_usage.find("file-operation:path", namespaces)
if elem is None or elem.text is None:
continue
if elem.text.lower().find('usb') >= 0:
usb_dirs.append(elem.text)
else:
if elem.text.lower().startswith('flash'):
master_dir = elem.text
else:
slave_dir_list.append(elem.text)
usb_dirs.sort(reverse=True)
return master_dir, slave_dir_list, usb_dirs

@ops_conn_operation
def file_exist_on_master(file_path='', ops_conn=None):
home_dir, _, _ = get_home_path()
if home_dir is None:
logging.error("Failed to get the home directory.")
return False
if file_path.startswith(home_dir):
file_path_real = file_path

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 196


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

else:
file_path_real = os.path.join(home_dir, file_path)

file_dir, file_name = os.path.split(file_path_real)


if file_dir == home_dir:
# Run the glob module to query the file in the root directory of the flash memory.
file_path_real = file_path_real.replace(home_dir, FLASH_HOME_PATH, 1)
file_list = glob.glob(file_path_real)
return True if len(file_list) > 0 else False
else:
# Invoke the YANG interface if the file is not in the root directory of the flash memory.
file_dir = file_dir + "/"
file_dir = file_dir.replace('/', '%2F')
uri = '{}'.format(f'/restconf/data/huawei-file-operation:file-operation/dirs/dir={file_name},{file_dir}')
req_data = None
ret, _, rsp_data = ops_conn.get(uri, req_data)
if ops_return_result(ret) or rsp_data == '':
return False
return True

def file_exist(file_path=''):
""" Check whether a file exists on the main control board. """

if file_path is None or file_path == '':


logging.warning("The path of file is none or ''.")
return ERR

if file_path.lower().startswith('flash'):
return file_exist_on_master(file_path)
else:
return file_exist_on_slave(file_path)

@ops_conn_operation
def file_delete(file_path='', ops_conn=None):
if file_path is None or file_path == '':
logging.warning("The path of file is none or ''.")
return ERR

if not file_exist(file_path): # file not exist


return OK

logging.info(f"Delete file '{file_path}' permanently...")


uri = '{}'.format('/restconf/operations/huawei-file-operation:delete-file')
req_template = string.Template('''
<input>
<file-name>$filePath</file-name>
<delete-type>$deleteType</delete-type>
</input>
''')
req_data = req_template.substitute(filePath=file_path, deleteType="unreserved")
ret, _, _ = ops_conn.create(uri, req_data)
if ops_return_result(ret):
logging.error('Failed to delete the file.')
return ret

logging.info("Delete the file successfully.")


return OK

def file_delete_on_MPUs(file_path='', slave=0):


if file_path:
file_name = os.path.basename(file_path)
home_path_master, home_path_slave, _= get_home_path()
ret = file_delete(file_path=os.path.join(home_path_master, file_name))
if ret != OK:
return ret
if slave: # If the standby main control board exists, delete files from it.
for slave_path in home_path_slave:

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 197


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

ret = file_delete(file_path=os.path.join(slave_path, file_name))


if ret != OK:
return ret
return OK

def del_list_file(files_list, exclude_file_list):


""" Deleted all files in the specified file list. """
for key in files_list.keys():
for filename in files_list.get(key):
if filename != exclude_file_list:
file_delete(os.path.join(key, filename))

@ops_conn_operation
def copy_file(src_path='', dest_path='', ops_conn=None):
"""Copy a file.

The value of src_path and dest_path can be in the format of filename,


flash:/filename, and flash:/xxx/filename.
"""
logging.info('Copy file {} to {}...'.format(src_path, dest_path))
uri = '{}'.format('/restconf/operations/huawei-file-operation:copy-file')
str_temp = string.Template('''\
<input>
<src-file-name>$src</src-file-name>
<des-file-name>$dest</des-file-name>
</input>
''')
req_data = str_temp.substitute(src=src_path, dest=dest_path)
ret, _, _ = ops_conn.create(uri, req_data)
if ops_return_result(ret):
logging.error('Copy file failed.')
return ERR
return OK

def get_file_list_cur(types=0):
filelist = []
fileNames = glob.glob(FLASH_HOME_PATH + r"/*.*")
try:
for fileName in fileNames:
name = os.path.basename(fileName)
filelist.append(name)
except Exception as reason:
logging.error("Failed to get file list! reason = {} ".format(reason))
return filelist

return filelist

@ops_conn_operation
def get_file_list(file_dir='', ops_conn=None):
"""Obtain the file list. """
file_list = []
home_dir, _, _ = get_home_path()
if home_dir == file_dir:
file_list = get_file_list_cur()
return file_list

if not file_dir.endswith('/'):
file_dir = '{}{}'.format(file_dir, '%2F')
file_dir = file_dir.replace('/', '%2F')

uriTmp = '{}'.format('/restconf/data/huawei-file-operation:file-operation/dirs/dir=')
uri = '{}{}{}'.format(uriTmp, ',', file_dir)
req_data = None
ret, _, rsp_data = ops_conn.get(uri, req_data)
if ops_return_result(ret) or rsp_data == '':

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 198


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

logging.error('Failed to get file list')


return file_list

rsp_data1=rsp_data.replace('<?xml version="1.0" encoding="UTF-8"?>','')


rsp_data1=rsp_data1.replace('xmlns="urn:huawei:yang:huawei-file-operation"','')
rsp_data = '{}{}{}'.format('<dirs>',rsp_data1,'</dirs>')

root_elem = etree.fromstring(rsp_data)
namespaces = {'file-operation': 'urn:huawei:yang:huawei-file-operation'}
mpath = '{}'.format('dir')
for file_tmp in root_elem.findall(mpath, namespaces):
file_name = file_tmp.find("file-name", namespaces)
elem = file_tmp.find("dir-name", namespaces)
if elem is None or file_name is None:
continue
_, part2 = os.path.splitext(file_name.text)
if part2 != '':
file_list.append(file_name.text)
return file_list

@ops_conn_operation
def get_file_size_form_dir(file_path='', file_dir='', ops_conn=None):
"""Return the size of a file in the directory under the home directory. """
file_size = 0
src_file_name = os.path.basename(file_path)
uriTmp = '{}'.format('/restconf/data/huawei-file-operation:file-operation/dirs/dir=')
uri = '{}{}{}{}'.format(uriTmp, src_file_name, ',', file_dir)
req_data = None
ret, _, rsp_data = ops_conn.get(uri, req_data)
if ops_return_result(ret) or rsp_data == '':
return file_size
else:
root_elem = etree.fromstring(rsp_data)
namespaces = {'file-operation': 'urn:huawei:yang:huawei-file-operation'}
uriTmp = '{}'.format('/size')
uriTmp = uriTmp.replace('/', '/file-operation:')
mpath = uriTmp[1:]
elem = root_elem.find(mpath, namespaces)
if elem is None:
return file_size
file_size = int(elem.text) / 1024
return file_size

def get_file_size_cur(file_path=''):

file_size = 0
if file_path == '' or file_path == None:
return file_size

src_file_name = os.path.basename(file_path)
fileName = '{}{}{}'.format(FLASH_HOME_PATH, '/', src_file_name)
try:
fileinfo = os.stat(fileName)
file_size = int(fileinfo.st_size)/1024
return file_size
except Exception as reason:
print_ztp_log(f"Get file size failed. reason = {reason}", LOG_ERROR_TYPE)
return file_size

def get_file_size(file_path=''):
"""Return the size of a file in the home directory."""
if file_path == '' or file_path == None:
return 0
home_dir, _, _ = get_home_path()
file_dir, _ = os.path.split(file_path)
if home_dir == file_dir:
return get_file_size_cur(file_path)

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 199


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

cwd, file_name= os.path.split(file_path)


file_dir = '{}{}'.format(cwd, '%2F')
file_dir = file_dir.replace('/', '%2F')

size = get_file_size_form_dir(file_path=file_name, file_dir=file_dir)

return size

@ops_conn_operation
def _sftp_download_file(ops_conn=None, url='', local_path=''):
"""Download files using SFTP.

Args:
url: URL of a remote file, for example, sftp://sftp_user:sftp_pwd@xx.xx.xx.xx:port/test/vrpcfg.cfg
local_path: The path must start with the root directory flash:, for example, flash:/vrpcfg.cfg or
vrpcfg.cfg.
"""
print_ztp_log(f'SFTP download {os.path.basename(url)} to {local_path}.', LOG_INFO_TYPE)
uri = '{}'.format('/restconf/operations/huawei-sshc:ssh-transfer-file')
str_temp = string.Template('''\
<input>
<server-port>$serverPort</server-port>
<host-addr-ipv4>$serverIp</host-addr-ipv4>
<command-type>get</command-type>
<user-name>$username</user-name>
<password>$password</password>
<local-file-name>$localPath</local-file-name>
<remote-file-name>$remotePath</remote-file-name>
</input>
''')
url_tuple = urlparse(url)
if re.match(r"\d+\.\d+\.\d+\.\d+", url_tuple.hostname):
server_ip = url_tuple.hostname
else:
server_ip = get_addr_by_hostname(host=url_tuple.hostname)
global sftp_server
sftp_server = server_ip
if url_tuple.port == None:
server_port = SFTP_DEFAULT_PORT
else:
server_port = url_tuple.port
req_data = str_temp.substitute(serverIp=server_ip,
serverPort=server_port,
username=url_tuple.username,
password=url_tuple.password,
remotePath=url_tuple.path[1:],
localPath=local_path)
try:
ret, _, _ = ops_conn.create(uri, req_data)
if ops_return_result(ret):
logging.error('Failed to download file "%s" using SFTP ret %s' %
(os.path.basename(local_path),ret))
ret = ERR
else:
ret = OK
return ret
except Exception as reason:
print_ztp_log(f'Failed to download file {os.path.basename(local_path)} using SFTP. (reason={reason})',
LOG_ERROR_TYPE)
return ERR

@ops_conn_operation
def _sftp_download_v6_file(ops_conn=None, url='', local_path=''):
print_ztp_log(f'SFTP ipv6 download {os.path.basename(url)} to {local_path}.', LOG_INFO_TYPE)
uri = '{}'.format('/restconf/operations/huawei-sshc:ssh-transfer-file')
str_temp = string.Template('''\
<input>

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 200


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

<server-port>$serverPort</server-port>
<host-addr-ipv6>$serverIp</host-addr-ipv6>
<command-type>get</command-type>
<user-name>$username</user-name>
<password>$password</password>
<local-file-name>$localPath</local-file-name>
<remote-file-name>$remotePath</remote-file-name>
</input>
''')
url_tuple = urlparse(url)
if check_addr(url_tuple.hostname) == 'DHCPv6':
server_ip = url_tuple.hostname
else:
server_ip = get_ipv6_addr_by_hostname(host=url_tuple.hostname)
global sftp_server
sftp_server = server_ip
if url_tuple.port == None:
server_port = SFTP_DEFAULT_PORT
else:
server_port = url_tuple.port
req_data = str_temp.substitute(serverIp=server_ip,
serverPort=server_port,
username=url_tuple.username,
password=url_tuple.password,
remotePath=url_tuple.path[1:],
localPath=local_path)

try:
ret, _, _ = ops_conn.create(uri, req_data)
if ops_return_result(ret):
logging.error('Failed to download file "%s" using SFTP ret %s' %
(os.path.basename(local_path),ret))
ret = ERR
else:
ret = OK
return ret
except Exception as reason:
print_ztp_log(f'Failed to download file {os.path.basename(local_path)} using SFTP. (reason={reason})',
LOG_ERROR_TYPE)
return ERR

@ops_conn_operation
def _http_download_file(ops_conn=None, url='', local_path=''):
"""Download files using HTTP.

Args:
url: URL of a remote file, for example,http://hostname[:port]/path
local_path: The path must start with the root directory flash:, for example, flash:/vrpcfg.cfg or
vrpcfg.cfg.
"""
print_ztp_log(f'HTTP download {os.path.basename(url)} to {local_path}.', LOG_INFO_TYPE)
uri = "{}".format('/restconf/operations/huawei-sztp:ztp-http-download')
req_template = string.Template('''
<input>
<fileurl>$file_url</fileurl>
<filepath>$file_path</filepath>
</input>
''')

file_dir, _, _ = get_home_path()
local_path = '{}{}'.format(file_dir, '/')

url_tuple = urlparse(url)
if not re.match(r"\d+\.\d+\.\d+\.\d+", url_tuple.hostname):
ip_address = get_addr_by_hostname(url_tuple.hostname)
if url_tuple.port is None:
url = f'{url_tuple.scheme}://{ip_address}:{HTTP_DEFAULT_PORT}{url_tuple.path}'
else:

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 201


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

url = f'{url_tuple.scheme}://{ip_address}:{url_tuple.port}{url_tuple.path}'
req_data = req_template.safe_substitute(file_url=url, file_path=local_path)

try:
ret, _, _ = ops_conn.create(uri, req_data)
if ops_return_result(ret):
logging.error('Failed to download file "%s" using HTTP ret %s' %
(os.path.basename(local_path),ret))
ret = ERR
else:
ret = OK
return ret
except Exception as reason:
print_ztp_log(f'Failed to download file {os.path.basename(local_path)} using HTTP. (reason={reason})',
LOG_ERROR_TYPE)
return ERR

def download_file(url, local_path, retry_times=0):


"""Download files using SFTP.
sftp://[username[:password]@]hostname[:port]/path
Download files using HTTP
http://hostname[:port]/path
Args:
url: URL of remote file
local_path: local path to put the file

Returns:
A integer of return code
"""
url_tuple = urlparse(url)
print_ztp_log(f"Download {url_tuple.path[1:]} to {local_path}...", LOG_INFO_TYPE)
func_dict = {
'sftp': _sftp_download_file,
'http': _http_download_file,
}
scheme = url_tuple.scheme
if scheme not in func_dict.keys():
raise ZTPErr('Unknown file transfer scheme %s' % scheme)
ret = OK
cnt = 0
while (cnt < 1 + retry_times):
if cnt:
print_ztp_log('Retry downloading...', LOG_INFO_TYPE)
ret = func_dict[scheme](url=url, local_path=local_path)
if ret is OK:
break
cnt += 1

if ret is not OK:


logging.warning('Try to delete the file that failed to download')
clean_download_temp_file(os.path.basename(url))
raise ZTPErr('Failed to download file "%s"' % os.path.basename(url))

return OK

def download_v6_file(url, local_path, retry_times=0):


url_tuple = urlparse(url)
print_ztp_log(f"Download {url_tuple.path[1:]} to {local_path} through IPv6...", LOG_INFO_TYPE)
func_dict = {
'sftp': _sftp_download_v6_file
}
scheme = url_tuple.scheme
if scheme not in func_dict.keys():
raise ZTPErr('Unknown file transfer scheme %s' % scheme)
ret = OK

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 202


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

cnt = 0
while (cnt < 1 + retry_times):
if cnt:
print_ztp_log('Retry downloading...', LOG_INFO_TYPE)
ret = func_dict[scheme](url=url, local_path=local_path)
if ret is OK:
break
cnt += 1

if ret is not OK:


logging.warning('Try to delete the file that failed to download')
clean_download_temp_file(os.path.basename(url))
raise ZTPErr('Failed to download file "%s"' % os.path.basename(url))

return OK

class StartupInfo(object):
""" Startup configuration information

image: startup system software


config: startup saved-configuration file
patch: startup patch package
feature_image: startup feature software
mod_list: startup module list
"""

def __init__(self, image=None, config=None, patch=None, mod_list=None, feature_plugin_list=None):


# display startup
self.image = image
self.config = config
self.patch = patch
self.feature_plugin_list = feature_plugin_list
# display module-information [next-startup]
self.mod_list = mod_list

def __eq__(self, obj):


if not isinstance(obj, StartupInfo):
return False

if self.image != obj.image or self.config != obj.config or self.patch != obj.patch:


return False

if self.feature_plugin_list is not None:


self.feature_plugin_list.sort()

if obj.feature_plugin_list is not None:


obj.feature_plugin_list.sort()

if self.feature_plugin_list != obj.feature_plugin_list:
return False

if self.mod_list is not None:


self.mod_list.sort()

if obj.mod_list is not None:


obj.mod_list.sort()

if self.mod_list != obj.mod_list:
return False

return True

class Startup(object):
"""Startup configuration information

current: current startup configuration


next: current next startup configuration

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 203


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

"""
def __init__(self):
self.current, self.next = self.get_startup_info()
self.is_need_clear_config = False
self.exportcfg = None

def set_exportcfg(self, export_value):


logging.info('Import configuration file.')
if export_value is not None:
self.exportcfg = export_value

def print_startup_info(self):
def get_info_str(info):
return str(info)

print_info = "Startup information of the current device:\n"


print_info += "{: <26}{: <68}{: <68}\n".format('item-name', 'configured', 'next-startup')
print_info += "-" * 150
print_info += "\n"
print_info += "{: <26}{: <68}{: <68}\n".format('system software',
get_info_str(self.current.image), get_info_str(self.next.image))
print_info += "{: <26}{: <68}{: <68}\n".format('saved-configurated file',
get_info_str(self.current.config), get_info_str(self.next.config))
print_info += "{: <26}{: <68}{: <68}\n".format('patch package',
get_info_str(self.current.patch), get_info_str(self.next.patch))

current_mod_info_len = len(self.current.mod_list)
next_mod_info_len = len(self.next.mod_list)
mod_info_len = max(current_mod_info_len, next_mod_info_len)
if mod_info_len == 0:
print_info += "{: <26}{: <68}{: <68}\n".format("module information", "None", "None")
else:
current_mod_info_print = [self.current.mod_list[i] if i < current_mod_info_len else "" for i in
range(mod_info_len)]
next_mod_info_print = [self.next.mod_list[i] if i < next_mod_info_len else "" for i in
range(mod_info_len)]
flag = True
for i in range(mod_info_len):
_item_name = "module information"
if not flag:
_item_name = ""
print_info += "{: <26}{: <68}{: <68}\n".format(_item_name, current_mod_info_print[i],
next_mod_info_print[i])
flag = False

current_feature_plugin_info_len = len(self.current.feature_plugin_list)
next_feature_plugin_info_len = len(self.next.feature_plugin_list)
feature_plugin_info_len = max(current_feature_plugin_info_len, next_feature_plugin_info_len)
if feature_plugin_info_len == 0:
print_info += "{: <26}{: <68}{: <68}\n".format("feature software", "None", "None")
else:
current_feature_plugin_info_print = [self.current.feature_plugin_list[i] if i <
current_feature_plugin_info_len else "" for i in range(feature_plugin_info_len)]
next_feature_plugin_info_print = [self.next.feature_plugin_list[i] if i < next_feature_plugin_info_len
else "" for i in range(feature_plugin_info_len)]
flag = True
for i in range(feature_plugin_info_len):
_item_name = "feature software"
if not flag:
_item_name = ""
print_info += "{: <26}{: <68}{: <68}\n".format(_item_name, current_feature_plugin_info_print[i],
next_feature_plugin_info_print[i])
flag = False

logging.info(print_info)

@staticmethod
def get_startup_info_by_type(file_type):
def func_execption_retry_policy(sleep_interval, try_times, func, *argv):

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 204


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

for _ in range(try_times):
try:
return func(*argv)
except OPIExecError as reason:
logging.warning(f"{reason}, retry...")
sleep(sleep_interval)
raise OPIExecError(f"Failed to get startup {file_type} information for many times.")

func_dict = {
FILE_TYPE_CFG: Startup.get_cfg_info,
FILE_TYPE_PAT: Startup.get_patch_info,
FILE_TYPE_SOFTWARE: Startup.get_software_info,
FILE_TYPE_MOD: Startup.get_mod_patch_info,
FILE_TYPE_FEATURE_PLUGIN: Startup.get_feature_plugin_info
}
func = func_dict.get(file_type)
if func is None:
return None, None
return func_execption_retry_policy(GET_STARTUP_INTERVAL, MAX_TIMES_GET_STARTUP, func)

@staticmethod
@ops_conn_operation
def get_cfg_info(ops_conn=None):
items = ['current-cfg-file', 'next-cfg-file']
filtering_str = ';'.join(items)
uri = "{}".format(f'/restconf/data?fields=/huawei-cfg:cfg/startup-infos/startup-info({filtering_str})')
req_data = None
ret, _, rsp_data = ops_conn.get(uri, req_data)
if ops_return_result(ret) or rsp_data == '':
raise OPIExecError('Failed to get the current config file information')

node_dict = {}
root_elem = etree.fromstring(rsp_data)
namespaces = {'cfg': 'urn:huawei:yang:huawei-cfg'}
elems = root_elem.find('cfg:cfg/cfg:startup-infos/cfg:startup-info', namespaces)
if elems is None:
return None, None

nslen = len(namespaces.get('cfg'))
for elem in elems:
tag_name = elem.tag[nslen + 2:]
if elem.text is None or elem.text == 'NULL':
continue
node_dict[tag_name] = elem.text

current_cfg = node_dict.get('current-cfg-file')
if current_cfg is not None:
current_cfg = os.path.basename(current_cfg)

next_cfg = node_dict.get('next-cfg-file')
if next_cfg is not None:
next_cfg = os.path.basename(next_cfg)

return current_cfg, next_cfg

@staticmethod
@ops_conn_operation
def get_software_info(ops_conn=None):
items = ['current-package', 'next-package']
filtering_str = ';'.join(items)
uri = "{}".format(f'/restconf/data?fields=/huawei-software:software/startup-packages/startup-
package({filtering_str})')
req_data = None
ret, _, rsp_data = ops_conn.get(uri, req_data)
if ret == http.client.NOT_FOUND:
rsp_data = '<software xmlns="urn:huawei:yang:huawei-software"></software>'
else:
if ops_return_result(ret) or rsp_data == '':
raise OPIExecError('Failed to get the startup software information')

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 205


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

root_elem = etree.fromstring(rsp_data)
namespaces = {'software': 'urn:huawei:yang:huawei-software'}
elems = root_elem.find('software:software/software:startup-packages/software:startup-package',
namespaces)
if elems is None:
return None, None

node_dict = {}
nslen = len(namespaces.get('software'))
for elem in elems:
tag_name = elem.tag[nslen + 2:]
if elem.text is None or elem.text == 'NULL':
continue
node_dict[tag_name] = elem.text

cur_image = node_dict.get('current-package')
if cur_image is not None:
cur_image = os.path.basename(cur_image)

next_image = node_dict.get('next-package')
if next_image is not None:
next_image = os.path.basename(next_image)

return cur_image, next_image

@staticmethod
@ops_conn_operation
def get_patch_info(ops_conn=None):
items = ['patch-infos', 'next-startup-patchs']
filtering_str = ';'.join(items)
uri = "{}".format(f'/restconf/data?fields=/huawei-patch:patch({filtering_str})')
req_data = None
ret, _, rsp_data = ops_conn.get(uri, req_data)
if ret == http.client.NOT_FOUND:
return None, None

if ops_return_result(ret) or rsp_data == '':


raise OPIExecError('Failed to get the patch file information')

root_elem = etree.fromstring(rsp_data)
namespaces = {'patch': 'urn:huawei:yang:huawei-patch'}
elems = root_elem.find('patch:patch/patch:patch-infos/patch:patch-info', namespaces)
node_dict = {}
cur_pat_file = None
if elems is not None:
nslen = len(namespaces.get('patch'))
for elem in elems:
tag_name = elem.tag[nslen + 2:]
node_dict[tag_name] = elem.text

cur_pat_file = node_dict.get("name")
if cur_pat_file is not None:
cur_pat_file = os.path.basename(cur_pat_file)

elems = root_elem.find('patch:patch/patch:next-startup-patchs/patch:next-startup-patch', namespaces)


if elems is None:
return cur_pat_file, None

node_dict = {}
nslen = len(namespaces.get('patch'))
for elem in elems:
tag_name = elem.tag[nslen + 2:]
node_dict[tag_name] = elem.text

next_pat_file = node_dict.get("name")
if next_pat_file is not None:
next_pat_file = os.path.basename(next_pat_file)

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 206


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

return cur_pat_file, next_pat_file

@staticmethod
@ops_conn_operation
def get_mod_patch_info(ops_conn=None):
items = ['module-infos', 'next-startup-modules']
filtering_str = ';'.join(items)
uri = "{}".format(f'/restconf/data?fields=/huawei-module-management:module-
management({filtering_str})')
req_data = None
ret, _, rsp_data = ops_conn.get(uri, req_data)
if ret == http.client.NOT_FOUND:
return [] ,[]

if ops_return_result(ret) or rsp_data == '':


raise OPIExecError('Failed to get the mod patch file information')

root_elem = etree.fromstring(rsp_data)
namespaces = {'module-management' : 'urn:huawei:yang:huawei-module-management'}
cur_mod_patch_files = []
node_path = 'module-management:module-management/module-management:module-infos/module-
management:module-info'
elems = root_elem.findall(node_path, namespaces)
if elems is not None:
for elem in elems:
elem_text = elem.find('module-management:package-name', namespaces)
cur_mod_patch_files.append(elem_text.text)

next_mod_patch_files = []
node_path = 'module-management:module-management/module-management:next-startup-modules/
module-management:next-startup-module'
elems = root_elem.findall(node_path, namespaces)
if elems is not None:
for elem in elems:
elem_text = elem.find('module-management:name', namespaces)
next_mod_patch_files.append(elem_text.text)

return cur_mod_patch_files, next_mod_patch_files

@staticmethod
@ops_conn_operation
def get_feature_plugin_info(ops_conn=None):
items = ['current-feature-packages', 'next-feature-packages']
filtering_str = ';'.join(items)
uri = "{}".format(f'/restconf/data?fields=/huawei-software:software/startup-packages/startup-
package({filtering_str})')
req_data = None
ret, _, rsp_data = ops_conn.get(uri, req_data)
if ret == http.client.NOT_FOUND:
rsp_data = '<software xmlns="urn:huawei:yang:huawei-software"></software>'
else:
if ops_return_result(ret) or rsp_data == '':
raise OPIExecError('Failed to get the startup software information')

root_elem = etree.fromstring(rsp_data)
node_path = 'software:software/software:startup-packages/software:startup-package'
namespaces = {'software' : 'urn:huawei:yang:huawei-software'}
elems = root_elem.findall(node_path, namespaces)
if elems is None:
return [], []

cur_feature_files = []
next_feature_files = []
nlen = len(namespaces['software'])
for elem in elems:
for child in elem:
if child.tag[nlen + 2:] == 'current-feature-packages':
feature_plugin = os.path.basename(child.text)

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 207


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

cur_feature_files.append(feature_plugin)
elif child.tag[nlen + 2:] == 'next-feature-packages':
feature_plugin = os.path.basename(child.text)
next_feature_files.append(feature_plugin)
else:
pass
break
return cur_feature_files, next_feature_files

def get_startup_info(self):
"""Get the startup information."""
print_ztp_log("Start to get the startup information...", LOG_INFO_TYPE)
current = StartupInfo()
curnext = StartupInfo()

current.config, curnext.config = Startup.get_startup_info_by_type(FILE_TYPE_CFG)


current.patch, curnext.patch = Startup.get_startup_info_by_type(FILE_TYPE_PAT)
current.image, curnext.image = Startup.get_startup_info_by_type(FILE_TYPE_SOFTWARE)
current.feature_plugin_list, curnext.feature_plugin_list =
Startup.get_startup_info_by_type(FILE_TYPE_FEATURE_PLUGIN)
current.mod_list, curnext.mod_list = Startup.get_startup_info_by_type(FILE_TYPE_MOD)

return current, curnext

@staticmethod
@ops_conn_operation
def set_mod_patch_file(file_path, ops_conn=None):
uri = '/restconf/operations/huawei-module-management:install-module'
req_template = string.Template('''
<input>
<name>$fileName</name>
</input>
''')
req_data = req_template.substitute(fileName=file_path)
ret, _, rsp_data = ops_conn.create(uri, req_data)
if ops_return_result(ret):
logging.error(f'set_mod_patch_file failed. (reason={rsp_data})')
raise OPIExecError('Failed to set the mod patch file')

def clean_next_config_file(self):
if self.is_need_clear_config == False:
return

_, nextcfg= self.get_startup_info_by_type(FILE_TYPE_CFG)
if nextcfg is not None:
self._del_startup_config_file()
sleep(5)

@ops_conn_operation
def set_next_mod_patch_file(self, file_path, ops_conn=None):
uri = '/restconf/operations/huawei-module-management:startup-module'
req_template = string.Template('''
<input>
<name>$fileName</name>
</input>
''')
req_data = req_template.substitute(fileName=file_path)
ret, _, rsp_data = ops_conn.create(uri, req_data)
if ops_return_result(ret):
logging.error(f'set_next_mod_patch_file failed. (reason={rsp_data})')
raise OPIExecError('Failed to set the next mod patch file')

@ops_conn_operation
def startup_next_feature_software(self, file_path, ops_conn=None):
""" Set next feature software file """
uri = '/restconf/operations/huawei-software:startup-feature-software'
req_template = string.Template('''
<input>
<feature-package-name>$fileName</feature-package-name>

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 208


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

</input>
''')
req_data = req_template.substitute(fileName=file_path)
ret, _, rsp_data = ops_conn.create(uri, req_data)
if ops_return_result(ret):
raise OPIExecError(f"Failed to set next feature plugin {rsp_data}.")

@ops_conn_operation
def unset_mod_patch_file(self, file_path, ops_conn=None):
uri = '/restconf/operations/huawei-module-management:uninstall-module'
req_template = string.Template('''
<input>
<action-type>single</action-type>
<name>$fileName</name>
</input>
''')
req_data = req_template.substitute(fileName=file_path)
ret, _, rsp_data = ops_conn.create(uri, req_data)
if ops_return_result(ret):
logging.error(f'unset_mod_patch_file failed. (reason={rsp_data})')
raise OPIExecError('Failed to unset the mod patch file')

@staticmethod
@ops_conn_operation
def set_feature_software(file_path, ops_conn=None):
uri = '/restconf/operations/huawei-software:install-feature-software'
req_template = string.Template('''
<input>
<name>$fileName</name>
</input>
''')
req_data = req_template.substitute(fileName=file_path)
ret, _, rsp_data = ops_conn.create(uri, req_data)
if ops_return_result(ret):
logging.error(f'Failed to set the feature software file. (reason={rsp_data})')
raise OPIExecError('Failed to set the feature software file')

@ops_conn_operation
def uninstall_feature_software(self, file_path, ops_conn=None):
""" Install feature software file """
uri = '/restconf/operations/huawei-software:uninstall-feature-software'
req_template = string.Template('''
<input>
<name>$fileName</name>
</input>
''')
req_data = req_template.substitute(fileName=file_path)
ret, _, _ = ops_conn.create(uri, req_data)
if ops_return_result(ret):
return ERR
return OK

def unset_feature_file_list(self, file_list, slave):


for file in file_list:
logging.info("Unset the feature plugin file...")
ret = self.uninstall_feature_software(file)
if ret == ERR:
logging.error(f"Failed unset feature {file}.")
continue
file_delete_on_MPUs(file, slave)

def reset_next_feature_file_list(self, file_list, slave):


for file in file_list:
logging.info("Reset the next feature plugin file...")
ret, _ = cli.reset_next_feature_plugin(file)
if ret == ERR:
logging.error(f"Failed reset next feature {file}.")
continue
file_delete_on_MPUs(file, slave)

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 209


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

@ops_conn_operation
def _set_startup_image_file(self, file_path, ops_conn=None):
"""Set the next startup system software."""
logging.info("Set the next startup system software "
"to {}...".format(file_path))

uri = '/restconf/operations/huawei-software:startup-by-mode'
str_temp = string.Template('''\
<input>
<name>$fileName</name>
<mode>all</mode>
</input>
''')
req_data = str_temp.substitute(fileName=file_path)
ret, _, _ = ops_conn.create(uri, req_data)
if ops_return_result(ret):
slog.syslog("Set the next startup system software to {} failed."\
.format(file_path), ops.ERROR, ops.SYSLOG)
raise OPIExecError("Failed to set startup system software.")

slog.syslog("Set the next startup system software to {} successfully."\


.format(file_path), ops.INFORMATIONAL, ops.SYSLOG)

@ops_conn_operation
def _set_startup_config_file(self, file_path, exportcfg=None, ops_conn=None):
"""Set the configuration file for the next startup."""
logging.info("Set the next startup saved-configuration file "
"to {}...".format(file_path))

uri = '/restconf/operations/huawei-cfg:set-startup'
req_data = ''
if exportcfg is not None:
exportcfg_change = ops.opscharacterEncode(exportcfg)
items = {'filename': file_path, 'shareable-mode': 'password', 'password': exportcfg_change}
else:
items = {'filename': file_path, 'shareable-mode': 'default'}

for key in items.keys():


req_data = '{}{}'.format(req_data, item_str(key, items[key]))

req_data=item_str('input', req_data)
ret, _, data = ops_conn.create(uri, req_data)
if ops_return_result(ret):
logging.error(f"Set the next startup saved-configuration file to {data} failed")
slog.syslog("Set the next startup saved-configuration file to {} failed."\
.format(file_path), ops.ERROR, ops.SYSLOG)
raise OPIExecError("Failed to set startup configuration file.")

slog.syslog("Set the next startup saved-configuration file to {} successfully."\


.format(file_path), ops.INFORMATIONAL, ops.SYSLOG)

@ops_conn_operation
def _del_startup_config_file(self, ops_conn=None):
"""Clear the startup configuration file."""
logging.info("Delete the next startup config file...")

uri = '/restconf/operations/huawei-cfg:clear-startup'
req_data = '''
<input>
</input>
'''
ret, _, _ = ops_conn.create(uri, req_data)
if ops_return_result(ret):
raise OPIExecError("Failed to clear startup configuration file.")

@ops_conn_operation
def _set_startup_patch_file(self, file_path, ops_conn=None):

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 210


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

"""Set the next startup patch file."""


logging.info("Set the next startup patch file "
"to {}...".format(file_path))

uri = '/restconf/operations/huawei-patch:startup-next-patch'
str_temp = string.Template('''\
<input>
<name>$fileName</name>
</input>
''')
req_data = str_temp.substitute(fileName=file_path)
ret, _, _ = ops_conn.create(uri, req_data)
if ops_return_result(ret):
slog.syslog("Set the next startup patch file to {} failed."\
.format(file_path), ops.ERROR, ops.SYSLOG)
raise OPIExecError("Failed to set startup patch file.")

slog.syslog("Set the next startup patch file to {} successfully."\


.format(file_path), ops.INFORMATIONAL, ops.SYSLOG)

def set_next_mod_patch_file_list(self, mod_patch_file, slave):


if mod_patch_file is None:
return

try:
self.set_next_mod_patch_file(mod_patch_file)
ret = self._check_set_startup_schedule(set_type=SET_MOD_PATCH, phase_item="startup-module",
retry_times=MAX_TIMES_GET_STARTUP)
if ret == ERR:
raise Exception("Set startup info {} failed".format(SET_MOD_PATCH))

if self.is_need_clear_config:
_, nextcfg= self.get_startup_info_by_type(FILE_TYPE_CFG)
if nextcfg is not None:
self._del_startup_config_file()
sleep(5)
except Exception as reason:
logging.error(reason)
self.reset_startup_info(slave)
file_delete(f'flash:/{mod_patch_file}')
file_delete(f'flash:/$_install_mod/{mod_patch_file}')
raise

def set_next_feature_plugin(self, file_name, slave):


if file_name is None:
return

try:
logging.info("Set the next feature plugin file...")
self.startup_next_feature_software(file_name)

self.clean_next_config_file()
except Exception as reason:
logging.error(reason)
self.reset_startup_info(slave)
raise

def reset_mod_patch_file_list(self, cur_mod_list, pre_next_mod_list, slave):


del_mod_file_list = []
for mod_file in cur_mod_list:
if mod_file not in pre_next_mod_list:
del_mod_file_list.append(mod_file)

for mod_patch_file in del_mod_file_list:


src_file_path = f'flash:/{mod_patch_file}'
dest_file_path = f'flash:/$_install_mod/{mod_patch_file}'
try:
self.unset_mod_patch_file(mod_patch_file)
ret = self._check_set_startup_schedule(set_type=SET_MOD_PATCH, phase_item="uninstall-

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 211


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

module", retry_times=MAX_TIMES_GET_STARTUP)
if ret == ERR:
raise Exception("Unset startup info {} failed".format(SET_MOD_PATCH))

file_delete(src_file_path)
file_delete(dest_file_path)
except Exception as reason:
logging.error(reason)

if self.is_need_clear_config:
_, nextcfg= self.get_startup_info_by_type(FILE_TYPE_CFG)
if nextcfg is not None:
self._del_startup_config_file()
sleep(5)

def reset_feature_plugin_file(self, pre_cur_file_list, configured_cur_file_list, pre_next_file_list,


configured_next_file_list, slave):
unset_file_list = [file for file in configured_cur_file_list if file not in pre_cur_file_list]
self.unset_feature_file_list(unset_file_list, slave)

reset_file_list = [file for file in configured_next_file_list if file not in pre_next_file_list and file not in
configured_cur_file_list]
self.reset_next_feature_file_list(reset_file_list, slave)

self.clean_next_config_file()

def rollback_feature_plugin_file(self, cur_file_list, pre_file_list):


for file in cur_file_list:
if pre_file_list is not None and file in pre_file_list:
continue

logging.info(f"Reset the feature software file {file}...")


ret, rsp_data = cli.reset_next_feature_plugin(file)
if ret == ERR:
logging.error(f'Failed to reset the feature software file {rsp_data}')
sleep(5)

self.clean_next_config_file()

def rollback_mod_patch_file_list(self, cur_mod_list, pre_next_mod_list):


del_mod_file_list = []
for mod_file in cur_mod_list:
if pre_next_mod_list is not None and mod_file in pre_next_mod_list:
continue
del_mod_file_list.append(mod_file)

for mod_patch_file in del_mod_file_list:


try:
self.unset_mod_patch_file(mod_patch_file)
ret = self._check_set_startup_schedule(set_type=SET_MOD_PATCH, phase_item="uninstall-
module", retry_times=MAX_TIMES_GET_STARTUP)
if ret == ERR:
logging.warning("Unset startup info {} failed".format(SET_MOD_PATCH))
except Exception as reason:
logging.error(reason)

if self.is_need_clear_config:
_, nextcfg= self.get_startup_info_by_type(FILE_TYPE_CFG)
if nextcfg is not None:
self._del_startup_config_file()
sleep(5)

@ops_conn_operation
def _reset_startup_patch_file(self, ops_conn=None):
"""Reset the patch file for system startup."""
logging.info("Reset the next startup patch file...")

uri = '/restconf/operations/huawei-patch:reset-startup-patch'
req_data = '''\

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 212


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

<input>
<delete-type>all</delete-type>
</input>
'''
ret, _, _ = ops_conn.create(uri, req_data)
if ops_return_result(ret):
raise OPIExecError('Failed to reset patch.')

def reset_startup_info(self, slave):


"""Reset startup info and delete the downloaded files"""
print_ztp_log("Reset the next startup information...", LOG_INFO_TYPE)
cur_startup_info, configured = self.get_startup_info()

self.is_need_clear_config = True
if self.next.config is not None:
self.is_need_clear_config = False

# 1. Reset next startup config file and delete it


try:
if configured.config != self.next.config:
if self.next.config is None:
self._del_startup_config_file()
sleep(15)
else:
self._set_startup_config_file(self.next.config)
ret = self._check_set_startup_info(set_type=SET_CFG, file_path=self.next.config,
retry_times=TIMES_STARTUP_RETRY)
if ret == ERR:
logging.warning("Set startup info {} failed".format(SET_CFG))

if configured.config is not None:


file_delete_on_MPUs(configured.config, slave)

except Exception as reason:


logging.error(reason)

# 2. Reset next startup patch file


try:
if cur_startup_info.patch != self.current.patch:
if self.current.patch is None:
cli.patch_delete_all()
else:
self.patch_active_proc(self.current.patch)
if self.is_need_clear_config:
_, nextcfg= self.get_startup_info_by_type(FILE_TYPE_CFG)
if nextcfg is not None:
self._del_startup_config_file()
sleep(5)
if cur_startup_info.patch is not None:
file_delete_on_MPUs(cur_startup_info.patch, slave)

if configured.patch != self.next.patch:
if self.next.patch is None:
self._reset_startup_patch_file()
ret = self._check_set_startup_schedule(set_type=SET_PATCH, phase_item="reset-startup-
patch", retry_times=MAX_TIMES_GET_STARTUP)
if ret == ERR:
logging.warning("Reset startup info {} failed".format(SET_PATCH))
else:
self._set_startup_patch_file(self.next.patch)
ret = self._check_set_startup_schedule(set_type=SET_PATCH, phase_item="startup-next-patch",
retry_times=MAX_TIMES_GET_STARTUP)
if ret == ERR:
logging.warning("Set startup info {} failed".format(SET_PATCH))

if self.is_need_clear_config:
_, nextcfg= self.get_startup_info_by_type(FILE_TYPE_CFG)
if nextcfg is not None:
self._del_startup_config_file()

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 213


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

sleep(5)
if configured.patch is not None:
file_delete_on_MPUs(configured.patch, slave)

except Exception as reason:


logging.error(reason)

# 3. Reset next startup system software and delete it


try:
if configured.image != self.next.image:
self._set_startup_image_file(self.next.image)
ret = self._check_set_startup_info(set_type=SET_SOFTWARE, file_path=self.next.image,
retry_times=TIMES_STARTUP_RETRY)
if ret == ERR:
logging.warning("Set startup info {} failed".format(SET_SOFTWARE))

if self.is_need_clear_config:
_, nextcfg= self.get_startup_info_by_type(FILE_TYPE_CFG)
if nextcfg is not None:
self._del_startup_config_file()
sleep(5)
sleep(90)
file_delete_on_MPUs(configured.image, slave)
except Exception as reason:
logging.error(reason)

self.reset_mod_patch_file_list(configured.mod_list, self.next.mod_list, slave)


configured_cur_feature_list = cur_startup_info.feature_plugin_list
configured_next_feature_list = configured.feature_plugin_list
pre_cur_feature_list = self.current.feature_plugin_list
pre_next_feature_list = self.next.feature_plugin_list
self.reset_feature_plugin_file(pre_cur_feature_list, configured_cur_feature_list, pre_next_feature_list,
configured_next_feature_list, slave)

def set_startup_info(self, image_file=None, config_file=None, patch_file=None,


mod_file=None, feature_plugin=None, slave=0):
"""Set the next startup information."""
print_ztp_log("Set the next startup information...", LOG_INFO_TYPE)
self.is_need_clear_config = True
if self.next.config is not None:
self.is_need_clear_config = False

# 1. Set next startup system software


if image_file is not None:
try:
self._set_startup_image_file(image_file)
ret = self._check_set_startup_info(set_type=SET_SOFTWARE, file_path=image_file,
retry_times=TIMES_STARTUP_RETRY)
if ret == ERR:
raise Exception("Set startup info {} failed".format(SET_SOFTWARE))

if self.is_need_clear_config:
_, nextcfg = self.get_startup_info_by_type(FILE_TYPE_CFG)
if nextcfg is not None:
self._del_startup_config_file()
sleep(5)
except Exception as reason:
logging.error(reason)
file_delete_on_MPUs(image_file, slave)
self.reset_startup_info(slave)
raise

# 2. Set next startup patch file


if patch_file is not None:
try:
self._set_startup_patch_file(patch_file)
ret = self._check_set_startup_schedule(set_type=SET_PATCH, phase_item="startup-next-
patch",retry_times=MAX_TIMES_GET_STARTUP)
if ret == ERR:

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 214


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

raise Exception("Set startup info {} failed".format(SET_PATCH))

if self.is_need_clear_config:
_, nextcfg= self.get_startup_info_by_type(FILE_TYPE_CFG)
if nextcfg is not None:
self._del_startup_config_file()
sleep(5)
except Exception as reason:
logging.error(reason)
file_delete_on_MPUs(patch_file, slave)
self.reset_startup_info(slave)
raise

# 3. Set mod patch


self.set_next_mod_patch_file_list(mod_file, slave)
self.set_next_feature_plugin(feature_plugin, slave)

# 4. Set next startup config file


if config_file is not None:
try:
self._set_startup_config_file(config_file, self.exportcfg)
ret = self._check_set_startup_info(set_type=SET_CFG, file_path=config_file,
retry_times=TIMES_STARTUP_RETRY)
if ret == ERR:
raise Exception("Set startup info {} failed".format(SET_CFG))
except Exception as reason:
logging.error(reason)
file_delete_on_MPUs(config_file, slave)
self.reset_startup_info(slave)
raise

def rollback_startup_info(self, image_file, config_file=None, patch_file=None,


mod_file_list=None, feature_plugin_list=None):
"""Rollback startup information."""

print_ztp_log("Rollback startup information...", LOG_INFO_TYPE)


_, configured = self.get_startup_info()

self.is_need_clear_config = True
if config_file is not None:
self.is_need_clear_config = False
# 1. Reset next startup config file
try:
if configured.config != config_file:
if config_file is None:
self._del_startup_config_file()
sleep(15)
else:
self._set_startup_config_file(config_file)
ret = self._check_set_startup_info(set_type=SET_CFG, file_path=config_file,
retry_times=TIMES_STARTUP_RETRY)
if ret == ERR:
logging.warning("Set startup info {} failed".format(SET_CFG))
except Exception as reason:
logging.error(reason)

# 2. Reset next startup patch file


try:
if configured.patch != patch_file:
if patch_file is None:
self._reset_startup_patch_file()
ret = self._check_set_startup_schedule(set_type=SET_PATCH, phase_item="reset-startup-
patch", retry_times=MAX_TIMES_GET_STARTUP)
if ret == ERR:
logging.warning("Reset startup info {} failed".format(SET_PATCH))
else:
self._set_startup_patch_file(patch_file)
ret = self._check_set_startup_schedule(set_type=SET_PATCH, phase_item="startup-next-patch",
retry_times=MAX_TIMES_GET_STARTUP)

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 215


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

if ret == ERR:
logging.warning("Set startup info {} failed".format(SET_PATCH))

if self.is_need_clear_config:
_, nextcfg= self.get_startup_info_by_type(FILE_TYPE_CFG)
if nextcfg is not None:
self._del_startup_config_file()
sleep(5)
except Exception as reason:
logging.error(reason)

# 3. Reset the next startup system software


try:
if configured.image != image_file:
self._set_startup_image_file(image_file)
ret = self._check_set_startup_info(set_type=SET_SOFTWARE, file_path=image_file,
retry_times=TIMES_STARTUP_RETRY)
if ret == ERR:
logging.warning("Set startup info {} failed".format(SET_SOFTWARE))
sleep(90)

if self.is_need_clear_config:
_, nextcfg= self.get_startup_info_by_type(FILE_TYPE_CFG)
if nextcfg is not None:
self._del_startup_config_file()
sleep(5)
except Exception as reason:
logging.error(reason)

# 4. Reset next startup system mod patch


self.rollback_mod_patch_file_list(configured.mod_list, mod_file_list)
self.rollback_feature_plugin_file(configured.feature_plugin_list, feature_plugin_list)

@ops_conn_operation
def _get_set_next_software_status(self, file_path, ops_conn=None):
"""Get the next software information."""

print_ztp_log("Get the next startup software information...", LOG_INFO_TYPE)


items = ['next-package']
filtering_str = ';'.join(items)
uri = "{}".format(f'/restconf/data?fields=/huawei-software:software/startup-packages/startup-
package({filtering_str})')
req_data = None
ret, _, rsp_data = ops_conn.get(uri, req_data)
if ops_return_result(ret) or rsp_data == '':
logging.warning('Failed to get the startup information')
return ERR

root_elem = etree.fromstring(rsp_data)
namespaces = {'software': 'urn:huawei:yang:huawei-software'}
elems = root_elem.find('software:software/software:startup-packages/software:startup-package',
namespaces)
if elems is None:
return ERR

node_dict = {}
nslen = len(namespaces.get('software'))
for elem in elems:
tag_name = elem.tag[nslen + 2:]
if elem.text is None and elem.text == 'NULL':
continue
node_dict[tag_name] = elem.text

next_image = node_dict.get('next-package')
if next_image is not None:
next_image = os.path.basename(next_image)

file_name = os.path.basename(file_path)
return OK if file_name == next_image else ERR

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 216


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

@ops_conn_operation
def _get_set_next_cfg_status(self, file_path, ops_conn=None):
"""Get the next cfg file information."""
print_ztp_log("Get the next cfg file information...", LOG_INFO_TYPE)
file_name = os.path.basename(file_path)
uri = '/restconf/data?fields=/huawei-cfg:cfg/startup-infos/startup-info(next-cfg-file)'
req_data = None

ret, _, rsp_data = ops_conn.get(uri, req_data)


if ops_return_result(ret) or rsp_data == '':
logging.warning('Failed to get the next cfg file information')
return ERR

root_elem = etree.fromstring(rsp_data)
namespaces = {'data':'urn:ietf:params:xml:ns:yang:ietf-restconf','cfg': 'urn:huawei:yang:huawei-cfg'}
uriTmp = '{}'.format('/cfg/startup-infos/startup-info')
uriTmp = uriTmp.replace('/', '/cfg:')
mpath = uriTmp[1:]
for info in root_elem.findall(mpath, namespaces):
elem_name = info.find("cfg:next-cfg-file", namespaces)
if elem_name is None:
return ERR
cfg_file_name = os.path.basename(elem_name.text)
if cfg_file_name != file_name:
return ERR

return OK

def _get_set_next_feature_image_status(self, file_path):


_, next_feature_image = Startup.get_feature_plugin_info()
return ERR if file_path != next_feature_image else OK

def _check_set_startup_info(self, set_type, file_path, retry_times=10):


print_ztp_log(f"Now checking {set_type} is complete or not...", LOG_INFO_TYPE)
func_dict = {
SET_SOFTWARE: self._get_set_next_software_status,
SET_CFG: self._get_set_next_cfg_status,
SET_FEATURE_PLUGIN: self._get_set_next_feature_image_status
}

if set_type not in func_dict.keys():


logging.warning('Unknown check startup type')
return ERR
ret = OK
cnt = 0
while cnt < retry_times:
ret = func_dict[set_type](file_path=file_path)
if ret == ERR:
cnt += 1
logging.info("Now system is {}, please wait...".format(set_type))
sleep(DELAY_INTERVAL_SET_INFO) # sleep to wait for system ready
continue
else:
sleep(10) # Wait for a period of time when the next startup item is as expected.
break
return ret

@ops_conn_operation
def _get_patch_progress(self, phase_item, ops_conn=None):
"""Get the next patch file information."""
uri = f'/restconf/data?fields=/huawei-patch:patch/operation-schedules(operation-schedule)'
req_data = None
ret, _, rsp_data = ops_conn.get(uri, req_data)
schedule_dict = {}
if ops_return_result(ret) or rsp_data == '':
logging.warning('Failed to get the next patch operation schedule')
return schedule_dict

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 217


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

namespaces = {'patch': 'urn:huawei:yang:huawei-patch'}


node_path = "patch:patch/patch:operation-schedules/patch:operation-schedule"
root_elem = etree.fromstring(rsp_data)
elems = root_elem.findall(node_path, namespaces)
if elems is None:
return schedule_dict

for elem in elems:


phase_node = elem.find('patch:phase', namespaces)
if phase_node is not None and phase_node.text == phase_item:
status_node = elem.find('patch:status', namespaces)
if status_node is not None:
schedule_dict['status'] = status_node.text
schedule_node = elem.find('patch:schedule', namespaces)
if schedule_node is not None:
schedule_dict['schedule'] = schedule_node.text
break
return schedule_dict

@ops_conn_operation
def _get_mod_patch_progress(self, phase_item, ops_conn=None):
"""Get the next patch file information."""
uri = f'/restconf/data?fields=/huawei-module-management:module-management/operation-
schedules(operation-schedule)'
req_data = None
ret, _, rsp_data = ops_conn.get(uri, req_data)
schedule_dict = {}
if ops_return_result(ret) or rsp_data == '':
logging.warning('Failed to get the next mod patch operation schedule')
return schedule_dict

namespaces = {'module-management': 'urn:huawei:yang:huawei-module-management'}


node_path = "module-management:module-management/module-management:operation-schedules/
module-management:operation-schedule"
root_elem = etree.fromstring(rsp_data)
elems = root_elem.findall(node_path, namespaces)
if elems is None:
return schedule_dict

for elem in elems:


phase_node = elem.find('module-management:phase', namespaces)
if phase_node is not None and phase_node.text == phase_item:
status_node = elem.find('module-management:status', namespaces)
if status_node is not None:
schedule_dict['status'] = status_node.text
schedule_node = elem.find('module-management:schedule', namespaces)
if schedule_node is not None:
schedule_dict['schedule'] = schedule_node.text
break
return schedule_dict

def _check_set_startup_schedule(self, set_type, phase_item, retry_times=10):

print_ztp_log(f"Now checking {set_type} is complete or not...", LOG_INFO_TYPE)


func_dict = {
SET_PATCH: self._get_patch_progress,
SET_MOD_PATCH: self._get_mod_patch_progress
}

if set_type not in func_dict.keys():


logging.warning('Unknown check startup type')
return ERR

ret = ERR
cnt = 0
while cnt < retry_times:
schedule_dict = func_dict[set_type](phase_item=phase_item)
status = schedule_dict.get('status')
schedule = schedule_dict.get('schedule')

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 218


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

print_ztp_log(f"Now schedule is {schedule}, status is {status}...", LOG_INFO_TYPE)


if schedule == "100" and status == "successful":
ret = OK
break
elif schedule == "100" and status == "failed":
break
else:
cnt += 1
sleep(10)
sleep(10)
return ret

@ops_conn_operation
def patch_active_proc(self, patch_name='', ops_conn=None):
"""patch active"""
if patch_name is None:
return OK

curpat, _ = self.get_startup_info_by_type(FILE_TYPE_PAT)
if curpat is not None:
cli.patch_delete_all()

uri = '/restconf/operations/huawei-patch:load-patch'
req_template = string.Template('''
<input>
<name>$patchName</name>
<load-type>run</load-type>
</input>
''')
req_data = req_template.substitute(patchName=patch_name)
ret, _, _ = ops_conn.create(uri, req_data)
if ops_return_result(ret):
raise OPIExecError('Failed to execute the patch active operation.')

ret = self._check_set_startup_schedule(set_type=SET_PATCH, phase_item="load-patch",


retry_times=MAX_TIMES_GET_STARTUP)
return ret

@ops_conn_operation
def mod_patch_active_proc(self, module_name='', ops_conn=None):
"""MOD active"""
if module_name is None:
return OK

uri = '/restconf/operations/huawei-module-management:install-module'
req_template = string.Template('''
<input>
<name>$fileName</name>
</input>
''')
req_data = req_template.substitute(fileName=module_name)
ret, _, _ = ops_conn.create(uri, req_data)
if ops_return_result(ret):
raise OPIExecError('Failed to execute the mod active operation.')

ret = self._check_set_startup_schedule(set_type=SET_MOD_PATCH, phase_item="install-module",


retry_times=MAX_TIMES_GET_STARTUP)
return ret

@ops_conn_operation
def feature_plugin_active_proc(self, feature_name='', ops_conn=None):
"""feature plugin active"""
if feature_name is None:
return OK

uri = '/restconf/operations/huawei-software:install-feature-software'
req_template = string.Template('''
<input>
<name>$fileName</name>

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 219


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

</input>
''')
req_data = req_template.substitute(fileName=feature_name)
ret, _, _ = ops_conn.create(uri, req_data)
if ops_return_result(ret):
raise OPIExecError('Failed to execute the feature plugin active operation.')
sleep(30)
return ret

@ops_conn_operation
def license_active_proc(self, license_name='', ops_conn=None):
"""license active"""
if license_name is None:
return OK

uri = '/restconf/operations/huawei-license:license-active'
req_template = string.Template('''
<input>
<filename>$licenseName</filename>
</input>
''')
req_data = req_template.substitute(licenseName=license_name)
ret, _, _ = ops_conn.create(uri, req_data)
if ops_return_result(ret):
raise OPIExecError('Failed to execute the license active operation.')
return ret

def file_effective_proc(self, file_info_list, file_name_dict):


"""Effect file"""
print_ztp_log("Activation will be performed.", LOG_INFO_TYPE)
active_startup_func_dict = {
FILE_TYPE_PAT : self.patch_active_proc,
FILE_TYPE_MOD : self.mod_patch_active_proc,
FILE_TYPE_LIC : self.license_active_proc,
FILE_TYPE_FEATURE_PLUGIN : self.feature_plugin_active_proc
}

for file_info in file_info_list:


effective_mode = file_info.get('*EFFECTIVE_MODE')
if effective_mode != EFFECTIVE_MODE_NO_REBOOT:
continue

file_type = file_info.get('*TYPE').lower()
func = active_startup_func_dict.get(file_type)
if func is None:
continue

logging.info(f"{file_type} active...")
ret = func(file_name_dict.get(file_type))
if ret == ERR:
raise ZTPErr(f"Active {file_type} file failed")

def check_filename_length(filename, filetype):


"""File name length check

Input parameters: filename, filetype


Return value: OK/ERR
Function usage: Check whether the name of the downloaded file exceeds the maximum length allowed
by the system.
If so, an error is returned and the file is not downloaded.
"""
file_name = os.path.basename(filename)
if filetype == FILE_TYPE_SOFTWARE:
if len((file_name)) > FELMNAMME_127 or len(file_name) < FELMNAMME_4:
logging.error('%s too long or too short, please check!',file_name)
return ERR
return OK
elif filetype == FILE_TYPE_CFG:

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 220


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

if len((file_name)) > FELMNAMME_64 or len(file_name) < FELMNAMME_5:


logging.error('%s too long, please check!', file_name)
return ERR
return OK
elif filetype == FILE_TYPE_PAT:
if len((file_name)) > (FELMNAMME_64 - 1) or len(file_name) < FELMNAMME_5:
logging.error('%s too long or too short, please check!', file_name)
return ERR
return OK
elif filetype == FILE_TYPE_MOD:
if len((file_name)) > (FELMNAMME_64 - 1) or len(file_name) < FELMNAMME_5:
logging.error('%s too long or too short, please check!', file_name)
return ERR
return OK
elif filetype == FILE_TYPE_FEATURE_PLUGIN:
if len((file_name)) > FELMNAMME_127 or len(file_name) < FELMNAMME_4:
logging.error('%s too long or too short, please check!', file_name)
return ERR
return OK
elif filetype == FILE_TYPE_LIC:
if len((file_name)) > FELMNAMME_127 or len(file_name) < FELMNAMME_5:
logging.error('%s too long or too short, please check!', file_name)
return ERR
return OK
else:
if len((file_name)) > FELMNAMME_64 or len(file_name) < 3:
logging.error('%s too long or too short, please check!', file_name)
return ERR
return OK

@ops_conn_operation
def get_disk_free_size(path='', ops_conn=None):
"""return list of disk free size, types = 0: main, types = 1: slave"""
uri = '{}'.format('/restconf/data/huawei-file-operation:file-operation/disk-usages')
disk_info = 0
req_data = None
ret, _, rsp_data = ops_conn.get(uri, req_data)
if ops_return_result(ret) or rsp_data == '':
logging.error('Failed to get disk free size')
return disk_info

root_elem = etree.fromstring(rsp_data)
namespaces = {'file-operation': 'urn:huawei:yang:huawei-file-operation'}
for disk_usage in root_elem.findall("file-operation:disk-usage", namespaces):
elem = disk_usage.find("file-operation:path", namespaces) # Path of the file system partition
if elem is None or elem.text is None:
continue

if not elem.text.lower().startswith(path):
continue

elem = disk_usage.find("file-operation:free-size", namespaces)


if elem is not None:
disk_info = int(elem.text)
return disk_info

return disk_info

@ops_conn_operation
def del_recycle_bin(ops_conn=None):
"""Delete files from the recycle bin."""
uri = '{}'.format('/restconf/operations/huawei-file-operation:reset-recycle-bin')
req_data = '''\
<input>
<reset-type>all</reset-type>
</input>
'''

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 221


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

ret, _, _ = ops_conn.create(uri, req_data)


if ops_return_result(ret):
logging.error('Delete recycle bin failed.')
return ERR
return OK

def space_enough(masterspace, slavespace, filespace, slave):


if int(filespace) < int(masterspace):
if slave:
if int(filespace) < int(slavespace):
return OK
else:
return ERR
return OK
else:
return ERR

def get_space_mode_str(space_clear):
check_print = 'undefined'
if space_clear in ['0', None]:
check_print = 'no cleanup'
elif space_clear == '1':
check_print = 'normal cleanup'
elif space_clear == '2':
check_print = 'deep cleanup'
return check_print

def check_devices_space(devices_res_space, need_space):


for key in devices_res_space.keys():
if need_space > devices_res_space.get(key):
return ERR
return OK

def check_if_space_enough(master_path, cc_image, all_devices_paths, softwareflag):


current_image_size = get_file_size(file_path=(os.path.join(master_path, cc_image)))
# Required space
if softwareflag == False:
need_space = 40000
else:
need_space = 40000 + current_image_size
# Obtain the available space of the master and slave MPUs.
devices_res_space = get_residual_space(all_devices_paths)
ret = check_devices_space(devices_res_space, need_space)
return ret, need_space

def get_residual_space(all_devices_paths=[]):
"""Obtain the available space of the master and slave MPUs."""
devices_space = {}
if len(all_devices_paths) == 0:
return devices_space
for path in all_devices_paths:
path_space = get_disk_free_size(path)
devices_space.update({path : path_space})

return devices_space

def get_mpus_files_list(all_devices_paths):

print_ztp_log("Get all file list.", LOG_INFO_TYPE)


devices_files = {}
for path in all_devices_paths:
device_path_list = get_file_list(path)
devices_files.update({path : device_path_list})

return devices_files

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 222


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

def get_devices_images_files(files_list, cc_image):


"""Obtain the system software packages on the master and slave MPUs."""

print_ztp_log("Obtain the list of system software packages.", LOG_INFO_TYPE)


images_files_list = {}
files_removes_device_images = {}
for key in files_list.keys():
files_removes_images = []
images_in_devices = []
for filename in files_list.get(key):
if os.path.splitext(filename)[-1] in ['.cc', '.CC'] and filename != os.path.basename(cc_image):
images_in_devices.append(filename)
if filename != os.path.basename(cc_image):
files_removes_images.append(filename)
images_files_list.update({key:images_in_devices})
files_removes_device_images.update({key:files_removes_images})

return files_removes_device_images, images_files_list

def get_space_of_files_list(files_list):

all_files_space = {}
space_temp = 0
for key in files_list.keys():
for filename in files_list.get(key):
space_temp = space_temp + get_file_size(os.path.join(key, filename))
all_files_space.update({key:space_temp})
space_temp = 0
return all_files_space

def check_space(startup_info, cc_image, softwareflag):

master_path, slave_paths, _ = get_home_path()


all_devices_paths = slave_paths
all_devices_paths.append(master_path)
space_clear_strategy = startup_info['SPACE_CLEAR']
ret, need_space = check_if_space_enough(master_path, cc_image, all_devices_paths, softwareflag)
if ret == OK:
print_ztp_log("The space enough, continue ztp...", LOG_INFO_TYPE)
return OK

if space_clear_strategy not in [ZTP_SPACE_CLEAR_NO_NEED, ZTP_SPACE_CLEAR_NORMAL,


ZTP_SPACE_CLEAR_DEEP]:
print_ztp_log("Invalid space clear strategy.", LOG_WARN_TYPE)
return ERR

print_ztp_log(f"The space clear strategy is {get_space_mode_str(space_clear_strategy)}.",


LOG_INFO_TYPE)
if space_clear_strategy == ZTP_SPACE_CLEAR_NO_NEED:
print_ztp_log("The current space is insufficient and no clearing policy is "
"configured to exit the ZTP process.", LOG_ERROR_TYPE)
return ERR

# Clear the recycle bin.


del_recycle_bin()

devices_res_space = get_residual_space(all_devices_paths)
ret = check_devices_space(devices_res_space, need_space)
if ret == OK:
print_ztp_log("Empty recycle bin, the space enough and continue ztp...", LOG_INFO_TYPE)
return OK

devices_files_list = get_mpus_files_list(all_devices_paths)
files_removes_device_images, devices_images_list = get_devices_images_files(devices_files_list, cc_image)
all_files_list_space = get_space_of_files_list(files_removes_device_images)
all_images_list_space = get_space_of_files_list(devices_images_list)
space_not_enough_path = []
space_enough_del = []

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 223


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

for image_path in all_images_list_space.keys():


if (all_images_list_space.get(image_path) + devices_res_space.get(image_path) < need_space):
space_not_enough_path.append(image_path)
else:
space_enough_del.append(image_path)

need_del_all_file = {}
need_del_images_file = {}
if len(space_not_enough_path) == 0:
del_list_file(devices_images_list, LOG_FILE)
print_ztp_log("Delete the system software packages on the master, continue the ZTP process.",
LOG_INFO_TYPE)
ret, _ = check_if_space_enough(master_path, cc_image, all_devices_paths, softwareflag)
if ret == ERR:
for path in space_enough_del:
need_del_all_file.update({path : files_removes_device_images.get(path)})
del_list_file(need_del_all_file, LOG_FILE)
elif len(space_not_enough_path) != 0 and space_clear_strategy == ZTP_SPACE_CLEAR_NORMAL:
print_ztp_log(f"The space of the following {space_not_enough_path} devices is insufficient.",
LOG_ERROR_TYPE)
return ERR
else:
for path in space_not_enough_path:
if all_files_list_space.get(path) + devices_res_space.get(path) < need_space:
print_ztp_log(f"The space of the following {path} devices is insufficient.", LOG_ERROR_TYPE)
return ERR
need_del_all_file.update({path : files_removes_device_images.get(path)})

for path in space_enough_del:


need_del_images_file.update({path : devices_images_list.get(path)})

del_list_file(need_del_all_file, LOG_FILE)
del_list_file(need_del_images_file, LOG_FILE)
print_ztp_log("Delete files on master and standby, continue the ZTP process.", LOG_INFO_TYPE)

# If some files fail to be deleted, check the space after the delete operation.
ret, _ = check_if_space_enough(master_path, cc_image, all_devices_paths, softwareflag)
if ret == ERR:
logging.error('Try to clean file failed, the space is still not enough.')
return ret

def check_software_in_ini(startup_info):
softwareflag = False
length = len(startup_info['FILE_INFO'])
for _len in range(length):
file_type = startup_info['FILE_INFO'][_len]['*TYPE']
if file_type.upper() == 'SOFTWARE':
softwareflag = True
return softwareflag

def check_file_sha256(path, file_sha256):


"""SHA256 verification on files"""
if file_sha256 is None:
return OK

# Calculate the SHA256 value of the file.


ret, calc_sha256 = sha256_calc(path, False)
if ret != OK or calc_sha256 != file_sha256:
return ERR
return OK

def download_xml(lic_list_file_path, lic_list_file_sha256, startup_info):


"""Download the XML file to be parsed for license-based batch deployment."""
local_path_file = None
lic_list_file_name = os.path.basename(lic_list_file_path)

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 224


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

if lic_list_file_name is not None:


url = os.path.join(startup_info['*FILESERVER'], lic_list_file_path)
local_path_file = lic_list_file_name
logging.info('Download "{}" for get license.'.format(lic_list_file_name))
file_delete(file_path=local_path_file)
ret = check_filename_length(url, FILE_TYPE_LIC)
if ret != OK:
raise ZTPErr("The file length is incorrect.")
if DHCP_TYPE == 'DHCPv4':
ret = download_file(url, local_path_file, MAX_TIMES_RETRY_DOWNLOAD)
else:
ret = download_v6_file(url, local_path_file, MAX_TIMES_RETRY_DOWNLOAD)
if ret is ERR or not file_exist(file_path=os.path.basename(url)):
logging.error('Failed to download file "{}"'.format(lic_list_file_name))
file_delete(file_path=local_path_file)
return ERR
logging.info('Download file "{}" successfully.'.format(lic_list_file_name))
# Add the downloaded file to the list of downloaded files.
ZTP_DOWNLOAD_FILE_LIST.append(lic_list_file_name)
# SHA256 verification
ret = check_file_sha256(local_path_file, lic_list_file_sha256)
if ret != OK:
logging.error('{} sha256 check error'.format(lic_list_file_name))
return ERR

return OK

def ztp_get_file_list(startup, sys_info, startup_info):


"""Obtain the list of files to be downloaded."""
file_list = []
file_name_dict = {}.fromkeys((FILE_TYPE_SOFTWARE, FILE_TYPE_CFG, FILE_TYPE_PAT, FILE_TYPE_MOD,
FILE_TYPE_LIC, FILE_TYPE_FEATURE_PLUGIN))
for file_info in startup_info.get('FILE_INFO'):
file_name = file_info.get('*FILENAME')
file_type = file_info.get('*TYPE')
if file_name is not None:
_file_name = file_name
_file_path = file_info.get('PATH')
_file_sha256 = file_info.get('SHA256')
_file_type = file_type.lower()
if file_type == FILE_TYPE_SOFTWARE:
if _file_name in [startup.current.image, startup.next.image]:
print_ztp_log('The name of image file to be downloaded is the same as the image file of
system.',
LOG_WARN_TYPE)
continue
file_name_dict[FILE_TYPE_SOFTWARE] = _file_name
elif file_type == FILE_TYPE_CFG:
if _file_name in [startup.current.config, startup.next.config]:
print_ztp_log('The name of config file to be downloaded is the same as the config file of
system.',
LOG_WARN_TYPE)
continue
file_name_dict[FILE_TYPE_CFG] = _file_name
elif file_type == FILE_TYPE_PAT:
if _file_name in [startup.current.patch, startup.next.patch]:
print_ztp_log('The name of patch file to be downloaded is the same as the patch file of
system.',
LOG_WARN_TYPE)
continue
file_name_dict[FILE_TYPE_MOD] = _file_name
elif file_type == FILE_TYPE_FEATURE_PLUGIN:
if _file_name in startup.current.feature_plugin_list or _file_name in
startup.next.feature_plugin_list:
raise ZTPErr('The name of feature_image file to be downloaded is the same as the
feature_image file of system.')
file_name_dict[FILE_TYPE_FEATURE_PLUGIN] = _file_name
elif file_type == FILE_TYPE_LIC:

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 225


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

if file_info.get('ISBATCHPROCESS') != '1':
file_name_dict[FILE_TYPE_LIC] = _file_name
else:
# Batch process licenses.
ret = download_xml(_file_path, _file_sha256, startup_info)
if ret is not OK:
raise ZTPErr('Download license list file error.')

_license_name, _license_sha256 = get_license_from_xml(sys_info['esn'], _file_name)


if _license_name is None:
raise ZTPErr('Failed to get license file from license list file.')

_file_name_real = os.path.basename(_license_name)
_file_path = _license_name.lstrip('/')
_file_sha256 = _license_sha256

logging.info('Get license from {} succesfully.(name={}, sha256={})'\


.format(_file_name, _file_name_real, _license_sha256))

file_name_dict[FILE_TYPE_LIC] = _file_name_real
else:
pass

file_list.append((_file_path, _file_sha256, _file_type))

return file_list, file_name_dict

def ztp_file_download(filelist, startup_info, slave):


"""Download all files in the file list."""
if startup_info.get('DIRECTORY') is None:
direct = ''
else:
direct = startup_info.get('DIRECTORY')

chg_flag = False

print_ztp_log(f"Ztp download filelist: {filelist}.", LOG_INFO_TYPE)


for _file in filelist:
local_path_file = None
if _file[0] is not None:
_file_path = _file[0]
_file_name = os.path.basename(_file_path)
_file_sha256 = _file[1]
_file_type = _file[2]
url = os.path.join(startup_info['*FILESERVER'], direct, _file_path)
local_path_file = _file_name
logging.info('The system begins to download {} file.'.format(_file_name))
slog.syslog('The system begins to download {} file.'.format(_file_name), ops.INFORMATIONAL,
ops.SYSLOG)
file_delete(file_path=local_path_file)
ret = check_filename_length(url, _file_type)
if ret != OK:
raise ZTPErr("The file length is incorrect.")
if DHCP_TYPE == 'DHCPv4':
ret = download_file(url, local_path_file, MAX_TIMES_RETRY_DOWNLOAD)
else:
ret = download_v6_file(url, local_path_file, MAX_TIMES_RETRY_DOWNLOAD)
if ret is ERR or not file_exist(file_path=os.path.basename(url)):
logging.error('Failed to download file "{}"'.format(_file_name))
slog.syslog('Failed to download file "{}"'.format(_file_name), ops.ERROR, ops.SYSLOG)
return ERR, chg_flag
logging.info('Download file "{}" successfully.'.format(_file_name))
slog.syslog('Download file "{}" successfully.'.format(_file_name), ops.INFORMATIONAL, ops.SYSLOG)
# Add the downloaded file to the list of downloaded files.
ZTP_DOWNLOAD_FILE_LIST.append(_file_name)
# SHA256 check
ret = check_file_sha256(local_path_file, _file_sha256)
if ret != OK:
slog.syslog('{} sha256 check error'.format(_file_name), ops.ERROR, ops.SYSLOG)

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 226


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

logging.error('{} sha256 check error'.format(_file_name))


return ERR, chg_flag
chg_flag = True
if slave:
if (flash_home_path_slave is None or len(flash_home_path_slave) <= 0):
return ERR
print_ztp_log(f"The {_file_name} is being copied to the other master board, please wait...",
LOG_INFO_TYPE)
for path in flash_home_path_slave:
file_path_slave = os.path.join(path, _file_name)
_ = file_delete(f"{file_path_slave}.tmp")
ret = file_delete(file_path_slave)
if ret != OK:
return ERR
ret = copy_file(src_path=local_path_file, dest_path=file_path_slave)
if ret != OK:
return ERR

return OK, chg_flag

@ops_conn_operation
def get_syslog_config(ops_conn=None, ip_type='ipv4'):
"""Obtain the log server configuration."""
ip_addresses = []
uri = '/restconf/data?fields=/huawei-syslog:syslog/servers/server(ipaddress)'
req_data = None
ret, _, rsp_data = ops_conn.get(uri, req_data)
if ops_return_result(ret) or rsp_data == '':
logging.warning('Failed to get information of syslog servers.')
return ip_addresses

root_elem = etree.fromstring(rsp_data)
namespaces = {
'syslog': 'urn:huawei:yang:huawei-syslog',
}

servers = root_elem.find("syslog:syslog/syslog:servers", namespaces)


if servers is not None:
for server in servers.findall("syslog:server", namespaces):
elem = server.find("syslog:ipaddress", namespaces)
if (elem is not None) and (elem.text is not None) and elem.text == ip_type:
ip_addresses.append(elem.text)

return ip_addresses

@ops_conn_operation
def set_syslog_config(ops_conn=None, ip_addresses=[], ipaddr_type='ipv4', syslog_trans=''):
"""Configure the log server."""
syslog_tran = syslog_trans.lower()
if syslog_tran in ['tcp']:
for ip_address in ip_addresses:
xpath = '/restconf/data/huawei-syslog:syslog/servers/server'
str_temp = string.Template('''\
<server>
<ip-type>$ip_type</ip-type>
<ipaddress>$ip_addr</ipaddress>
<is-default-vpn>true</is-default-vpn>
<vrf-name>_public_</vrf-name>
<level>debugging</level>
<port>514</port>
<facility>local2</facility>
<channel-id>2</channel-id>
<timestamp>UTC</timestamp>
<transport-mode>$syslog_tran</transport-mode>
</server>
''')
req_data = str_temp.substitute(ip_type=ipaddr_type, ip_addr=ip_address, syslog_tran=syslog_tran)
ret, _, _ = ops_conn.set(xpath, req_data)

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 227


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

if ops_return_result(ret):
raise OPIExecError('Failed to change the transmission mode')
return OK

@ops_conn_operation
def get_addr_by_hostname(ops_conn=None, host='', addr_type='1'):
"""Convert the host name into an IP address."""

print_ztp_log("Get IP address by host name...", LOG_INFO_TYPE)


xpath = '{}{}'.format('/restconf/data/huawei-dns:dns/query-host-ips/query-host-ip=', host)
req_data = None
ret, _, rsp_data = ops_conn.get(xpath, req_data)
if ops_return_result(ret):
raise OPIExecError('Failed to get address by host name')

root_elem = etree.fromstring(rsp_data)
uriTmp = '{}'.format('/ip-address')
uriTmp = uriTmp.replace('/', '/dns:')
mpath = uriTmp[1:]
namespaces = {'dns': 'urn:huawei:yang:huawei-dns'}
elem = root_elem.find(mpath,namespaces)
if elem is None:
raise OPIExecError('Failed to get IP address by host name')

return elem.text

@ops_conn_operation
def get_ipv6_addr_by_hostname(ops_conn=None, host=''):
print_ztp_log("Get IPv6 address by host name...", LOG_INFO_TYPE)
xpath = '{}{}'.format('/restconf/data/huawei-dns:dns/query-host-ipv6s/query-host-ipv6=', host)
req_data = None
ret, _, rsp_data = ops_conn.get(xpath, req_data)
if ops_return_result(ret):
raise OPIExecError('Failed to get IPv6 address by host name')

root_elem = etree.fromstring(rsp_data)
namespaces = {'dns': 'urn:huawei:yang:huawei-dns'}
elem = root_elem.find('dns:ipv6-address', namespaces)
if elem is None:
raise OPIExecError('Failed to get IPv6 address by host name.')

return elem.text

@ops_conn_operation
def ztp_status_set(envValue=ZTP_STATUS_END, ops_conn=None):
"""Set the ZTP process status.

input: envValue int Environment variable value, which can be true or false
output: ret int Operation result
"""
logging.info("Set the value of envZtpStatus to {} .".format(envValue))
if envValue not in ['true', 'false']:
logging.error("The envValue:%s is invalid, not in ['true', 'false']!" % envValue)
return ERR

xpath = '{}'.format('/restconf/operations/huawei-ztp:set-enable-status')
str_temp = string.Template('''\
<input>
<enable>$enableSta</enable>
</input>
''')
req_data = str_temp.substitute(enableSta=envValue)
ret, _, _ = ops_conn.create(xpath, req_data)
if ops_return_result(ret):
raise OPIExecError('Failed to set the value of envZtpStatus.')

return OK

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 228


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

@ops_conn_operation
def ztp_status_get(ops_conn=None):
"""Obtain the ZTP process status.

output: ret int Operation result


envValue str Environment variable value obtained
"""
logging.info("Get the value of envZtpStatus...")
xpath = '{}'.format('/restconf/data?fields=/huawei-ztp:ztp/status(enable)')
req_data = None
ret, _, rsp_data = ops_conn.get(xpath, req_data)
if ret == http.client.NOT_FOUND:
return ERR, ''
if ops_return_result(ret) or rsp_data == '':
raise OPIExecError('Failed to get the value of envZtpStatus.')

root_elem = etree.fromstring(rsp_data)
namespaces = {'data':'urn:ietf:params:xml:ns:yang:ietf-restconf', 'ztp':'urn:huawei:yang:huawei-ztp'}
uriTmp = '{}'.format('/ztp/status/enable')
uriTmp = uriTmp.replace('/', '/ztp:')
mpath = uriTmp[1:]
elem = root_elem.find(mpath, namespaces)
if elem is None:
return ERR, ''

return OK, elem.text

@ops_conn_operation
def has_slave_mpu(ops_conn=None, mpu_slot={}):
"""Whether device has slave MPU, returns a bool value"""

print_ztp_log("Test whether device has slave MPU...", LOG_INFO_TYPE)


uri = '/restconf/data/huawei-devm:devm/physical-entitys/physical-entity=mpuModule'
req_data = None

has_slave = False
ret, _, rsp_data = ops_conn.get(uri, req_data)
if ops_return_result(ret) or rsp_data == '':
raise OPIExecError('Failed to get the device slave information')

# Re-construct a packet for parsing.


rsp_data_tmp = rsp_data.replace('<?xml version="1.0" encoding="UTF-8"?>','')
rsp_data_tmp = rsp_data_tmp.replace(' xmlns="urn:huawei:yang:huawei-devm"','')
rsp_data_tmp = '{}{}{}'.format(
'<physical-entitys xmlns="urn:huawei:yang:huawei-devm">', rsp_data_tmp,
'</physical-entitys>')
root_elem = etree.fromstring(rsp_data_tmp)

namespaces = {'devm': 'urn:huawei:yang:huawei-devm'}


for entity in root_elem.findall("devm:physical-entity", namespaces):
elem = entity.find("devm:standby-state", namespaces)
if (elem is not None) and (elem.text is not None):
if elem.text.lower().find('slave') >= 0:
has_slave = True
elem = entity.find("devm:position", namespaces)
if elem is not None:
mpu_slot['slave'] = elem.text
elif elem.text.lower().find('master') >= 0:
elem = entity.find("devm:position", namespaces)
if elem is not None:
mpu_slot['master'] = elem.text

logging.info("device has slave: {} .".format(str(has_slave)))

return has_slave

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 229


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

@ops_conn_operation
def get_system_info(ops_conn=None):
"""Get system info, returns a dict"""

print_ztp_log("Get the system information...", LOG_INFO_TYPE)


uri = '/restconf/data?fields=/huawei-system:system/system-info(product-name;esn;mac;product-version)'
req_data = None
ret, _, rsp_data = ops_conn.get(uri, req_data)
if ops_return_result(ret) or rsp_data == '':
raise OPIExecError('Failed to get the system information.')

sys_info = {}.fromkeys(('product-name', 'esn', 'mac', 'product-version'))


root_elem = etree.fromstring(rsp_data)
namespaces = {
'system': 'urn:huawei:yang:huawei-system'
}
mpath = '{}'.format('system:system/system:system-info')
nslen = len(namespaces['system'])
elem = root_elem.find(mpath, namespaces)
if elem is not None:
for child in elem:
tag = child.tag[nslen + 2:] # skip the namespace, '{namespace}esn'
if tag in list(sys_info.keys()):
sys_info[tag] = child.text

return sys_info

def convert_file_list_info(file_list):
if not isinstance(file_list, list):
return ""
return ",".join(file_list)

def record_startup_info_to_file(startup_info, startup):


"""Record the startup information to file."""

print_ztp_log("Record the current startup information to file...", LOG_INFO_TYPE)


slog.syslog("Record the current startup information to file...", ops.INFORMATIONAL, ops.SYSLOG)
sn_value = startup_info.get('*TIME_SN')
sn_value = '' if sn_value in [None, 'DEFAULT'] else sn_value
record_info = {}.fromkeys((FILE_TYPE_SOFTWARE, FILE_TYPE_CFG, FILE_TYPE_PAT,
FILE_TYPE_MOD, FILE_TYPE_FEATURE_PLUGIN), '')

if startup.current.image is not None:


record_info[FILE_TYPE_SOFTWARE] = startup.current.image
if startup.current.config is not None:
record_info[FILE_TYPE_CFG] = startup.current.config
if startup.current.patch is not None:
record_info[FILE_TYPE_PAT] = startup.current.patch
if startup.current.mod_list is not None:
record_info[FILE_TYPE_MOD] = convert_file_list_info(startup.current.mod_list)
if startup.current.feature_plugin_list is not None:
record_info[FILE_TYPE_FEATURE_PLUGIN] = convert_file_list_info(startup.current.feature_plugin_list)

str_temp = string.Template('TIME_SN=$sn\n'
'SOFTWARE=$image_name\n' \
'CFG=$config_name\n' \
'PAT=$patch_name\n'
'MOD=$mod_list\n'
'FEATURE_IMAGE=$feature_image_name\n')

startup_info_str = str_temp.substitute(sn=sn_value,
image_name=record_info[FILE_TYPE_SOFTWARE],
config_name=record_info[FILE_TYPE_CFG],
patch_name=record_info[FILE_TYPE_PAT],
mod_list=record_info[FILE_TYPE_MOD],

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 230


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

feature_image_name=record_info[FILE_TYPE_FEATURE_PLUGIN])

try:
file_path = os.path.join(FLASH_HOME_PATH, STARTUP_INFO_FILE_NAME)
if os.path.islink(file_path) != False:
raise Exception("This is a soft link file. Please chack.")

with open(file_path, 'w', encoding='utf-8') as fhdl:


fhdl.write(startup_info_str)
os.fsync(fhdl)
os.chmod(file_path,0o660)
except Exception as reason:
logging.error(reason)
raise

def revert_file_list_info(file_info):
return file_info.split(",")

def get_startup_info_from_file():
"""Get startup information from file"""

print_ztp_log("Get the backup startup information from file...", LOG_INFO_TYPE)


sn_value = ''
startup_info_backup = {}.fromkeys((FILE_TYPE_SOFTWARE, FILE_TYPE_CFG, FILE_TYPE_PAT,
FILE_TYPE_MOD, FILE_TYPE_FEATURE_PLUGIN), None)

try:
file_path = os.path.join(FLASH_HOME_PATH, STARTUP_INFO_FILE_NAME)
if os.path.islink(file_path) != False:
raise Exception("This is a soft link file. Please chack.")

with open(file_path, 'r', encoding='utf-8') as fhdl:


fhdl.seek(0)
lines_info = fhdl.readlines()
for line in lines_info:
if line.startswith('TIME_SN='):
sn_value = line[8:-1]
elif line.startswith('SOFTWARE=') and line[9:-1] != '':
startup_info_backup[FILE_TYPE_SOFTWARE] = line[9:-1]
elif line.startswith('CFG=') and line[4:-1] != '':
startup_info_backup[FILE_TYPE_CFG] = line[4:-1]
elif line.startswith('PAT=') and line[4:-1] != '':
startup_info_backup[FILE_TYPE_PAT] = line[4:-1]
elif line.startswith('MOD=') and line[4:-1] != '':
startup_info_backup[FILE_TYPE_MOD] = revert_file_list_info(line[4:-1])
elif line.startswith('FEATURE_IMAGE=') and line[14:-1] != '':
startup_info_backup[FILE_TYPE_FEATURE_PLUGIN] = revert_file_list_info(line[14:-1])
else:
continue
except Exception as reason:
logging.error(reason)
raise

return sn_value, startup_info_backup

def set_file_effectiveMode(startup_info):
"""Set the mode for activating version files.

Traverse the information in the startup_info file and read the *EFFECTIVE_MODE field.
If it has been set, no processing is required. If it is set to None, the default
activation mode is used based on the file type. The system software package and
configuration file take effect only after the device is restarted.Therefore, only the
default activation mode can be configured for them. Activation is not required for
customized files.
"""
file_info_list = startup_info.get('FILE_INFO')

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 231


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

if not isinstance(file_info_list, list):


logging.error("Parameters is invalid.")
return

for i in range(len(file_info_list)):
file_type = file_info_list[i].get('*TYPE').lower()
effective_mode = file_info_list[i].get('*EFFECTIVE_MODE')
if effective_mode is None or file_type in [FILE_TYPE_SOFTWARE, FILE_TYPE_CFG, FILE_TYPE_LIC,
FILE_TYPE_USER] or \
(file_type in [FILE_TYPE_PAT, FILE_TYPE_MOD, FILE_TYPE_FEATURE_PLUGIN] and effective_mode
== EFFECTIVE_MODE_NO_NEED):
file_info_list[i].update({
'*EFFECTIVE_MODE': FILE_DEFAULT_EFFECTIVE_MODE.get(file_type.lower())
})

def get_license_from_xml(esn, file_path_xml):


"""Obtain the license file that matches the ESN from the license file list.

The license file name and SHA256 value of the file are returned.
"""
if not isinstance(file_path_xml, str):
logging.error("File path is invalid.")
return None, None
# Check the file name.
file_name = os.path.basename(file_path_xml)
if file_name != LICENSE_LIST_FILE_NAME:
logging.error("File name is not {}.(file_name={})"\
.format(LICENSE_LIST_FILE_NAME, file_name))
return None, None
file_path_real = os.path.join(FLASH_HOME_PATH, file_name)
# Check whether the file exists.
if not os.path.isfile(file_path_real):
logging.error("File does not exist.")
return None, None
try:
tree = etree.parse(file_path_real)
# Obtain the root node.
root = tree.getroot()
except Exception as reason:
logging.error(reason)
raise

for lic in root:


for child in lic:
if child.tag == "Esn" and child.text == esn:
lic_name = lic.get("name")
lic_sha256 = lic.get("sha256")
if lic_sha256 == '':
lic_sha256 = None
return lic_name, lic_sha256

return None, None

@ops_conn_operation
def patch_active_proc(ops_conn=None, patch_name=''):
"""Activate the patch file."""

print_ztp_log("Patch active...", LOG_INFO_TYPE)

uri = '/restconf/operations/huawei-patch:load-patch'
str_temp = string.Template('''\
<input>
<name>$patchName</name>
<load-type>run</load-type>
</input>
''')
req_data = str_temp.substitute(patchName=patch_name)

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 232


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

ret, _, _ = ops_conn.create(uri, req_data)


if ops_return_result(ret):
raise OPIExecError('Failed to execute the patch active operation.')

@ops_conn_operation
def license_active_proc(ops_conn=None, license_name=''):
"""Activate the license file."""

print_ztp_log("License active...", LOG_INFO_TYPE)


uri = '/restconf/operations/huawei-license:license-active'
str_temp = string.Template('''\
<input>
<filename>$licenseName</filename>
</input>
''')
req_data = str_temp.substitute(licenseName=license_name)
ret, _, _ = ops_conn.create(uri, req_data)
if ops_return_result(ret):
raise OPIExecError('Failed to execute the license active operation.')

@ops_conn_operation
def delete_startup_patch_file(ops_conn=None):
"""Delete patch file for system to startup"""

print_ztp_log("Delete the patch file...", LOG_INFO_TYPE)


uri = '/restconf/operations/huawei-patch:delete-patch'
req_data = '''\
<input>
<delete-type>all</delete-type>
</input>
'''
# it is a action operation, so use create for HTTP POST
ret, _, rsp_data = ops_conn.create(uri, req_data)
if ops_return_result(ret):
logging.error("delete_startup_patch_file failed, rsp_data = \n{}".format(rsp_data))
raise OPIExecError('Failed to delete patch.')

@ops_conn_operation
def get_active_intime(ops_conn=None):
"""Obtain the number of seconds to be delayed based on the activation delay configured in the .ini
file."""
time_sys = '0:0'
uri = '/restconf/data?fields=/huawei-tm:tm/date-and-time(current-time)'
req_data = None
ret, _, rsp_data = ops_conn.get(uri, req_data)
if ops_return_result(ret) or rsp_data == '':
logging.warning("Get active in time failed!")
return time_sys

root_elem = etree.fromstring(rsp_data)
namespaces = {'tm': 'urn:huawei:yang:huawei-tm'}
elem = root_elem.find('tm:tm/tm:date-and-time/tm:current-time', namespaces)
if elem is not None:
text_list = re.findall(".*T(.*)Z.*", elem.text)
if text_list is not None:
text_list_member = text_list[0]
time_sys = text_list_member[0:5]
return time_sys

def get_active_intime_delay(active_in_time):

if not isinstance(active_in_time, str):


return None

if re.match(r'^(0[0-9]|1[0-9]|2[0-3]|[0-9])\:(0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]|[0-9])$',

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 233


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

active_in_time):
# The time is entered, for example, 23:59.
h_intime, m_intime = active_in_time.split(":")
m_intime_count = int(h_intime) * ONEMINUTE + int(m_intime)

time_now = get_active_intime()
h_timenow, m_timenow = time_now.split(":")
m_timenow_count = int(h_timenow) * ONEMINUTE + int(m_timenow)

if m_intime_count > m_timenow_count:


time_sleep = m_intime_count - m_timenow_count
return time_sleep * ONEMINUTE
else:
time_sleep = m_intime_count + 24 * ONEMINUTE - m_timenow_count
return time_sleep * ONEMINUTE
else:
logging.warning("The field of ACTIVE_INTIME is invalid!")
return None

def get_delay_time_sec(active_delay_time):

if not isinstance(active_delay_time, str):


return None

if re.match(r'(\d+)$', active_delay_time):
# The delay is entered, for example, 60.
delay_time_sec = int(active_delay_time)
if delay_time_sec > (ONEHOUR * 24):
logging.error("The active delay time over 24 hours!")
delay_time_sec = ONEHOUR * 24
return delay_time_sec
else:
logging.warning("The field of ACTIVE_DELAYTIME is invalid!")
return None

def get_delay_time(active_delay_time, active_in_time):


"""Obtain the number of seconds to be delayed based on the activation delay or file effective time
configured in the .ini file."""

print_ztp_log("Get activation delay time...", LOG_INFO_TYPE)


if active_delay_time is None and active_in_time is None:
return 0

delay_time = get_delay_time_sec(active_delay_time)
if delay_time is not None:
return delay_time

delay_time = get_active_intime_delay(active_in_time)
if delay_time is not None:
return delay_time

logging.warning("Activation delay time is invalid!")


return None

def sha256_calc(file_path, is_config_file=False):


"""Calculate the SHA256 value.

input: file_path str Path of the file for which the SHA256 needs to be calculated.
is_config_file int Indicates whether a file is an intermediate file.
output: ret int Indicates whether the calculation is successful.
outStr str SHA256 value.
"""
def read_chunks(fhdl):
"""read chunks"""
chunk = fhdl.read(8096)
while chunk:

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 234


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

yield chunk
chunk = fhdl.read(8096)
else:
fhdl.seek(0)

if not isinstance(file_path, str):


logging.error("File path is invalid.")
return ERR, ""

file_name = os.path.basename(file_path)
file_path_real = os.path.join(FLASH_HOME_PATH, file_name)
if os.path.islink(file_path_real) != False:
raise Exception("This is a soft link file. Please chack.")

if not os.path.exists(file_path_real):
logging.error("File does not exist.")
return ERR, ""

if is_config_file not in [True, False]:


logging.error("The flag of config file is invalid. "
"is_config_file = {}".format(is_config_file))
return ERR, ""

sha256_obj = sha256()
with open(file_path_real, "rb") as fhdl:
if is_config_file is True:
# skip the first line
fhdl.seek(0)
fhdl.readline()
for chunk in read_chunks(fhdl):
sha256_obj.update(chunk)

sha256_value = sha256_obj.hexdigest()
return OK, sha256_value

def get_file_info_str(file_info_list):
if len(file_info_list) == 0:
return None

str_tmp = ''
for file_info in file_info_list:
str_tmp = '{}{} {}'.format(str_tmp, '\n', str(file_info))

return str_tmp

def get_file_infos_from_user_config(user_config_dict, dict_name_str):


cnt = 0
_key = None
for key in list(user_config_dict.keys()):
file_infos = user_config_dict.get(key)
if len(file_infos) != 0:
cnt += 1
_key = key

if cnt == 1:
return _key, user_config_dict.get(_key)
elif cnt > 1:
logging.warning("User configuration information {} is invalid, "
"please check!".format(dict_name_str))
return None, None
else:
return None, None

def print_product_infos(sys_info):
product_name = sys_info.get('product-name')
product_esn = sys_info.get('esn')

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 235


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

product_mac = sys_info.get('mac')

print_ztp_log(f"Product info of the device: product-name = '{product_name}', esn = '{product_esn}', "


f"mac = '{product_mac}'.", LOG_INFO_TYPE)

def set_startup_info_from_user_config(startup_info, sys_info):


startup_info.update({'*FILESERVER': FILE_SERVER})
startup_info.update({'*TIME_SN': TIME_SN})
startup_info.update({'SPACE_CLEAR': SPACE_CLEAR})
startup_info.update({'SYSLOG_INFO': SYSLOG_INFO})
startup_info.update({'DIRECTORY': ''})
startup_info.update({'ACTIVE_DELAYTIME': ACTIVE_DELAYTIME})
startup_info.update({'ACTIVE_INTIME': ACTIVE_INTIME})

file_info_list = []
print_product_infos(sys_info)

# REMOTE_IMAGE
if len(REMOTE_IMAGE) != 0:
_key, _infos = get_file_infos_from_user_config(REMOTE_IMAGE, 'REMOTE_IMAGE')
if _infos != None:
image_info = _infos.get(sys_info.get(_key))
if image_info != None:
image_path = image_info.get('path')
if image_path != None:
file_info = {}.fromkeys(('*FILENAME', '*TYPE', '*EFFECTIVE_MODE', 'ISBATCHPROCESS',
'SHA256', 'PATH'))
file_info['*FILENAME'] = os.path.basename(image_path)
file_info['PATH'] = image_path.lstrip('/')
if file_info['*FILENAME'] not in [None, '']:
file_info['*TYPE'] = FILE_TYPE_SOFTWARE
file_info['*EFFECTIVE_MODE'] = EFFECTIVE_MODE_REBOOT
file_info['ISBATCHPROCESS'] = '0'
file_info['SHA256'] = image_info.get('sha256')
if file_info['SHA256'] == '':
file_info['SHA256'] = None

if ((VRPVER is not None) and (sys_info['product-version'].lower() == VRPVER.lower())):


logging.warning('The downloaded package version is the same as the current device
package version, '
'package download will be skipped')
pass
else:
file_info_list.append(file_info)

# REMOTE_CONFIG
if len(REMOTE_CONFIG) != 0:
_key, _infos = get_file_infos_from_user_config(REMOTE_CONFIG, 'REMOTE_CONFIG')
if _infos != None:
config_info = _infos.get(sys_info.get(_key))
if config_info != None:
config_path = config_info.get('path')
if config_path != None:
file_info = {}.fromkeys(('*FILENAME', '*TYPE', '*EFFECTIVE_MODE', 'ISBATCHPROCESS',
'SHA256', 'PATH'))
file_info['*FILENAME'] = os.path.basename(config_path)
file_info['PATH'] = config_path.lstrip('/')
if file_info['*FILENAME'] not in [None, '']:
file_info['*TYPE'] = FILE_TYPE_CFG
file_info['*EFFECTIVE_MODE'] = EFFECTIVE_MODE_REBOOT
file_info['ISBATCHPROCESS'] = '0'
file_info['SHA256'] = config_info.get('sha256')
if file_info['SHA256'] == '':
file_info['SHA256'] = None
file_info_list.append(file_info)

# REMOTE_PATCH
if len(REMOTE_PATCH) != 0:
_key, _infos = get_file_infos_from_user_config(REMOTE_PATCH, 'REMOTE_PATCH')

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 236


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

if _infos != None:
patch_info = _infos.get(sys_info.get(_key))
if patch_info != None:
patch_path = patch_info.get('path')
if patch_path != None:
file_info = {}.fromkeys(('*FILENAME', '*TYPE', '*EFFECTIVE_MODE', 'ISBATCHPROCESS',
'SHA256', 'PATH'))
file_info['*FILENAME'] = os.path.basename(patch_path)
file_info['PATH'] = patch_path.lstrip('/')
if file_info['*FILENAME'] not in [None, '']:
file_info['*TYPE'] = FILE_TYPE_PAT
file_info['*EFFECTIVE_MODE'] = patch_info.get('effective_mode')
if file_info['*EFFECTIVE_MODE'] in [None, '']:
file_info['*EFFECTIVE_MODE'] = EFFECTIVE_MODE_NO_REBOOT
file_info['ISBATCHPROCESS'] = '0'
file_info['SHA256'] = patch_info.get('sha256')
if file_info['SHA256'] == '':
file_info['SHA256'] = None
file_info_list.append(file_info)
# REMOTE_PATCH
if len(REMOTE_MOD) != 0:
_key, _infos = get_file_infos_from_user_config(REMOTE_MOD, 'REMOTE_MOD')
if _infos != None:
patch_info = _infos.get(sys_info.get(_key))
if patch_info != None:
patch_path = patch_info.get('path')
if patch_path != None:
file_info = {}.fromkeys(('*FILENAME', '*TYPE', '*EFFECTIVE_MODE', 'ISBATCHPROCESS',
'SHA256', 'PATH'))
file_info['*FILENAME'] = os.path.basename(patch_path)
file_info['PATH'] = patch_path.lstrip('/')
if file_info['*FILENAME'] not in [None, '']:
file_info['*TYPE'] = FILE_TYPE_MOD
file_info['*EFFECTIVE_MODE'] = patch_info.get('effective_mode')
if file_info['*EFFECTIVE_MODE'] in [None, '']:
file_info['*EFFECTIVE_MODE'] = EFFECTIVE_MODE_NO_REBOOT
file_info['ISBATCHPROCESS'] = '0'
file_info['SHA256'] = patch_info.get('sha256')
if file_info['SHA256'] == '':
file_info['SHA256'] = None
file_info_list.append(file_info)

if len(REMOTE_FEATURE_PLUGIN) != 0:
_key, _infos = get_file_infos_from_user_config(REMOTE_FEATURE_PLUGIN,
'REMOTE_FEATURE_PLUGIN')
if _infos != None:
patch_info = _infos.get(sys_info.get(_key))
if patch_info != None:
patch_path = patch_info.get('path')
if patch_path != None:
file_info = {}.fromkeys(('*FILENAME', '*TYPE', '*EFFECTIVE_MODE', 'ISBATCHPROCESS',
'SHA256', 'PATH'))
file_info['*FILENAME'] = os.path.basename(patch_path)
file_info['PATH'] = patch_path.lstrip('/')
if file_info['*FILENAME'] not in [None, '']:
file_info['*TYPE'] = FILE_TYPE_FEATURE_PLUGIN
file_info['*EFFECTIVE_MODE'] = patch_info.get('effective_mode')
if file_info['*EFFECTIVE_MODE'] in [None, '']:
file_info['*EFFECTIVE_MODE'] = EFFECTIVE_MODE_NO_REBOOT
file_info['ISBATCHPROCESS'] = '0'
file_info['SHA256'] = patch_info.get('sha256')
if file_info['SHA256'] == '':
file_info['SHA256'] = None
file_info_list.append(file_info)

# REMOTE_LICLIST
license_info = REMOTE_LICLIST
license_path = license_info.get('path')

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 237


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

if license_path != None:
file_info = {}.fromkeys(('*FILENAME', '*TYPE', '*EFFECTIVE_MODE', 'ISBATCHPROCESS', 'SHA256',
'PATH'))
file_info['*FILENAME'] = os.path.basename(license_path)
file_info['PATH'] = license_path.lstrip('/')
if file_info['*FILENAME'] not in [None, '']:
file_info['*TYPE'] = FILE_TYPE_LIC
file_info['*EFFECTIVE_MODE'] = EFFECTIVE_MODE_NO_REBOOT
file_info['ISBATCHPROCESS'] = '1'
file_info['SHA256'] = license_info.get('sha256')
if file_info['SHA256'] == '':
file_info['SHA256'] = None
file_info_list.append(file_info)

# REMOTE_USER
if len(REMOTE_USER) != 0:
_key, _infos = get_file_infos_from_user_config(REMOTE_USER, 'REMOTE_USER')
if _infos != None:
user_info_list = _infos.get(sys_info.get(_key))
if user_info_list != None:
for user_info in user_info_list:
if len(file_info_list) >= 9:
logging.warning("Too many user files, please check!")
break
user_path = user_info.get('path')
if user_path != None:
file_info = {}.fromkeys(('*FILENAME', '*TYPE', '*EFFECTIVE_MODE', 'ISBATCHPROCESS',
'SHA256', 'PATH'))
file_info['*FILENAME'] = os.path.basename(user_path)
file_info['PATH'] = user_path.lstrip('/')
if file_info['*FILENAME'] not in [None, '']:
file_info['*TYPE'] = FILE_TYPE_USER
file_info['*EFFECTIVE_MODE'] = EFFECTIVE_MODE_NO_NEED
file_info['ISBATCHPROCESS'] = '0'
file_info['SHA256'] = user_info.get('sha256')
if file_info['SHA256'] == '':
file_info['SHA256'] = None
file_info_list.append(file_info)

print_ztp_log(f"The device deployment file infos: {get_file_info_str(file_info_list)}.", LOG_INFO_TYPE)


startup_info.update({'FILE_INFO': file_info_list})

def check_parameter(aset):
seq = ['&', '>', '<', '"', "'", "|", '`', '$', ';', '(', ')', '[', ']', '{', '}', '~', '*', '?']
if aset:
for c in seq:
if c in aset:
return True
return False

def check_number(aset):
nums = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0']
if aset:
for num in aset:
if num not in nums:
return True
return False

def check_filename_and_extension(startup_info):
file_info_list = startup_info.get('FILE_INFO')
for file_info in file_info_list:
file_name = file_info.get('*FILENAME')
file_type = file_info.get('*TYPE')
if file_name not in ['', None] and check_parameter(file_name):
raise ZTPErr('Invalid filename of {} file, the name should not contain: {} {} {} {} {} {} {} {} .'\
.format(file_type, '&', '>', '<', '"', "'", "|", '`', '$'))

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 238


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

_, ext = os.path.splitext(file_name)
if (file_type != FILE_TYPE_USER) and (ext.lower() not in FILE_EXTENSION.get(file_type)):
raise ZTPErr('Invalid filename extension of {} file.'.format(file_type))

def check_SN_config(startup_info):
sn = startup_info.get('*TIME_SN')
if not isinstance(sn, str):
raise ZTPErr('Invalid type of TIME_SN value.')
if len(sn) != 14:
raise ZTPErr('Invalid length of TIME_SN value.')
if check_number(sn):
raise ZTPErr('Invalid value of TIME_SN, the value should only contain numbers.')

def check_user_config(startup_info):
check_filename_and_extension(startup_info)
check_SN_config(startup_info)

def check_starupinfo_txt(startup_info, startup):


if file_exist(file_path=STARTUP_INFO_FILE_NAME):
# Obtain information from the file.
sn_from_file, startup_info_last = get_startup_info_from_file()
sn_from_py = TIME_SN
if sn_from_py == sn_from_file:
# Obtain the current deployment status flag.
ret, ztp_status = ztp_status_get()
if ret is OK:
if ztp_status == str(ZTP_STATUS_END):
# Exit the ZTP process. The device starts.
logging.warning('The current device was successfully deployed last time, '
'and the TIME_SN configured this time is the same as that of the last time. '
'Please check!')
raise ZTPAbort('There is no need to continue!')
elif ztp_status == str(ZTP_STATUS_RUNNING):
# The device restarts unexpectedly during the last deployment. Rollback is required.
startup.rollback_startup_info(
startup_info_last.get(FILE_TYPE_SOFTWARE),
startup_info_last.get(FILE_TYPE_CFG),
startup_info_last.get(FILE_TYPE_PAT),
startup_info_last.get(FILE_TYPE_MOD),
startup_info_last.get(FILE_TYPE_FEATURE_PLUGIN))
global system_startupInfo_state
system_startupInfo_state = SYSTEM_STARUPINFO_END
raise ZTPRollback('Startup info rollback successfully.')
else:
flag = 0
flag1 = 0
ret, ztp_status = ztp_status_get()
if ret is OK and ztp_status == str(ZTP_STATUS_END):
for file_info in startup_info.get('FILE_INFO'):
file_name = file_info.get('*FILENAME')
file_type = file_info.get('*TYPE')
if file_type in [FILE_TYPE_SOFTWARE, FILE_TYPE_PAT]:
flag += 1
if file_name == startup.current.image or file_name == startup.current.patch:
logging.warning('The file {} is the same as the current of device.'.format(file_name))
flag1 += 1

if flag1 > 0:
record_startup_info_to_file(startup_info, startup)
if flag == flag1:
logging.warning('The current device was successfully deployed last time, '
'and the system software or patch configured this time '
'is the same as that of the current device. Please check!')
raise ZTPAbort('There is no need to continue!')
else:
logging.warning('The current device is successfully started last time. '

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 239


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

'The system software package and patch in the intermediate file for '
'this deployment are the same as those of the current device. Please check.')
raise ZTPErr('The intermediate file system software package or patch is the same as '
'the device system software package or patch!')

def check_if_reboot_needed(startup_info):
file_info_list = startup_info.get('FILE_INFO')
if not isinstance(file_info_list, list):
logging.error("The type of FILE_INFO is invalid.")
return True

reboot_flag = False
for i in range(len(file_info_list)):
effective_mode = file_info_list[i].get('*EFFECTIVE_MODE')
if effective_mode == EFFECTIVE_MODE_REBOOT:
reboot_flag = True
break

return reboot_flag

@ops_conn_operation
def set_master_key(masterkey='', ops_conn=None):
"""set masterkey"""

print_ztp_log('Now set master key...', LOG_INFO_TYPE)


is_master_key = ops.opscharacterEncode(masterkey)
uri = '{}'.format('/restconf/operations/huawei-masterkey:set-masterkey')
if is_master_key == '':
req_data = """<input> </input>"""
else:
req_template = string.Template('''
<input>
<new-masterkey>$newmasterkey</new-masterkey>
</input>
''')
req_data = req_template.substitute(newmasterkey=is_master_key)
ret, _, rsp_data = ops_conn.create(uri, req_data)
if ops_return_result(ret):
return ERR, rsp_data
return OK, ''

def record_clear_master_key_to_file():
"""Record the startup information to file."""

print_ztp_log("Record clear master key to file...", LOG_INFO_TYPE)


try:
file_path = os.path.join(FLASH_HOME_PATH, SET_MASTER_FILE_NAME)

if os.path.islink(file_path) != False:
raise Exception("This is a soft link file. Please chack.")

with open(file_path, 'w', encoding='utf-8') as fhdl:


os.fsync(fhdl)
os.chmod(file_path,0o660)
except Exception as reason:
logging.error(reason)
raise

def copy_mod_file_to_dest(mod_name):
if mod_name is None:
return OK

src_file_path = f'flash:/{mod_name}'
dest_file_path = f'flash:/$_install_mod/{mod_name}'
ret = file_delete(dest_file_path)

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 240


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

if ret != OK:
return ERR
ret = copy_file(src_file_path, dest_file_path)
if ret != OK:
return ERR
return OK

def check_addr(address):
try:
version = ipaddress.ip_address(address).version
if version == 4:
return 'DHCPv4'
elif version == 6:
return 'DHCPv6'
else:
return None
except Exception as e:
return None

def check_filserver_dhcp_type(url):
url_tuple = urlparse(url)
ipaddr = url_tuple.hostname
cur_type = check_addr(ipaddr)
return cur_type

def clean_download_temp_file(file_path):
ret1 = file_delete(file_path)
ret2 = file_delete(f"{file_path}.tmp")
if ret1 != OK or ret2 != OK:
return ERR
return OK

def main_proc():
"""Main processing"""

print_ztp_log("Start ztp_script...", LOG_INFO_TYPE)


sys_info = get_system_info()
startup = Startup()
mpu_slot = {}.fromkeys(('master', 'slave'))
slave = has_slave_mpu(mpu_slot=mpu_slot) # Check whether a slave MPU exists.

# Generate startup information based on the user configuration.


startup_info = {}
set_startup_info_from_user_config(startup_info, sys_info)

# Check the user input configuration.


check_user_config(startup_info)

# Configure the log server based on the configured log transfer protocol.
syslog_trans_protocol = startup_info.get('SYSLOG_INFO')
addr_type = 'ipv4'
if DHCP_TYPE == 'DHCPv6':
addr_type = 'ipv6'
ip_addresses = get_syslog_config(ip_type = addr_type)
set_syslog_config(ip_addresses=ip_addresses, ipaddr_type=addr_type, syslog_trans=syslog_trans_protocol)

check_starupinfo_txt(startup_info, startup)
global system_startupInfo_state
system_startupInfo_state = SYSTEM_STARUPINFO_END

# Check the flash memory space.


softwareflag = check_software_in_ini(startup_info)
ret = check_space(startup_info, startup.current.image, softwareflag)
if ret is ERR:
slog.syslog("Error: the space is not enough.", ops.ERROR, ops.SYSLOG)

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 241


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

raise ZTPErr('The space is not enough.')

# Set the ZTP deployment status to 0.


ztp_status_set(ZTP_STATUS_RUNNING)
# Record the current startup and configuration information to a file for new deployment.
record_startup_info_to_file(startup_info, startup)

url = startup_info['*FILESERVER']
cur_dhcp_type = check_filserver_dhcp_type(url)
if cur_dhcp_type is not None and cur_dhcp_type != DHCP_TYPE:
print_ztp_log("The IP version in ini file is inconsistant with bootfile server.", LOG_ERROR_TYPE)
return ERR

# Obtain the version file list and names.


file_list, file_name_dict = ztp_get_file_list(startup, sys_info, startup_info)
slog.syslog('The device of system mac %s, ESN %s begins to download file.' %(sys_info['mac'],
sys_info['esn']), ops.INFORMATIONAL, ops.SYSLOG)
# Activate the file.
delay_time_sec = get_delay_time(startup_info.get('ACTIVE_DELAYTIME'),
startup_info.get('ACTIVE_INTIME'))

if delay_time_sec == None:
slog.syslog("Get delay time failed.", ops.INFORMATIONAL, ops.SYSLOG)
return ERR
# Download the version files.
ret, chg_flag= ztp_file_download(file_list, startup_info, slave)
if ret != OK or chg_flag is False:
return ERR

# Set the mode for activating the file.


set_file_effectiveMode(startup_info)
global system_reboot_needed
system_reboot_needed = check_if_reboot_needed(startup_info)

image_name = file_name_dict.get(FILE_TYPE_SOFTWARE)
config_name = file_name_dict.get(FILE_TYPE_CFG)
patch_name = file_name_dict.get(FILE_TYPE_PAT)
mod_name = file_name_dict.get(FILE_TYPE_MOD)
feature_name = file_name_dict.get(FILE_TYPE_FEATURE_PLUGIN)
# Activate the file.
print_ztp_log(f"After {delay_time_sec} seconds activation will be performed.", LOG_INFO_TYPE)
slog.syslog("After {} seconds activation will be performed.".format(delay_time_sec),
ops.INFORMATIONAL, ops.SYSLOG)
sleep(delay_time_sec)
# copy the mod file.
ret = copy_mod_file_to_dest(mod_name)
if ret != OK:
logging.error("Failed to copy mod file to destination path.")
return ERR

# set masterkay
if master_exportcfg is None and config_name is not None and is_set_master is not None :
ret, _= set_master_key(is_set_master)
_, nextcfg = startup.get_startup_info_by_type(FILE_TYPE_CFG)
if nextcfg is not None:
startup._del_startup_config_file()
if ret == OK:
print_ztp_log('Now set master key success...', LOG_INFO_TYPE)
else:
raise ZTPErr('Failed to set master key.')

if is_clear_master == True:
record_clear_master_key_to_file()
ZTP_DOWNLOAD_FILE_LIST.append(SET_MASTER_FILE_NAME)

file_info_list = startup_info.get('FILE_INFO')
if not isinstance(file_info_list, list):
logging.error("Parameters is invalid.")

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 242


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

return ERR

for file_info in file_info_list:


effective_mode = file_info.get('*EFFECTIVE_MODE')
if effective_mode != EFFECTIVE_MODE_NO_REBOOT:
continue

file_type = file_info.get('*TYPE').lower()
if file_type == FILE_TYPE_PAT:
patch_name = None

if file_type == FILE_TYPE_MOD:
mod_name = None

if file_type == FILE_TYPE_FEATURE_PLUGIN:
feature_name = None

startup.set_exportcfg(master_exportcfg)
# Specify the version files for the next startup.
startup.set_startup_info(image_name, config_name, patch_name, mod_name, feature_name, slave)
global system_file_state
system_file_state = SYSTEM_FILE_SETTING_END

startup.file_effective_proc(file_info_list, file_name_dict)

return OK

def main(download_file_list=[], logfile_name=''):


"""The main function of user script. It is called by ZTP frame, so do not remove or change this function.

Args:
Raises:
Returns: user script processing result
"""
try:
global LOG_FILE
LOG_FILE = logfile_name
global flash_home_path_master
global flash_home_path_slave
flash_home_path_master, flash_home_path_slave, _= get_home_path()
ret = main_proc()

except ZTPAbort as reason:


raise ZTPAbort(reason)

except ZTPRollback as reason:


raise ZTPRollback(reason)

except OPIExecError as reason:


print_ztp_log(f"OPI execute error: {str(reason)}", LOG_ERROR_TYPE)
ret = ERR

except ZTPErr as reason:


print_ztp_log(f"ZTP error: {str(reason)}", LOG_ERROR_TYPE)
ret = ERR

except IOError as reason:


print_ztp_log(f"{str(reason)}", LOG_ERROR_TYPE)
ret = ERR

except Exception as reason:


print_ztp_log(f"{str(reason)}", LOG_ERROR_TYPE)
traceinfo = traceback.format_exc()
logging.error(traceinfo)
ret = ERR

finally:
download_file_list.extend(ZTP_DOWNLOAD_FILE_LIST)

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 243


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

return ret, (system_file_state, system_startupInfo_state, system_reboot_needed)

if __name__ == "__main__":
main()

NOTE

In Table 6-14, the bold content in the Script Content column can be modified based on
the actual running environment.

Table 6-14 Script description


Script Content Description
#sha256="cb203b72b6070f535eaff14c7c7d984cf SHA256 verification code of the script,
28c58052fadf1b484f80258b07fc8c9"
which is used to check the integrity of
the downloaded script.
NOTE
Before an SHA256 verification code is
generated, do not add the #sha256= field
to the script. Instead, #sha256= should be
added to the beginning of the script after
the SHA256 verification code is generated.
A script without an SHA256 verification
code can still be executed.

REMOTE_IMAGE = { Path, file name, and SHA256


'product-name': {
'S16700' : {
verification code of the system
'path': '/image/software_file_name.cc', software.
'sha256': '',
}, ● path: If this field is left empty, no
}, system software needs to be
'esn': {}, loaded.
'mac': {}
} ● sha256: SHA256 verification code,
which can be left empty.
NOTE
Only one of product-name, esn, and mac
can be specified and these fields cannot be
all empty.
● When product-name is used for
deployment, the value of product-
name can be queried using the display
version command. In the command
output, S16700 in "Version xxx (S16700
xxx)" is the value of product-name.
● When esn is used for deployment, the
value of esn can be queried using the
display device esn command.
● When mac is used for deployment, the
value of mac can be queried using the
display bridge mac-address command.
The MAC address, which is case
sensitive, must be the same as that
queried on the device, for example,
00e0-fc12-3456.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 244


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Script Content Description


REMOTE_CONFIG = { Path, file name, and SHA256
'product-name': {},
'esn': {
verification code of the configuration
'BARCODETEST20200620' : { file.
'path': '/config/conf_file_name.cfg',
'sha256': '', ● path: If this field is left empty, no
}, configuration file needs to be
}, loaded.
'mac': {}
} ● sha256: SHA256 verification code,
which can be left empty.
NOTE
Only one of product-name, esn, and mac
can be specified and these fields cannot be
all empty.
● When product-name is used for
deployment, the value of product-
name can be queried using the display
version command. In the command
output, S16700 in "Version xxx (S16700
xxx)" is the value of product-name.
● When esn is used for deployment, the
value of esn can be queried using the
display device esn command.
● When mac is used for deployment, the
value of mac can be queried using the
display bridge mac-address command.
The MAC address, which is case
sensitive, must be the same as that
queried on the device, for example,
00e0-fc12-3456.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 245


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Script Content Description


REMOTE_PATCH = { Path, file name, activation mode, and
'product-name': {},
'esn': {},
SHA256 verification code of the PAT
'mac': { patch file.
'00E0-FC12-3456' : {
'path': '/patch/pat_file_name.pat', ● path: If this field is left empty, no
'effective_mode': patch file needs to be loaded.
EFFECTIVE_MODE_NO_REBOOT,
'sha256': '', ● effective_mode: activation mode. If
}, this field is left empty, a patch file is
} activated without the need of
}
device restart.
– EFFECTIVE_MODE_NO_REBOOT:
A patch file is activated without
the need of device restart.
– EFFECTIVE_MODE_REBOOT: A
patch file is activated upon
restart.
● sha256: SHA256 verification code,
which can be left empty.
NOTE
Only one of product-name, esn, and
mac can be specified and these fields
cannot be all empty.
● When product-name is used for
deployment, the value of product-
name can be queried using the
display version command. In the
command output, S16700 in
"Version xxx (S16700 xxx)" is the
value of product-name.
● When esn is used for deployment,
the value of esn can be queried
using the display device esn
command.
● When mac is used for deployment,
the value of mac can be queried
using the display bridge mac-
address command. The MAC
address, which is case sensitive,
must be the same as that queried
on the device, for example, 00e0-
fc12-3456.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 246


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Script Content Description


REMOTE_MOD = { Path, file name, activation mode, and
'product-name': {},
'esn': {},
SHA256 verification code of the MOD
'mac': { patch file.
'00E0-FC12-3456' : {
'path': '/patch/mod_file_name.MOD', ● path: If this field is left empty, no
'effective_mode': patch file needs to be loaded.
EFFECTIVE_MODE_NO_REBOOT,
'sha256': '', ● effective_mode: activation mode. If
}, this field is left empty, a patch file is
} activated without the need of
}
device restart.
– EFFECTIVE_MODE_NO_REBOOT:
A patch file is activated without
the need of device restart.
– EFFECTIVE_MODE_REBOOT: A
patch file is activated upon
restart.
● sha256: SHA256 verification code,
which can be left empty.
NOTE
Only one of product-name, esn, and
mac can be specified and these fields
cannot be all empty.
● When product-name is used for
deployment, the value of product-
name can be queried using the
display version command. In the
command output, S16700 in
"Version xxx (S16700 xxx)" is the
value of product-name.
● When esn is used for deployment,
the value of esn can be queried
using the display device esn
command.
● When mac is used for deployment,
the value of mac can be queried
using the display bridge mac-
address command. The MAC
address, which is case sensitive,
must be the same as that queried
on the device, for example, 00e0-
fc12-3456.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 247


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Script Content Description


REMOTE_FEATURE_PLUGIN = { Path, file name, activation mode, and
'product-name': {
'S16700' : {
SHA256 verification code of the
'path': 'url_file_name.ccx', feature package.
'effective_mode':
EFFECTIVE_MODE_REBOOT, ● path: If this field is left empty, no
'sha256': '', feature package file needs to be
}, loaded.
},
'esn': {}, ● effective_mode: activation mode. If
'mac': {}, this field is left empty, a feature
}
package file is activated without the
need of device restart.
– EFFECTIVE_MODE_NO_REBOOT:
A feature package file is
activated without the need of
device restart.
– EFFECTIVE_MODE_REBOOT: A
feature package file is activated
upon restart.
● sha256: SHA256 verification code,
which can be left empty.
NOTE
Only one of product-name, esn, and
mac can be specified and these fields
cannot be all empty.
● When product-name is used for
deployment, the value of product-
name can be queried using the
display version command. In the
command output, S16700 in
"Version xxx (S16700 xxx)" is the
value of product-name.
● When esn is used for deployment,
the value of esn can be queried
using the display device esn
command.
● When mac is used for deployment,
the value of mac can be queried
using the display bridge mac-
address command. The MAC
address, which is case sensitive,
must be the same as that queried
on the device, for example, 00e0-
fc12-3456.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 248


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Script Content Description


LICENSE_LIST_FILE_NAME = 'ztp_license_list.xml' License list file name. The file name
must be ***.xml, for example,
ztp_license_list.xml.
If license files are stored in a separate
directory, the license file names in the
license list file must contain paths. For
example, if the license files
LIC_file1.xml and LIC_file2.dat are
stored in /license/, the following is an
example of the license list file:
<?xml version="1.0" encoding="utf-8"
standalone="yes"?>
<Index formatVersion="1.0">
<Lic name="/license/LIC_file1.xml"
sha256="d27305447dbb1e76ea9c6f27e19be298650
3b91d8240612f9ebde708e7d1019e">
<LSN>LIC202005183TCG5M</LSN>
<Esn>102050157695</Esn>
</Lic>
<Lic name="/license/LIC_file2.dat"
sha256="6a2690e7a08e3df844ba86e1f48dc3c504a
f3b760dd0e38134771e1024fe1a5f">
<LSN>LIC202005183TCI50</LSN>
<Esn>2102311LDL0000000805</Esn>
</Lic>
</Index>

REMOTE_LICLIST = { Path and SHA256 verification code of


'path': '/license/
{}'.format(LICENSE_LIST_FILE_NAME),
the license list file.
'sha256': ● path: If this field is left empty, no
'a7638ea0a69933ac20df66ea9bf6ea301de815568
4d81fbcdf00f6ca07261d7c', license file needs to be loaded.
} ● sha256: SHA256 verification code,
which can be left empty.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 249


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Script Content Description


REMOTE_USER = { Path, name, and SHA256 verification
'product-name': {},
'esn': {
code of a customized file.
'BARCODETEST20200620' : [ ● path: If this field is left empty, no
{
'path': '', customized file is required.
'sha256': '', ● sha256: SHA256 verification code,
},
], which can be left empty.
'BARCODETEST20200000' : [ NOTE
{ Customized deployment files are
'path': '/user/ztp_user.txt',
supported. For a deployment, a maximum
'sha256': '',
}, of nine files can be used. As such, the
{ number of customized deployment files is
'path': '/user/ztp_user1.txt', limited. For example, if the system
'sha256': '', software, configuration file, patch file, and
}, customized files are involved in a
], deployment, a maximum of six customized
}, files can be added. The format of multiple
'mac': {}
customized files is as follows:
}
'BARCODETEST20200620' : [
{
'path': '/user/ztp_user.txt',
'sha256': '',
},
{
'path': '/user/ztp_user1.txt',
'sha256': '',
},
],

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 250


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Script Content Description


FILE_SERVER = 'sftp:// File server information.
sftp_user:sftp_pwd@10.1.3.2'
You can obtain deployment files from
an SFTP server.
In the IPv4 scenario, the value format
is as follows:
● The address is in sftp://
username:password@hostname:port
format.
In this format, port is optional.
In the IPv6 scenario, the value format
is as follows:
sftp://
username:password@hostname:port/
path
The value of hostname can be a
domain name or an IP address.
● If the value is a domain name, the
format is sftp://
username:password@hostname:port
/path.
● If the value is an IP address, the
format is sftp://
username:password@[address]:port
/path.
In this format, port is optional and
path specifies the directory where
deployment files are stored on the file
server.
TIME_SN = '20200526120159' Uniquely identifies a deployment in
order to prevent repeated deployment.
The value format is
yyyymmddhhmmss.
For example, this field can be set to
20200526120159, indicating 12:01:59
on 2020-05-26.
SYSLOG_INFO = 'UDP' Transport protocol used by the Syslog
server.
● TCP: Logs are transmitted using TCP.
● UDP: Logs are transmitted using
UDP.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 251


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Script Content Description


SPACE_CLEAR = Whether to automatically clean up the
ZTP_SPACE_CLEAR_NO_NEED
system storage space in the case of
space insufficiency.
● ZTP_SPACE_CLEAR_NO_NEED: The
system storage space is not cleaned
up.
● ZTP_SPACE_CLEAR_NORMAL: Only
system software among
deployment files is deleted.
● ZTP_SPACE_CLEAR_DEEP: In-depth
cleanup is performed. System
software among deployment files is
deleted first. If the available space
is still insufficient, all unnecessary
files are deleted from the flash
directory.
NOTE
In-depth cleanup involves some inherent
risks. As such, you are advised to back up
required files locally before performing in-
depth cleanup.

ACTIVE_DELAYTIME = '60' Delay for deployment to be performed.


The value is an integer that ranges
from 0 to 86400, in the unit of
seconds. If the value is greater than
86400, the value 86400 is used.
ACTIVE_INTIME = None Scheduled time for deployment to be
NOTE performed within 24 hours. The value
If both ACTIVE_DELAYTIME and format is HH:MM, where HH indicates
ACTIVE_INTIME are set, the 24-hour format, and MM indicates
ACTIVE_DELAYTIME is preferentially used.
the 60-minute format. For example,
the value 20:10 indicates that the
deployment will be performed at
20:10.
NOTE
If the configured time is earlier than the
system time of the device, the actual
deployment time is the configured time
plus 24 hours minus the current system
time. For example, if the configured time is
10:00 and the device system time is 11:00,
the deployment will be performed at 23:00.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 252


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Script Content Description


VRPVER = None System software version number.
If the current system software version
of the device is the same as the value
specified here, the device does not
download the system software from
the deployment file server.
If the current system software package
is that required for deployment, you
are advised to set this field.
DHCP_TYPE = 'DHCPv6' DHCP packet type.
DHCPv4: The current deployment
mode is intermediate file-based
deployment in IPv4 scenarios, and
DHCPv4 packets are used.
DHCPv6: The current deployment
mode is intermediate file-based
deployment in IPv6 scenarios, and
DHCPv6 packets are used.
is_set_master = Master key of a configuration file for
"""AB123xxei9e:e*)34dkeieneii21@2343\0d"""
deployment. The value is a string of 20
to 32 characters. It must contain
uppercase letters, lowercase letters,
digits, and special characters.
NOTE
● This field takes effect only when the
configuration file for deployment exists.
● The configuration file is exported from
a device, which has a master key
configured. This master key is used as
the value of this field.
● Because this field is configured, the
intermediate file contains the key in
plaintext. Therefore, you need to ensure
the security of the intermediate file.

is_clear_master = False Whether to clear the master key


configured in the .ini file.
● True: After ZTP is complete, the
device clears the master key
configured in the .ini file, and
restores the master key to the
random master key.
● False: After ZTP deployment, the
device continues to use the master
key configured in the .ini file.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 253


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

6.6.5 Configuring a DHCP Server

Context
The DHCP server uses Option parameters to carry network configuration
parameters that are required for ZTP. The device can function as a DHCP server. If
the device to be deployed and DHCP server are on different network segments,
configure a DHCP relay agent to forward DHCP packets exchanged between them.

The device sends a DHCP Discover message that carries DHCP Option parameters
when the DHCP discover phase starts in DHCPv4 scenarios. Table 6-15 describes
the DHCP Option parameters.

Table 6-16 describes the DHCPv4 Option parameters. Table 6-17 shows the
DHCPv6 Option parameters.

Table 6-18 describes the DHCP Option parameters.

Table 6-19 describes the DHCP Option parameters required in SZTP.

CAUTION

● The DHCP server does not support authentication and may be spoofed. You are
advised to use a trusted DHCP server for deployment on a secure network.
● DHCP uses a non-encrypted transmission protocol, so the user name and
password of the SFTP file server carried in DHCP Option 59, Option 66 and
Option 67 have security risks. You are advised to use this protocol on a secure
network.

Table 6-15 DHCPv4 Option parameters in a request

Optio Function Example


n

Optio Vendor ID, which "huawei CloudEngine S16700-4"


n 60 indicates the vendor
and model of a
device.

Optio Client ID, which "00e0-fc12-3456"


n 61 indicates the MAC
address of a device.

Table 6-16 DHCPv4 Option parameters for intermediate file-based ZTP

Option Mandatory or Not Function

Option 1 Yes Specifies the subnet


mask of the IP address.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 254


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Option Mandatory or Not Function

Option 3 Yes Specifies the egress


gateway of the DHCP
client.

Option 6 No Specifies the IP address


of the DNS server.
A DNS server is required
if a domain name (for
example, www.ztp.com)
is specified as the host
name of the
intermediate file server.
If an IP address is
specified as the host
name of the
intermediate file server,
no DNS server is
required.

Option 7 No Specifies the IPv4


address of the Syslog
server.

Option 66 No Specifies the host name


of the intermediate file
server.
The file server must be
an SFTP server, whose
address is in sftp://
username:password@hos
tname:port format.
In this format, port is
optional and hostname
can be set to a domain
name or an IP address. If
hostname is set to a
domain name, a DNS
server is required.
NOTE
● The configured server
URL cannot contain
forward slashes (/) or
number signs (#).
● The domain name of
the SFTP server is in
the standard URL
format.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 255


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Option Mandatory or Not Function

Option 67 Yes Specifies the name of


the intermediate file.
The value format is
path/filename, whereby:
● path may or may not
contain the host
name of the
intermediate file
server. For example,
the value can be /
script/ztp_script.py
without a host name,
or sftp://
sftp_user:Hyx_Hy123
4@10.1.3.2/
ztp_script.py with a
host name. If the path
without a host name
is used, you must set
Option 66.
● filename can be
ztp***.ini or ztp***.py,
and has a maximum
length of 64
characters.
NOTE
The configured
intermediate file name
cannot contain forward
slashes (/) or number signs
(#).

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 256


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Table 6-17 DHCPv6 Option parameters for intermediate file-based ZTP


Option Mandatory or Not Function

Option 59 Yes Specifies the host name


of the intermediate file
server.
The intermediate file
server must be an SFTP
file server whose address
format is as follows:
sftp://
username:password@hos
tname:port/path/
filename
The value of hostname
can be a domain name
or an IP address.
● If the value is a
domain name, the
format is sftp://
username:password@
hostname:port/path/
filename and a DNS
server needs to be
deployed.
● If the value is an IP
address, the format is
sftp://
username:password
@[address]:port/path/
filename.
In this format, port is
optional and path
specifies the path for
storing the intermediate
file on the file server.
filename can be ***.ini or
***.py, and has a
maximum length of 64
characters.
NOTE
● The configured server
URL cannot contain
forward slashes (/) or
number signs (#).
● The domain name of
the SFTP server is in the
standard URL format.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 257


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Option Mandatory or Not Function

Option 23 No Specifies the IPv6


address of the DNS
server.
A DNS server is required
if a domain name (for
example, www.ztp.com)
is specified as the host
name of the bootstrap
server. If an IP address is
specified as the host
name of the
intermediate file server,
no DNS server is
required.

Option 17 (suboption 2) No Specifies the IPv6


address of the Syslog
server.

Table 6-18 DHCP Option parameters for Option parameter-based ZTP


Option Mandatory or Not Function

Option 1 Yes Specifies the subnet mask


of the IP address.

Option 3 Yes Specifies the egress


gateway of the DHCP
client.

Option 6 No Specifies the IP address of


the DNS server.
A DNS server is required
if a domain name (for
example, www.ztp.com) is
specified as the host
name of the intermediate
file server. If an IP address
is specified as the host
name of the intermediate
file server, no DNS server
is required.

Option 7 No Specifies the IP address of


the Syslog server.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 258


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Option Mandatory or Not Function

Option 66 No Specifies the host name


of the deployment file
server.
The deployment file
server must be an SFTP
server, whose address is
in sftp://
username:password@host
name:port format.
In this format, port is
optional and hostname
can be set to a domain
name or an IP address. If
hostname is set to a
domain name, a DNS
server is required.
NOTE
● The configured server
URL cannot contain
forward slashes (/) or
number signs (#).
● The domain name of
the SFTP server is in the
standard URL format.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 259


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Option Mandatory or Not Function

Option 67 Yes Specifies the name of the


deployment configuration
file. You can specify a file
path. The specified path
and file name can
contain a maximum of 69
characters and cannot
contain spaces or special
characters.
The value format is path/
filename, whereby:
● path may or may not
contain the host name
of the deployment file
server. For example,
the value can be /
path_name/filename
without a host name,
or sftp://
username:password@h
ostname/filename
with a host name. If
the path without a
host name is used, you
must set Option 66.
The value of hostname
can be a domain name
or an IP address. If
hostname is set to a
domain name, a DNS
server is required.
● filename can have an
extension name of .cfg
or .zip. and has a
maximum of 64
characters.
NOTE
● The configured server
URL cannot contain
forward slashes (/) or
number signs (#).

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 260


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Option Mandatory or Not Function

Option 145 No Specifies the system


software, version number,
patch file, or masterkey
file. A file path can be
specified. If no path is
specified, the root path
on the deployment file
server is used by default.
The format is as follows:
vrpfile=VRPFILENAME;vrpver=VRP
VERSION;patchfile=PATCHFILENA
ME;masterfile=MASTERFILE;

● vrpfile: system
software name,
including the file path
and file name. The
value is a string of 4 to
69 characters. The
system software
package name
excluding the file path
can contain a
maximum of 64
characters.
● vrpver: system
software version.
● patchfile: patch file
name, including the
path and file name.
The value is a string of
5 to 69 characters. The
patch file name
excluding the file path
can contain a
maximum of 63
characters
● masterfile: masterkey
file name, including
the file path and file
name. The value is a
string of 5 to 32
characters.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 261


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Option Mandatory or Not Function

Option 146 No Specifies the information


about a specified action,
which can be actions
taken when the storage
space is insufficient and
the delay for a file to
take effect. It contains
the following subfields:
● opervalue: indicates
whether to delete the
system software from
the file system if the
storage space is
insufficient. The value
0 indicates that the
system software will
not be deleted, and
the value 1 indicates
that the system
software will be
deleted. The default
value of this subfield is
0.
● delaytime: indicates
the delay for a
downloaded file to
take effect. The unit is
second. The default
value of this subfield is
0.
● intime: indicates the
time when a file takes
effect. The value
ranges from 00:00 to
23:59.
NOTE
● The maximum delay for
a file to take effect is
one day (86400
seconds). A delay longer
than one day is counted
as one day.
● If both delaytime and
intime are configured,
delaytime takes effect.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 262


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Table 6-19 DHCP Option parameters for SZTP


Option Mandatory or Not Function

Option 1 Yes Specifies the subnet


mask of the IP address.

Option 3 Yes Specifies the egress


gateway of the DHCP
client.

Option 6 No Specifies the IP address


of the DNS server.
A DNS server is required
if a domain name (for
example, www.ztp.com)
is specified as the host
name of the
intermediate file server.
If an IP address is
specified as the host
name of the
intermediate file server,
no DNS server is
required.

Option 7 No Specifies the IP address


of the Syslog server.

Option 143 Yes Specifies the bootstrap


server address list.
NOTE
This field must be
configured using the
option 143 hex sub-hex-
string command.

Procedure
Step 1 Configure the DHCP server.
Step 2 (Optional) Configure the DHCP relay agent.
NOTE

If a Huawei device is used as the DHCP relay agent, see "DHCPv4 Configuration" or
"DHCPv6 Configuration" in CLI Configuration Guide > IP Address and Service Configuration.
If a third-party device is used as the DHCP relay agent, see the operation guide of the third-
party DHCP server and DHCP relay agent.

----End

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 263


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

6.6.6 (Optional) Configuring a Bootstrap Server

Context
Huawei devices do not provide the bootstrap server capability. Therefore, a third-
party bootstrap server needs to be deployed. For details about how to configure
the third-party bootstrap server, see the operation guide of the third-party
bootstrap server.

Before configuring the bootstrap server, you must obtain the ownership voucher of
the device to be deployed by referring to the following process:

● Send the root certificate of the bootstrap server to Huawei technical support
engineers.
● Huawei then issues the ownership voucher of the device to be deployed based
on the root certificate of the bootstrap server and the ESN of the device.
● Huawei technical support engineers send the ownership voucher to you.

Procedure
Step 1 Log in to Huawei PKI website and download the Huawei level-2 CA certificate of
the device to be deployed.

Step 2 Install the Huawei level-2 CA certificate on the bootstrap server.

Step 3 Obtain the ownership voucher issued by Huawei for the ZTP device to be
deployed.

Step 4 Install the ownership voucher on the bootstrap server.

Step 5 Configure the bootstrap server.

For SZTP, you need to create and upload bootstrapping data on the bootstrap
server. Bootstrapping data is a set of data obtained by the device from the
bootstrap server during SZTP. For details, see RFC 8572.

The following is an example of the interaction process between the device to be


deployed and the bootstrap server:

The device to be deployed requests bootstrapping data:


POST:/restconf/operations/ietf-sztp-bootstrap-server:get-bootstrapping-data
Content-Type: application/yang.data+xml
<input xmlns="urn:ietf:params:xml:ns:yang:ietf-sztp-bootstrap-server">
<signed-data-preferred/>
</input>

The bootstrap server replies with bootstrapping data.


Content-Type: application/yang.data+xml
<output xmlns="urn:ietf:params:xml:ns:yang:ietf-sztp-bootstrap-server">
<conveyed-information>base64encodedvalue==</conveyed-information>
<owner-certificate>base64encodedvalue==</owner-certificate>
<ownership-voucher>base64encodedvalue==</ownership-voucher>
</output>

Bootstrapping data contains the following parts:

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 264


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

1. Conveyed information: contains the bootstrapping information required by the


device to be deployed, that is, redirect information or onboarding information
(only one type of the information can be carried).
ietf-sztp-conveyed-info example of the YANG model:
yang-data conveyed-information:
+-- (information-type)
+--:(redirect-information)
| +-- redirect-information
| +-- bootstrap-server* [address]
| +-- address inet:host
| +-- port? inet:port-number
| +-- trust-anchor? cms
+--:(onboarding-information)
+-- onboarding-information
+-- boot-image
| +-- os-name? string
| +-- os-version? string
| +-- download-uri* inet:uri
| +-- image-verification* [hash-algorithm]
| +-- hash-algorithm identityref
| +-- hash-value yang:hex-string
+-- configuration-handling? enumeration
+-- pre-configuration-script? script
+-- configuration? binary
+-- post-configuration-script? script
– Redirect information: is used to redirect a device to another bootstrap
server. The redirect information contains a list of bootstrap servers, as
well as the host name, optional port, and optional trust anchor certificate
used by the device to authenticate the bootstrap server.
Example:
<conveyed-information xmlns="urn:ietf:params:xml:ns:yang:ietf-sztp-conveyed-info">
<redirect-information>
<bootstrap-server>
<address>https://sztp1.example.com</address>
<port>90</port>
<trust-anchor>base64encodedvalue==</trust-anchor>
</bootstrap-server>
<bootstrap-server>
<address>https://sztp2.example.com</address>
<port>90</port>
<trust-anchor>base64encodedvalue==</trust-anchor>
</bootstrap-server>
<bootstrap-server>
<address>https://sztp3.example.com</address>
<port>90</port>
<trust-anchor>base64encodedvalue==</trust-anchor>
</bootstrap-server>
</redirect-information>
</conveyed-information>
– Onboarding information: provides detailed information about the image,
configuration file, and other deployment files of the device to be
deployed.
Example:
<conveyed-information xmlns="urn:ietf:params:xml:ns:yang:ietf-sztp-conveyed-info">
<onboarding-information>
<boot-image>
<os-name></os-name>
<os-version></os-version>
<download-uri>https://example.com/path/to/image/cfg_file_name.cfg</download-uri>
<image-verification>
<hash-algorithm>ietf-sztp-conveyed-info:sha-256</hash-algorithm>
<hash-
value>ee0d0a46ebb2db92762eedba2c0afd9543bf3c3a983dab2e00c559ba9e62196f</hash-value>

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 265


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

</image-verification>
</boot-image>
<configuration-handling>merge</configuration-handling>
<pre-configuration-script>base64encodedvalue==</pre-configuration-script>
<configuration>base64encodedvalue==</configuration>
<post-configuration-script>base64encodedvalue==</post-configuration-script>
</onboarding-information>
</conveyed-information>

2. Owner certificate: contains the public key certificate of the customer. The
device can use this certificate to verify the signature of the conveyed
information.
3. Ownership voucher: is signed by Huawei. The customer needs to provide the
pinned domain certificate and the ESN of the device to be deployed. Huawei
generates and provides the ownership voucher for the customer. For details
about the ownership voucher, see RFC 8366.
Example:
{
"ietf-voucher:voucher": {
"created-on": "2023-05-30T19:31:42Z",
"expires-on": "2023-09-30T19:31:42Z",
"assertion": "verified",
"serial-number": "BARCODETEST20200620",
"idevid-issuer": "base64encodedvalue==",
"pinned-domain-cert": "base64encodedvalue==",
"domain-cert-revocation-checks": "false",
"last-renewal-date": ""
}
}

----End

6.6.7 Configuring a File Server


Prerequisites
There must be reachable routes between the file server and the device with
factory configurations.

Context
A file server stores the files to be downloaded to devices with factory
configurations, including intermediate files and deployment files. If a device is
configured as the file server, those files will occupy a significant amount of device
storage resources. To ensure the device performance, a third-party file server is
typically used on a ZTP network. For details about how to configure a third-party
file server, see the third-party server operation guide.
The intermediate file server and deployment file server can be the same file server.
The file server must be an SFTP file server. Currently, the device uses the SHA2
algorithm by default. The file server must also support the SHA2 algorithm. You
can run the display this include-default | include ssh command to check the
algorithms used by the client and server. At least one algorithm supported by the
file server must be the same as that supported by the device.

Procedure
Step 1 Configure the file server.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 266


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

NOTE

● If a Huawei device is used, see 7.6.1 Configuring a Device as an SFTP Server in the CLI
Configuration Guide > Basic Configuration > File System Management Configuration.
● If a third-party device is used as the file server, see the operation guide of the third-
party SFTP or HTTPS file server.
● The file server used for SZTP must have the HTTPS server capability, but Huawei devices
do not provide the capability. Therefore, a third-party server needs to be deployed. For
details about how to configure a third-party server, see the third-party server operation
guide.

Step 2 Place the intermediate file and deployment files to the working directory of the
file server.

The HTTPS deployment file server has certain requirements on the length of the
deployment file name. Ensure that the following requirements are met:

● System software: 4 to 124 characters


● Configuration file: 5 to 64 characters
● Patch file: 5 to 63 characters
● Intermediate file: 5 to 64 characters
NOTE

To ensure security of the file server, configure a unique user name for the file server and
assign the read-only permission to the user to prevent unauthorized modification of the
files. After the ZTP process is complete, disable the file server function.

----End

6.6.8 Starting DHCP-based ZTP Without a Controller

Context
A device with factory configurations has never started ZTP before. In its factory
configurations, the ZTP function is enabled by default. To start ZTP, you only need
to power on the device. The ZTP function can be disabled on a device. If you log in
to a device through the console port and disable the ZTP function when the device
starts with empty configuration, the ZTP process is terminated. To enable the
device to execute the ZTP process when it starts with empty configuration next
time, you need to enable the ZTP function.

Procedure
Step 1 Power on the device.

Step 2 (Optional) Enable the ZTP function on the device.


set ztp enable

By default, the ZTP function is enabled on a device.

To disable a device from running the ZTP process upon startup with factory
configurations, run the set ztp disable command on the device.

Step 3 (Optional) Restart the device with factory configurations.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 267


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

reboot fast

----End

6.6.9 Verifying DHCP-based ZTP Without a Controller


Procedure
Step 1 The device completes the ZTP process in about 15 minutes after it is powered on.
You can then log in to the device to check whether the startup files are the
required ones.
display startup

----End

Follow-up Procedure
If deployment fails, analyze ZTP logs on the device to determine the cause. ZTP
logs are saved in the file named ztp_YYYYMMHHMMSS.log in the flash:/
directory.

6.6.10 (Optional) Configuring the Device to Download a CA


Certificate from the Bootstrap Server

Prerequisites
The device has been deployed.

Context
In the scenario where no initial certificate is available on iMaster NCE-Campus, if
the device needs to be managed by the controller, you need to import the CA
certificate trusted by the controller to the device.
The bootstrap server stores the CA certificate trusted by the controller. Currently,
iMaster NCE-Campus integrates the function of the bootstrap server. The device
needs to download the CA certificate NCE-bootstrap.pem from the bootstrap
server and import the certificate to the default domain.
A maximum of 10 bootstrap servers can be configured for the device. The
bootstrap servers with the same IP address and VPN instance name are considered
as one bootstrap server. The interaction process between the device and bootstrap
server is as follows:
1. The device proactively establishes an HTTPS connection with a bootstrap
server.
2. The device sends a request packet to the bootstrap server to download a CA
certificate. The request packet carries the device ESN or the IP address of the
bootstrap server.
3. The bootstrap server searches for the CA certificate based on the ESN or IP
address in the request packet and sends a response packet carrying the CA
certificate to the device. The response packet also carries the device ESN or
the IP address of the bootstrap server.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 268


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

4. After receiving the response packet from the bootstrap server, the device
terminates the HTTPS connection with the bootstrap server, parses the
response packet, and verifies the validity of the certificate. If the verification
fails, the device cannot obtain the CA certificate. In this case, the device
attempts to obtain the CA certificate from the next bootstrap server. The
device will keep doing so until it successfully obtains a CA certificate.

After successfully obtaining the CA certificate NCE-bootstrap.pem from the


bootstrap server, the device automatically imports the certificate to the default
domain.

Procedure
Step 1 Enter the system view.
system-view

Step 2 Configure an SSL policy and bind it to the default domain.


ssl policy policy-name
pki-domain default
quit

Step 3 Configure the device to download a CA certificate from the bootstrap server.
ztp certificate-remote { ipv4-addr | ipv6 ipv6-addr } [ vpn-instance vpnvalue ] port portvalue ssl-policy
policyname [ verify-type esn ]

By default, the device is not configured to download a CA certificate from the


bootstrap server.

When the verify-type esn parameter is specified, a certificate is authenticated


based on the device ESN. That is, the request packet sent by the device to the
bootstrap server for downloading the CA certificate carries the device ESN. When
parsing the response packet from the bootstrap server, the device uses the ESN for
verification.

When the verify-type esn parameter is not specified, a certificate is authenticated


based on the IP address of the bootstrap server. That is, the request packet sent by
the device to the bootstrap server for downloading the CA certificate carries the IP
address of the bootstrap server. When parsing the response packet from the
bootstrap server, the device uses the IP address for verification.

After NCE-bootstrap.pem is imported to the default domain, if another CA


certificate needs to be downloaded from the bootstrap server, delete the original
certificate from the default domain and run the ztp certificate-remote command
again.

----End

6.6.11 Example for Configuring Intermediate File-based ZTP

Networking Requirements
In Figure 6-16, DeviceA and DeviceB are two unconfigured devices on the
network, and both are connected to DeviceC, which functions as the egress
gateway of DeviceA and DeviceB. There are reachable routes between DeviceC
and the DHCP server, and between DeviceC and the file server.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 269


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

The customer requires that DeviceA and DeviceB automatically load the system
software and configuration files after they are powered on to reduce labor costs
and device deployment time.
Table 6-20 lists information about DeviceA and DeviceB, and the files to be
loaded to them.

Table 6-20 Device information and files to be loaded


New Device Device ESN Files to Be Loaded

DeviceA 2102311LDL000000 ● System software: software_file.cc


0806 ● Configuration file: conf_file.cfg

DeviceB 2102311LDL000000 ● System software: software_file1.cc


0918 ● Configuration file: conf_file1.cfg

Figure 6-16 Network diagram of DHCP-based ZTP


NOTE

In this example, interface1, interface2, and interface3 represent 10GE1/0/1, 10GE1/0/2, and
10GE1/0/3, respectively.

Configuration Roadmap
The configuration roadmap is as follows:
1. Edit the intermediate file.
2. Configure the DHCP server.
3. Configure the DHCP relay agent.
4. Configure the file server.
5. Power on DeviceA and DeviceB to start the ZTP process.

Procedure
Step 1 Edit the intermediate file. For more information about the fields in an
intermediate file, see 6.6.3 Intermediate File in the INI Format and 6.6.4

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 270


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Intermediate File in the Python Format. The intermediate file in .ini format is
used as an example.
# Edit the intermediate file in .ini format by referring to Table 6-21. The file name
is ztp_script.ini. For details about the file content, see Configuration Scripts.

Table 6-21 Fields in an intermediate file in .ini format

Field Description Value

FILESERVER Address of the When deployment files


deployment file server. are obtained from an
SFTP server, the value is
sftp://
sftp_user:Hyx_Hy1234@
10.1.3.2.

TIME_SN Uniquely identifies a 20200526120159


deployment.

DEVICE_TYPE_NUM Number of device types. 2

ESN ESN of a device. The values of DeviceA


and DeviceB are as
follows:
● 2102311LDL00000008
06
● 2102311LDL00000009
18

FILETYPENUM Number of deployment 2


files to be loaded.

FILENAME_n Name of a deployment The values of DeviceA


file. are as follows:
FILENAME_1=software_fi
le.cc
FILENAME_2=cfg_file.cfg
The values of DeviceB
are as follows:
FILENAME_1=software_fi
le1.cc
FILENAME_2=cfg_file1.cf
g

TYPE_n Type of a deployment TYPE_1=SOFTWARE


file. TYPE_2=CFG

EFFECTIVE_MODE_n Activation mode. EFFECTIVE_MODE_1=0


EFFECTIVE_MODE_2=0

Step 2 Configure the DHCP server.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 271


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

# Configure the IP address pool that the DHCP server uses to allocate IP addresses
to DeviceA and DeviceB and set DHCP options by referring to Table 6-22. In this
example, a Huawei device is used as the DHCP server.

Table 6-22 DHCP server options


Option Description Value

Option 1 Subnet mask of an IP 255.255.255.0


address

Option 3 Egress gateway of a 10.1.1.1


DHCP client

Option 67 File server address and sftp://


intermediate file name sftp_user:Hyx_Hy1234@1
0.1.3.2/ztp_script.ini

<HUAWEI> system-view
[HUAWEI] sysname dhcp_server
[dhcp_server] dhcp enable
[dhcp_server] ip pool pool1
[dhcp_server-ip-pool-pool1] gateway-list 10.1.1.1
[dhcp_server-ip-pool-pool1] network 10.1.1.0 mask 255.255.255.0
[dhcp_server-ip-pool-pool1] option 67 cipher sftp://sftp_user:Hyx_Hy1234@10.1.3.2/ztp_script.ini
[dhcp_server-ip-pool-pool1] quit
[dhcp_server] vlan batch 10
[dhcp_server] interface 10ge 1/0/3
[dhcp_server-10GE1/0/3] portswitch
[dhcp_server-10GE1/0/3] port link-type trunk
[dhcp_server-10GE1/0/3] port trunk allow-pass vlan 10
[dhcp_server-10GE1/0/3] quit
[dhcp_server] interface vlanif 10
[dhcp_server-Vlanif10] ip address 10.1.2.2 24
[dhcp_server-Vlanif10] quit

Step 3 Configure the DHCP relay agent.


# Configure the DHCP relay function on DeviceC. Set the IP address of the
interface connecting DeviceC to DeviceA and DeviceB to 10.1.1.1 to configure
DeviceC as the default gateway of DeviceA and DeviceB.
<HUAWEI> system-view
[HUAWEI] sysname DeviceC
[DeviceC] vlan batch 10
[DeviceC] interface 10ge 1/0/1
[DeviceC-10GE1/0/1] portswitch
[DeviceC-10GE1/0/1] port link-type trunk
[DeviceC-10GE1/0/1] port trunk allow-pass vlan 10
[DeviceC-10GE1/0/1] port trunk pvid vlan 10
[DeviceC-10GE1/0/1] quit
[DeviceC] interface 10ge 1/0/2
[DeviceC-10GE1/0/2] portswitch
[DeviceC-10GE1/0/2] port link-type trunk
[DeviceC-10GE1/0/2] port trunk allow-pass vlan 10
[DeviceC-10GE1/0/2] port trunk pvid vlan 10
[DeviceC-10GE1/0/2] quit
[DeviceC] interface vlanif 10
[DeviceC-Vlanif10] ip address 10.1.1.1 24
[DeviceC-Vlanif10] quit
[DeviceC] dhcp enable
[DeviceC] interface vlanif 10

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 272


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

[DeviceC-Vlanif10] dhcp select relay


[DeviceC-Vlanif10] dhcp relay server-ip 10.1.2.2

Step 4 Configure the file server.

# If a device is configured as the file server, files will occupy a significant amount
of device storage resources. To ensure the device performance, a third-party file
server is typically used on a ZTP network. For details about how to configure a
third-party file server, see the third-party server operation guide.

# After configuring the file server, save the system software, configuration files,
and intermediate files to be loaded to DeviceA and DeviceB in the root directory
on the file server.

Step 5 Power on DeviceA and DeviceB to start the ZTP process.

----End

Verifying the Configuration


The devices complete the ZTP process in about 15 minutes after they are powered
on. Log in to the devices and run the display startup command to check whether
the current system software and configuration files are the required ones. The
following shows the command output of DeviceA.
<DeviceA> display startup
MainBoard:
Configured startup system software: flash:/software_file.cc
Startup system software: flash:/software_file.cc
Next startup system software: flash:/software_file.cc
Startup saved-configuration file: flash:/conf_file.cfg
Next startup saved-configuration file: flash:/conf_file.cfg
Startup paf file: default
Next startup paf file: default
Startup patch package: NULL
Next startup patch package: NULL
Startup feature software: NULL
Next startup feature software: NULL

Configuration Scripts
● DeviceC
#
sysname DeviceC
#
vlan batch 10
#
dhcp enable
#
interface Vlanif10
ip address 10.1.1.1 255.255.255.0
dhcp select relay
dhcp relay server-ip 10.1.2.2
#
interface 10GE1/0/1
port link-type trunk
port trunk pvid vlan 10
port trunk allow-pass vlan 10
#
interface 10GE1/0/2
port link-type trunk
port trunk pvid vlan 10
port trunk allow-pass vlan 10
#
return

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 273


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

● DHCP server
#
sysname dhcp_server
#
dhcp enable
#
vlan batch 10
#
ip pool pool1
gateway-list 10.1.1.1
network 10.1.1.0 mask 255.255.255.0
option 67 cipher %+%#,nl-3C^(L"r2cE=]>Z[X2Xo+<e0-S;@s"#ReXBA(h>4\4h_@P']"!
t4*26):0x31:fqp7Jz4FG'SYLo#%+%#
#
interface Vlanif10
ip address 10.1.2.2 255.255.255.0
#
interface 10GE1/0/3
port link-type trunk
port trunk allow-pass vlan 10
#
return
● Intermediate file
The intermediate file in .ini format is used as an example.
;BEGIN ZTP CONFIG
[GLOBAL CONFIG]
*FILESERVER=sftp://sftp_user:Hyx_Hy1234@10.1.3.2
*TIME_SN=20200526120159
*DEVICE_TYPE_NUM=2
SET_MASTER=
CLEAR_MASTER=
EXPORTCFG=
[DEVICE_TYPE_1 DESCRIPTION]
DEVICE_TYPE=
ESN=2102311LDL0000000806
MAC=
VRPVER=
SYSLOG_INFO=
SPACE_CLEAR=
DIRECTORY=
ACTIVE_DELAYTIME=
ACTIVE_INTIME=
*FILETYPENUM=2
*FILENAME_1=software_file.cc
*TYPE_1=SOFTWARE
*EFFECTIVE_MODE_1=0
*FILENAME_2=cfg_file.cfg
*TYPE_2=CFG
*EFFECTIVE_MODE_2=0

[DEVICE_TYPE_2 DESCRIPTION]
DEVICE_TYPE=
ESN=2102311LDL0000000918
MAC=
VRPVER=
SYSLOG_INFO=
SPACE_CLEAR=
DIRECTORY=
ACTIVE_DELAYTIME=
ACTIVE_INTIME=
*FILETYPENUM=2
*FILENAME_1=software_file1.cc
*TYPE_1=SOFTWARE
*EFFECTIVE_MODE_1=0
*FILENAME_2=cfg_file1.cfg
*TYPE_2=CFG
*EFFECTIVE_MODE_2=0
;END ZTP CONFIG

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 274


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

6.6.12 Example for Configuring Option-based ZTP


Networking Requirements
In Figure 6-17, DeviceA and DeviceB are two unconfigured devices on the
network, and both are connected to DeviceC, which functions as the egress
gateway of DeviceA and DeviceB. There are reachable routes between DeviceC
and the DHCP server, and between DeviceC and the file server.

The customer requires that DeviceA and DeviceB automatically load the system
software and configuration files after they are powered on to reduce labor costs
and device deployment time.

Table 6-23 lists information about DeviceA and DeviceB, and the files to be
loaded to them.

Table 6-23 Device information and files to be loaded

New Device Device ESN Files to Be Loaded

DeviceA 2102311LDL000000 ● System software: software_file.cc


0806 ● Configuration file: conf_file.cfg

DeviceB 2102311LDL000000 ● System software: software_file.cc


0918 ● Configuration file: conf_file.cfg

Figure 6-17 Network diagram of option-based ZTP


NOTE

In this example, interface1, interface2, and interface3 represent 10GE1/0/1, 10GE1/0/2, and
10GE1/0/3, respectively.

Configuration Roadmap
The configuration roadmap is as follows:

1. Configure the DHCP server.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 275


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

2. Configure the DHCP relay agent.


3. Configure the file server.
4. Power on DeviceA and DeviceB to start the ZTP process.

Procedure
Step 1 Edit the masterkey.ini file.
Create a .txt file and change the file name to masterkey.ini. The following uses
saving the configuration file as an example. The password is YsHsjx_202206. Edit
the file as follows:
[BEGIN]
EXPORTCFG=YsHsjx_202206
[END]

Step 2 Configure the DHCP server.


# Configure the IP address pool that the DHCP server uses to allocate IP addresses
to DeviceA and DeviceB and set DHCP options by referring to Table 6-24. In this
example, a Huawei device is used as the DHCP server.

Table 6-24 DHCP server options


Option Description Value

Option 1 Subnet mask of an IP 255.255.255.0


address

Option 3 Egress gateway of a 10.1.1.1


DHCP client

Option 67 File server address and sftp://


deployment file name sftp_user:Hyx_Hy1234@1
0.1.3.2/conf_file.cfg

Option 145 Deployment system ● The deployment


software and masterkey system software is
file software_file.cc.
● The masterkey file is
masterkey.ini.

<HUAWEI> system-view
[HUAWEI] sysname dhcp_server
[dhcp_server] dhcp enable
[dhcp_server] ip pool pool1
[dhcp_server-ip-pool-pool1] gateway-list 10.1.1.1
[dhcp_server-ip-pool-pool1] network 10.1.1.0 mask 255.255.255.0
[dhcp_server-ip-pool-pool1] option 67 cipher sftp://sftp_user:Hyx_Hy1234@10.1.3.2/conf_file.cfg
[dhcp_server-ip-pool-pool1] option 145 ascii vrpfile=software_file.cc;masterfile=masterkey.ini;
[dhcp_server-ip-pool-pool1] quit
[dhcp_server] vlan batch 10
[dhcp_server] interface 10ge 1/0/3
[dhcp_server-10GE1/0/3] portswitch
[dhcp_server-10GE1/0/3] port link-type trunk
[dhcp_server-10GE1/0/3] port trunk allow-pass vlan 10
[dhcp_server-10GE1/0/3] quit
[dhcp_server] interface vlanif 10

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 276


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

[dhcp_server-Vlanif10] ip address 10.1.2.2 24


[dhcp_server-Vlanif10] quit

Step 3 Configure the DHCP relay agent.

# Configure the DHCP relay function on DeviceC. Set the IP address of the
interface connecting DeviceC to DeviceA and DeviceB to 10.1.1.1 to configure
DeviceC as the default gateway of DeviceA and DeviceB.
<HUAWEI> system-view
[HUAWEI] sysname DeviceC
[DeviceC] vlan batch 10
[DeviceC] interface 10ge 1/0/1
[DeviceC-10GE1/0/1] portswitch
[DeviceC-10GE1/0/1] port link-type trunk
[DeviceC-10GE1/0/1] port trunk allow-pass vlan 10
[DeviceC-10GE1/0/1] port trunk pvid vlan 10
[DeviceC-10GE1/0/1] quit
[DeviceC] interface 10ge 1/0/2
[DeviceC-10GE1/0/2] portswitch
[DeviceC-10GE1/0/2] port link-type trunk
[DeviceC-10GE1/0/2] port trunk allow-pass vlan 10
[DeviceC-10GE1/0/2] port trunk pvid vlan 10
[DeviceC-10GE1/0/2] quit
[DeviceC] interface vlanif 10
[DeviceC-Vlanif10] ip address 10.1.1.1 24
[DeviceC-Vlanif10] quit
[DeviceC] dhcp enable
[DeviceC] interface vlanif 10
[DeviceC-Vlanif10] dhcp select relay
[DeviceC-Vlanif10] dhcp relay server-ip 10.1.2.2

Step 4 Configure the file server.

# If a device is configured as the file server, files will occupy a significant amount
of device storage resources. To ensure the device performance, a third-party file
server is typically used on a ZTP network. For details about how to configure a
third-party file server, see the third-party server operation guide.

# After configuring the file server, save the system software, configuration files,
and intermediate files to be loaded to DeviceA and DeviceB in the root directory
on the file server.

Step 5 Power on DeviceA and DeviceB to start the ZTP process.

----End

Verifying the Configuration


The devices complete the ZTP process in about 15 minutes after they are powered
on. Log in to the devices and run the display startup command to check whether
the current system software and configuration files are the required ones. The
following shows the command output of DeviceA.
<DeviceA> display startup
MainBoard:
Configured startup system software: flash:/software_file.cc
Startup system software: flash:/software_file.cc
Next startup system software: flash:/software_file.cc
Startup saved-configuration file: flash:/conf_file.cfg
Next startup saved-configuration file: flash:/conf_file.cfg
Startup paf file: default
Next startup paf file: default
Startup patch package: NULL
Next startup patch package: NULL

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 277


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Startup feature software: NULL


Next startup feature software: NULL

Configuration Scripts
● DeviceC
#
sysname DeviceC
#
vlan batch 10
#
dhcp enable
#
interface Vlanif10
ip address 10.1.1.1 255.255.255.0
dhcp select relay
dhcp relay server-ip 10.1.2.2
#
interface 10GE1/0/1
port link-type trunk
port trunk pvid vlan 10
port trunk allow-pass vlan 10
#
interface 10GE1/0/2
port link-type trunk
port trunk pvid vlan 10
port trunk allow-pass vlan 10
#
return

● DHCP server
#
sysname dhcp_server
#
dhcp enable
#
vlan batch 10
#
ip pool pool1
gateway-list 10.1.1.1
network 10.1.1.0 mask 255.255.255.0
option 67 cipher %+%#,nl-3C^(L"r2cE=]>Z[X2Xo+<e0-S;@s"#ReXBA(h>4\4h_@P']"!
t4*26):0x31:fqp7Jz4FG'SYLo#%+%#
option 145 ascii vrpfile=software_file.cc;masterfile=masterkey.ini;
#
interface Vlanif10
ip address 10.1.2.2 255.255.255.0
#
interface 10GE1/0/3
port link-type trunk
port trunk allow-pass vlan 10
#
return

6.6.13 Example for Configuring Bootstrap Server-based SZTP

Networking Requirements
In Figure 6-18, DeviceA and DeviceB are two unconfigured devices on the
network, and both are connected to DeviceC, which functions as the egress
gateway of DeviceA and DeviceB. There are reachable routes between DeviceC
and the DHCP server, and between DeviceC and the file server.

The customer requires that DeviceA and DeviceB automatically load the system
software and configuration files in SZTP mode after they are powered on.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 278


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Table 6-25 lists information about DeviceA and DeviceB, and the files to be
loaded to them.

Table 6-25 Device information and files to be loaded

New Device Files to Be Loaded

DeviceA ● System software: software_file.cc


● Configuration file: conf_file1.cfg

DeviceB ● System software: software_file.cc


● Configuration file: conf_file2.cfg

Figure 6-18 Network diagram of SZTP


NOTE

In this example, interface1, interface2, and interface3 represent 10GE1/0/1, 10GE1/0/2, and
10GE1/0/3, respectively.

Configuration Roadmap
The configuration roadmap is as follows:

1. Configure the DHCP server.


2. Configure the DHCP relay agent.
3. Configure the bootstrap server.
4. Configure the HTTPS deployment file server.
5. Power on DeviceA and DeviceB to start the SZTP process.

Procedure
Step 1 Configure the DHCP server.

# Configure the IP address pool that the DHCP server uses to allocate IP addresses
to DeviceA and DeviceB and set DHCP options by referring to Table 6-26. In this
example, a Huawei device is used as the DHCP server.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 279


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Table 6-26 DHCP server options


Option Description Value

Option 1 Subnet mask of an IP 255.255.255.0


address

Option 3 Egress gateway of a 10.1.1.1


DHCP client

Option 143 IP address of a bootstrap 10.1.4.2


server

<HUAWEI> system-view
[HUAWEI] sysname dhcp_server
[dhcp_server] dhcp enable
[dhcp_server] ip pool pool1
[dhcp_server-ip-pool-pool1] gateway-list 10.1.1.1
[dhcp_server-ip-pool-pool1] network 10.1.1.0 mask 255.255.255.0
[dhcp_server-ip-pool-pool1] option 143 hex 001268747470733a2f2f31302e312e342e323a31
[dhcp_server-ip-pool-pool1] quit
[dhcp_server] vlan batch 10
[dhcp_server] interface 10ge 1/0/3
[dhcp_server-10GE1/0/3] portswitch
[dhcp_server-10GE1/0/3] port link-type trunk
[dhcp_server-10GE1/0/3] port trunk allow-pass vlan 10
[dhcp_server-10GE1/0/3] quit
[dhcp_server] interface vlanif 10
[dhcp_server-Vlanif10] ip address 10.1.2.2 24
[dhcp_server-Vlanif10] quit

Step 2 Configure the DHCP relay agent.


# Configure the DHCP relay function on DeviceC. Set the IP address of the
interface connecting DeviceC to DeviceA and DeviceB to 10.1.1.1 to configure
DeviceC as the default gateway of DeviceA and DeviceB.
<HUAWEI> system-view
[HUAWEI] sysname DeviceC
[DeviceC] vlan batch 10
[DeviceC] interface 10ge 1/0/1
[DeviceC-10GE1/0/1] portswitch
[DeviceC-10GE1/0/1] port link-type trunk
[DeviceC-10GE1/0/1] port trunk allow-pass vlan 10
[DeviceC-10GE1/0/1] port trunk pvid vlan 10
[DeviceC-10GE1/0/1] quit
[DeviceC] interface 10ge 1/0/2
[DeviceC-10GE1/0/2] portswitch
[DeviceC-10GE1/0/2] port link-type trunk
[DeviceC-10GE1/0/2] port trunk allow-pass vlan 10
[DeviceC-10GE1/0/2] port trunk pvid vlan 10
[DeviceC-10GE1/0/2] quit
[DeviceC] interface vlanif 10
[DeviceC-Vlanif10] ip address 10.1.1.1 24
[DeviceC-Vlanif10] quit
[DeviceC] dhcp enable
[DeviceC] interface vlanif 10
[DeviceC-Vlanif10] dhcp select relay
[DeviceC-Vlanif10] dhcp relay server-ip 10.1.2.2

Step 3 Configure the bootstrap server.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 280


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

# Huawei devices do not support the bootstrap server function. In the SZTP
networking, a third-party server needs to be deployed. For details about how to
configure a third-party server, see the third-party server operation guide.
# Huawei level-2 CA certificate, ownership voucher, and owner certificate need to
be built in the bootstrap server.
# On the bootstrap server, set the IP address of the HTTPS file server to 10.1.3.2,
and set the deployment files, configuration files, and their paths for DeviceA and
DeviceB.
Step 4 Configure the HTTPS deployment file server.
# Huawei devices do not support the HTTPS server function. In the SZTP
networking, a third-party server needs to be deployed. For details about how to
configure a third-party server, see the third-party server operation guide.
# After configuring the file server, save the deployment files and configuration
files to be loaded to devices to the paths specified on the bootstrap server.
Step 5 Power on DeviceA and DeviceB to start the SZTP process.

----End

Verifying the Configuration


# The devices complete the SZTP process in about 15 minutes after they are
powered on. Log in to the devices and run the display startup command to check
whether the current system software and configuration files are the required ones.
The following shows the command output of DeviceA.
<DeviceA> display startup
MainBoard:
Configured startup system software: flash:/software_file.cc
Startup system software: flash:/software_file.cc
Next startup system software: flash:/software_file.cc
Startup saved-configuration file: flash:/conf_file1.cfg
Next startup saved-configuration file: flash:/conf_file1.cfg
Startup paf file: default
Next startup paf file: default
Startup patch package: NULL
Next startup patch package: NULL
Startup feature software: NULL
Next startup feature software: NULL

Configuration Scripts
● DeviceC
#
sysname DeviceC
#
vlan batch 10
#
dhcp enable
#
interface Vlanif10
ip address 10.1.1.1 255.255.255.0
dhcp select relay
dhcp relay server-ip 10.1.2.2
#
interface 10GE1/0/1
port link-type trunk
port trunk pvid vlan 10
port trunk allow-pass vlan 10

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 281


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

#
interface 10GE1/0/2
port link-type trunk
port trunk pvid vlan 10
port trunk allow-pass vlan 10
#
return

● DHCP server
#
sysname dhcp_server
#
dhcp enable
#
vlan batch 10
#
ip pool pool1
gateway-list 10.1.1.1
network 10.1.1.0 mask 255.255.255.0
option 143 hex 001268747470733a2f2f31302e312e342e323a31
#
interface Vlanif10
ip address 10.1.2.2 255.255.255.0
#
interface 10GE1/0/3
port link-type trunk
port trunk allow-pass vlan 10
#
return

6.7 Configuring USB-based Deployment

6.7.1 Understanding USB-based Deployment


Fundamentals
Before initiating USB-based deployment, create an intermediate file named usb.ini
and save it to the root directory of the USB flash drive. Then save the deployment
files to be loaded to the directory specified in the usb.ini file. Insert the USB flash
drive into the device; the device will automatically load the deployment files based
on the usb.ini file.

Implementation Process
Implementation Process shows the implementation process of USB-based
deployment.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 282


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Figure 6-19 Implementation process

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 283


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

The USB-based deployment implementation process involves the following steps:

1. Powering on the device and inserting the USB flash drive into the device
After the device is powered on and starts, it detects the USB flash drive. If the
device has no configuration file, it directly enters the USB-based deployment
process. If the device has a configuration file, it checks whether the USB-
based deployment function is enabled. A device with a configuration file can
enter the USB-based deployment process only when the function is enabled.
The device then checks whether the intermediate file usb.ini exists in the root
directory of the USB flash drive. If not, the deployment process exits.
2. Reading the intermediate file and obtaining deployment files
The device reads the usb.ini file in the root directory of the USB flash drive
and obtains deployment files from the directory specified in the usb.ini file.
If the device fails to read the intermediate file, the USB-based deployment
process exits. If no deployment file is obtained from the specified directory in
the USB flash drive, the USB-based deployment process ends due to the
exception.
3. Performing security check
– If the function of compressing deployment files with a password is
enabled in the intermediate file but the file requires the use of HMAC to
verify the integrity of the deployment files, the device decompresses the
deployment files and then performs HMAC verification. The deployment
process can continue only after the deployment files have been
decompressed and verified successfully.
– If the function of compressing deployment files with a password is
enabled in the intermediate file but the file does not require using
hashed-based message authentication (HMAC) to verify the integrity of
the deployment files, the device only decompresses the deployment files.
The deployment process continues after the deployment files have been
decompressed successfully.
– If the function of compressing the deployment files with a password is
not enabled in the intermediate file and the file requires the use of
HMAC to verify the integrity of the deployment files, the device directly
performs HMAC verification on the deployment files. The deployment
process continues after the deployment files have been verified
successfully.
4. Deployment end
The device determines whether to activate a deployment file online or
whether to set a deployment file as the system startup file according to the
deployment file type, and then restarts to complete automatic deployment.

6.7.2 Preparing Deployment Files

Context
Before USB-based ZTP, you need to prepare the configuration file and
intermediate file. The configuration file can be copied from other devices, and the
intermediate file needs to be manually edited.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 284


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

NOTE

To ensure security, you are advised to run the save shareable-configuration command to
export the configuration file and not advised to manually edit the configuration file.
Ensure that the configuration file for deployment contains the console password or an AAA
user name that can be used to log in to the device remotely. Otherwise, the configuration
file cannot be successfully set, causing a deployment failure.

Procedure
Step 1 Save the configuration file on the device that provides the configuration file.
save shareable-configuration configuration-file

Step 2 Export the configuration file from the device to the USB flash drive.
Step 3 Edit the intermediate file. Create a text file named usb.ini on the terminal, and
edit the intermediate file by referring to 6.7.3 Intermediate File for USB-based
Deployment.
Step 4 Copy the intermediate file usb.ini to the root directory of the USB flash drive.
NOTE

The file system format of a USB flash drive must be FAT32 or EXT4 and its interface must
be USB 2.0 compliant.

Step 5 Copy the configuration file to the directory specified by DIRECTORY in the usb.ini
file.

----End

6.7.3 Intermediate File for USB-based Deployment


Intermediate File for USB-based Deployment
The intermediate file is used to save information about the device and its
deployment files. The file name must be usb.ini, and the following is an example
of such a file. For details about the fields included in this file, see Table 6-27.
#sha256="676a306a0c22d46ed975633de9d05af4b1ebb94879ed1dd1d1e34de2a72c4e7e"
;BEGIN USB
[GLOBAL CONFIG]
*TIME_SN=20200526120159
*DEVICE_TYPE_NUM=1

[DEVICE_TYPE_1 DESCRIPTION]
DEVICE_TYPE=
ESN=
MAC=
VRPVER=
SPACE_CLEAR=1
DIRECTORY=
ACTIVE_DELAYTIME=10
ACTIVE_INTIME=
*FILETYPENUM=6
*FILENAME_1=software_file1.cc
*TYPE_1=SOFTWARE
*EFFECTIVE_MODE_1=1
ISBATCHPROCESS_1=0
SHA256_1=
HMAC_1=
COMPRESS_ENCRYTION_1=

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 285


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

*FILENAME_2=file1_cfg.zip
*TYPE_2=CFG
*EFFECTIVE_MODE_2=2
ISBATCHPROCESS_2=0
SHA256_2=
HMAC_2=
COMPRESS_ENCRYTION_2=1
*FILENAME_3=lic_file1.xml
*TYPE_3=LIC
*EFFECTIVE_MODE_3=1
ISBATCHPROCESS_3=0
SHA256_3=
HMAC_3=
COMPRESS_ENCRYTION_3=
*FILENAME_4=pat_file1.PAT
*TYPE_4=PAT
*EFFECTIVE_MODE_4=1
ISBATCHPROCESS_4=1
SHA256_4=d4b1670069a2b2b9fbe0eaaf872564c305783d438fc6a020ce8aa05f91053d5e
HMAC_4=
COMPRESS_ENCRYTION_4=
*FILENAME_5=pat_file2.MOD
*TYPE_5=PAT
*EFFECTIVE_MODE_5=0
ISBATCHPROCESS_5=0
SHA256_5=c7f70c5bd82a1ccb71eb3b6a837d8311594cba0ebf00f84bcccf2578fcf83698
HMAC_5=
*FILENAME_6=user_file1.log
*TYPE_6=USER
*EFFECTIVE_MODE_6=2
ISBATCHPROCESS_6=0
SHA256_6=
HMAC_6=
COMPRESS_ENCRYTION_6=

;END USB CONFIG

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 286


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Table 6-27 Fields in the intermediate file


Field Mandatory or Not Description

sha256 No SHA256 verification code


of the script, which is
used to check the
integrity of the
downloaded script.
You can use either of the
following methods to
generate an SHA256
verification code for a
script file:
1. Use the SHA256
calculation tool, such
as HashMyFiles.
2. Run the certutil -
hashfile filename
SHA256 command
provided by the
Windows operating
system.
NOTE
Before an SHA256
verification code is
generated, do not add the
#sha256= field to the
script. Instead, #sha256=
should be added to the
beginning of the script
after the SHA256
verification code is
generated.
A script without an
SHA256 verification code
can still be executed.

;BEGIN USB Yes Start flag of the file. This


field cannot be modified.

[GLOBAL CONFIG] Yes Start flag of the global


configuration. This field
cannot be modified.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 287


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Field Mandatory or Not Description

TIME_SN Yes Uniquely identifies a


deployment in order to
prevent repeated
deployment. The value
format is
yyyymmddhhmmss.
For example, this field
can be set to
20200526120159,
indicating 12:01:59 on
2020-05-26.

DEVICE_TYPE_NUM Yes Number of device types.


The value 1 indicates
that only one type of
device can be deployed.

[DEVICE_TYPE_n Yes Start tag of the device


DESCRIPTION] description. n indicates
the device number. The
value is an integer
starting from 1.

DEVICE_TYPE When Device type.


DEVICE_TYPE_NUM is The value of
set to 1, DEVICE_TYPE, DEVICE_TYPE can be
ESN, and MAC can all be queried using the
set to DEFAULT or left display version
empty. command. In the
When command output,
DEVICE_TYPE_NUM is S16700 in "Version xxx
greater than 1, (S16700 xxx)" is the
DEVICE_TYPE, ESN, and value of DEVICE_TYPE.
MAC must be specified If this field is left empty
and only one of them or set to DEFAULT, the
can be specified. device type is not
NOTE checked. The default
● To upgrade devices in value is DEFAULT.
batches, set
DEVICE_TYPE.
● To upgrade a single
device, you can set the
ESN or MAC address of
the device.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 288


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Field Mandatory or Not Description

ESN ESN of a device. You can


run the display device
esn command to query
the ESN.
If this field is left empty
or set to DEFAULT, the
device does not check
the value. If this field is
set to another value, the
device checks whether
that value is the same as
its ESN. The default
value is DEFAULT.

MAC MAC address of a device,


in the XXXX-XXXX-XXXX
format, in which X is a
hexadecimal number.
You can run the display
bridge mac-address
command to query the
MAC address.
If this field is left empty
or set to DEFAULT, the
device does not check
the value. If this field is
set to another value, the
device checks whether
that value is the same as
its MAC address. The
default value is
DEFAULT.

VRPVER No System software version


number.
If the current system
software version of the
device is the same as the
value specified here, the
device does not
download the system
software from the
deployment file server.
If the current system
software package is that
required for deployment,
you are advised to set
this field.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 289


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Field Mandatory or Not Description

SPACE_CLEAR No Whether to
automatically clean up
the system storage space
in the case of space
insufficiency. The value is
of the enumerated type.
● 0: The system storage
space is not cleaned
up.
● 1: Only system
software among
deployment files is
deleted.
● 2: In-depth cleanup is
performed. System
software among
deployment files is
deleted first. If the
available space is still
insufficient, all
unnecessary files are
deleted from the flash
directory.
If this field is left empty
or set to DEFAULT, the
space is not cleaned up.
The default value is
DEFAULT.
NOTE
In-depth cleanup involves
some inherent risks. As
such, you are advised to
back up required files
locally before performing
in-depth cleanup.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 290


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Field Mandatory or Not Description

DIRECTORY No Relative directory of the


deployment file on the
file server. The maximum
length of the path and
file name is 110
characters.
If this field is left empty
or set to DEFAULT,
deployment files are
stored in the root
directory. The default
value is DEFAULT.
NOTE
The relative directory must
start with a folder name
and cannot start with a
slash (/).

ACTIVE_DELAYTIME No Delay for deployment to


NOTE be performed. The value
If both is an integer that ranges
ACTIVE_DELAYTIME and from 0 to 86400, in the
ACTIVE_INTIME are set, unit of seconds. If the
ACTIVE_DELAYTIME is
value is greater than
preferentially used.
86400, the value 86400
is used.

ACTIVE_INTIME Scheduled time for


deployment to be
performed within 24
hours. The value format
is HH:MM, where HH
indicates the 24-hour
format, and MM
indicates the 60-minute
format. For example, the
value 20:10 indicates
that the deployment will
be performed at 20:10.
NOTE
If the configured time is
earlier than the system
time of the device, the
actual deployment time is
the configured time plus
24 hours minus the current
system time. For example,
if the configured time is
10:00 and the device
system time is 11:00, the
deployment will be
performed at 23:00.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 291


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Field Mandatory or Not Description

FILETYPENUM Yes Number of deployment


files to be loaded.
NOTE
The total number of
deployment files must not
exceed 9.
The value of this field must
be the same as the actual
number of deployment
files, and the value is the
same as n in FILENAME_n.

FILENAME_n Yes Name of a deployment


file, which can be the
system software,
configuration file, license
file, patch file, feature
package file, or
customized file.
NOTE
You are advised to run the
save shareable-
configuration password
command without entering
a password to export a
configuration file.
If the length of a
deployment file name
exceeds the limit, it may
fail to be downloaded. The
length limits for different
deployment files are as
follows:
● System software: 4 to
127 characters
● Configuration file: 5 to
64 characters
● License file: 5 to 127
characters
● Patch file: 5 to 63
characters
● Customized file: 3 to 64
characters
● Feature package file: 4
to 127 characters

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 292


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Field Mandatory or Not Description

TYPE_n Yes Type of a deployment


file. The value is of the
enumerated type.
● SOFTWARE: system
software
● CFG: configuration file
● LIC: license file
● PAT: patch file
● USER: customized file
● FEATURE-PLUGIN:
feature package file

EFFECTIVE_MODE_n Yes Activation mode. The


value is of the
enumerated type.
● 0: effective upon
restart, which applies
to the system
software,
configuration file,
patch file, and feature
package file.
● 1: effective
immediately, which
applies to the license
file, feature package
file, and patch file.
● 2: Activation is not
required, which
applies to the
customized file.
The default activation
mode of the system
software and
configuration file is 0.
The default activation
mode of the patch file,
feature package file, and
license file is 1.
The default activation
mode of the customized
file is 2.
If EFFECTIVE_MODE_n is
set to a value that is not
0, 1, or 2, the default
activation mode of each
type of file is used.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 293


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Field Mandatory or Not Description

ISBATCHPROCESS_n No Whether to perform


batch processing for the
license list file. The value
is of the enumerated
type.
● 0: no
● 1: yes
If this field is left empty
or set to DEFAULT, batch
processing is not
performed. The default
value is DEFAULT.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 294


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Field Mandatory or Not Description


NOTE
Devices can use the license
list file, which contains
mappings between licenses
and device ESNs, to
automatically load license
files. A device first
downloads the license list
file and then downloads
the corresponding license
file based on the mappings
to load it. The license list
file is in XML format and
its name must be
ztp_license_list. An
example of such a file is as
follows:
<?xml version="1.0"
encoding="UTF-8"
standalone="true"?>
-<Index formatVersion="1.0">
-<Lic
Esn="2102353UNW123456789
0">
<LSN>LIC202005183TCG5M</
LSN>
<name>LIC_file1.xml</name>
<sha256>eb75e8456b049e240
6fe61925499080a083bd91319
c50f59551cc3ea113a35f2</
sha256>
<hamc_sha256/>
<compress_encrytion/>
>
</Lic>
-<Lic
Esn="BARCODETEST20200620
">
<LSN>LIC202005183TCI50</
LSN>
<name>LIC_file2.dat</name>
<sha256>6a2690e7a08e3df84
4ba86e1f48dc3c504af3b760dd
0e38134771e1024fe1a5f</
sha256>
<hamc_sha256>6a2690e7a08e
3df844ba86e1f48dc3c504af3b
760dd0e3813477</
hamc_sha256>
<compress_encrytion>1</
compress_encrytion>
>
</Lic>
</Index>

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 295


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Field Mandatory or Not Description

SHA256_n No Verification code


NOTE corresponding to the
If neither SHA256 nor SHA256 encryption
HMAC is selected, the algorithm, which is used
device does not verify the to verify the integrity of
deployment file integrity.
a deployment file.
If either SHA256 or HMAC
is configured, the If this field is left empty,
configured one takes the deployment file
effect. integrity is not verified.
If both SHA256 and HMAC
HMAC_n are configured, only HMAC
Verification code
verification is performed. corresponding to the
HMAC_SHA256
encryption algorithm,
which is used to verify
the integrity of a
deployment file.
If this field is left empty,
the file integrity is not
verified.

COMPRESS_ENCRYTION_ No Whether to compress a


n deployment file.
The value can only be
empty or 1.
If the value is empty, the
deployment file is not
compressed. In this case,
the device does not need
to decompress the
deployment file.
If the value is 1, the
deployment file is
compressed with a
password. The device
needs to use the
password to decompress
the deployment file.

;END USB CONFIG Yes End flag of the file. This


field cannot be modified.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 296


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

6.7.4 (Optional) Configuring Deployment File Security


Verification

Context
To ensure the security of deployment files, you can encrypt and compress the files
and configure HMAC key-based integrity verification.

● Setting a password for decompressing a deployment file


– Before a deployment file is copied to the USB flash drive, you can
compress the deployment file into a .zip package based on a specified
password.
NOTE

Deployment files can only be encrypted and compressed on Huawei devices.


The .zip package name must be in the name_nametype.zip format, where name
is the name of the file extracted from the package, and nametype is the type of
the extracted file.
Each deployment file is compressed into a separate .zip file, and one .zip file can
contain only one deployment file.
– During USB-based deployment, the device downloads the deployment
files and uses the preset password to decompress them.
● Configuring an HMAC key for deployment file integrity verification
– Before copying a deployment file to the USB flash drive, you can calculate
a hash value based on the configured HMAC key for the deployment file
and writes it to the HMAC field in the intermediate file usb.ini. You can
use the openssl dgst tool to obtain the hash value.
– During USB-based deployment, the device downloads the deployment file
and uses the configured HMAC key to calculate the hash value of the
deployment file.
– The device compares the calculated hash value with that of the HMAC
field in the usb.ini file. If the two values are the same, HMAC-based
integrity verification succeeds. Otherwise, the verification fails.
NOTE

To compress a deployment file and configure HMAC key-based verification, you must
calculate the hash value for the file and compress the deployment file with a password.

Procedure
Step 1 Enter the system view.
system-view

Step 2 Set a password for decompressing a deployment file.


ztp usb-deployment file-compress password [ filepasswordval ]

By default, no decompression password is configured for a deployment file. The


password must be the same as that used to compress the deployment file.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 297


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

NOTE

If the weak password dictionary maintenance function is enabled, the passwords defined in
the weak password dictionary cannot be used. To view these passwords, run the display
security weak-password-dictionary command.

Step 3 Configure an HMAC key for deployment file integrity verification.


ztp usb-deployment file-integrity password [ hmacpasswordval ]

By default, no HMAC key is configured for deployment file integrity verification.


The key must be the same as the HMAC key used to calculate the hash value of
the deployment file.

NOTE

If the weak password dictionary maintenance function is enabled, the passwords defined in
the weak password dictionary cannot be used. To view these passwords, run the display
security weak-password-dictionary command.

----End

6.7.5 Starting USB-based Deployment


Context
USB-based deployment is classified into deployment for devices that start with
factory configurations and deployment for devices with non-factory
configurations. If the device starts with factory configurations, the USB-based
deployment function is enabled on the device. In this case, you do not need to
perform the following operations. To enable the USB-based deployment function
when a configuration file exists, perform the following operations first.

Procedure
Step 1 Enter the system view.
system-view

Step 2 (Optional) Enable the ZTP function on the device. By default, a device
automatically starts the ZTP process after it is powered on and starts with factory
configurations. You can disable the ZTP function on a device. If you log in to a
device through the console port and disable the ZTP function when the device
starts with factory configurations, the ZTP process is terminated. To enable the
device to execute the ZTP process when it starts with factory configurations next
time, you need to enable the ZTP function.
set ztp enable

NOTE

This command does not take effect for USB-based deployment on a device with non-
factory configurations.

By default, the ZTP function is enabled on a device. To disable a device from


running the ZTP process upon startup with factory configurations, run the set ztp
disable command on the device.
Step 3 Enable the USB-based deployment function for a device with a non-factory
configuration file.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 298


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

ztp usb-deployment enable

By default, the USB-based deployment function is not enabled for a device with a
non-factory configuration file.

NOTE

● This command takes effect only when a USB flash drive is installed on the device that
has a configuration file.
● It is recommended that you run the undo ztp usb-deployment enable command to
disable the USB-based deployment function after completing a deployment. Otherwise,
an unnecessary upgrade will be triggered if a USB flash drive is connected to the device
by mistake, causing service interruption.

Step 4 Restart the device with factory configurations.


reboot fast

----End

6.7.6 Verifying USB-based Deployment

Context
When using a USB flash drive for deployment, you can observe the USB indicator
to determine the progress of USB-based deployment.

● Steady green: USB-based deployment succeeds. If there is no deployment


configuration file, deployment will be repeatedly performed. In this case, the
indicator is also steady green.
● Blinking green: USB-based deployment is in progress.
● Steady red: USB-based deployment fails.
● Off: No USB flash drive is installed, or the indicator fails.

Procedure
Step 1 A device completes the USB-based process within about 15 minutes after it is
powered on. You can then log in to the device to check whether the startup files
are the required ones.
display startup

----End

Follow-up Procedure
If deployment fails, analyze USB logs on the device to determine the cause. ZTP-
related logs are saved in the ztp_YearMonthHourMinuteSecond.log file in the
flash:/ directory and in the ztp_esn_YearMonthHourMinuteSecond.log file in the
root directory of the USB flash drive.

NOTE

You can run the display device esn command to obtain the ESN of a device.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 299


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

6.7.7 (Optional) Configuring the Device to Download a CA


Certificate from the Bootstrap Server

Prerequisites
The device has been deployed.

Context
In the scenario where no initial certificate is available on iMaster NCE-Campus, if
the device needs to be managed by the controller, you need to import the CA
certificate trusted by the controller to the device.

The bootstrap server stores the CA certificate trusted by the controller. Currently,
iMaster NCE-Campus integrates the function of the bootstrap server. The device
needs to download the CA certificate NCE-bootstrap.pem from the bootstrap
server and import the certificate to the default domain.

A maximum of 10 bootstrap servers can be configured for the device. The


bootstrap servers with the same IP address and VPN instance name are considered
as one bootstrap server. The interaction process between the device and bootstrap
server is as follows:

1. The device proactively establishes an HTTPS connection with a bootstrap


server.
2. The device sends a request packet to the bootstrap server to download a CA
certificate. The request packet carries the device ESN or the IP address of the
bootstrap server.
3. The bootstrap server searches for the CA certificate based on the ESN or IP
address in the request packet and sends a response packet carrying the CA
certificate to the device. The response packet also carries the device ESN or
the IP address of the bootstrap server.
4. After receiving the response packet from the bootstrap server, the device
terminates the HTTPS connection with the bootstrap server, parses the
response packet, and verifies the validity of the certificate. If the verification
fails, the device cannot obtain the CA certificate. In this case, the device
attempts to obtain the CA certificate from the next bootstrap server. The
device will keep doing so until it successfully obtains a CA certificate.

After successfully obtaining the CA certificate NCE-bootstrap.pem from the


bootstrap server, the device automatically imports the certificate to the default
domain.

Procedure
Step 1 Enter the system view.
system-view

Step 2 Configure an SSL policy and bind it to the default domain.


ssl policy policy-name
pki-domain default
quit

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 300


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Step 3 Configure the device to download a CA certificate from the bootstrap server.
ztp certificate-remote { ipv4-addr | ipv6 ipv6-addr } [ vpn-instance vpnvalue ] port portvalue ssl-policy
policyname [ verify-type esn ]

By default, the device is not configured to download a CA certificate from the


bootstrap server.

When the verify-type esn parameter is specified, a certificate is authenticated


based on the device ESN. That is, the request packet sent by the device to the
bootstrap server for downloading the CA certificate carries the device ESN. When
parsing the response packet from the bootstrap server, the device uses the ESN for
verification.

When the verify-type esn parameter is not specified, a certificate is authenticated


based on the IP address of the bootstrap server. That is, the request packet sent by
the device to the bootstrap server for downloading the CA certificate carries the IP
address of the bootstrap server. When parsing the response packet from the
bootstrap server, the device uses the IP address for verification.

After NCE-bootstrap.pem is imported to the default domain, if another CA


certificate needs to be downloaded from the bootstrap server, delete the original
certificate from the default domain and run the ztp certificate-remote command
again.

----End

6.7.8 Example for Configuring USB-based Deployment

Networking Requirements
A new network needs to be deployed. DeviceA and DeviceB are two devices
without a configuration file, and the customer requires that they automatically
load system software and configuration files after they are powered on to reduce
labor costs and deployment time. Table 6-28 lists device information and files to
be loaded to DeviceA and DeviceB.

Table 6-28 Device information and files to be loaded

New Device Device ESN Files to Be Loaded

DeviceA 2102311LDL000000 ● System software: software_file.cc


0806 ● Configuration file: conf_file1.cfg

DeviceB 2102311LDL000000 ● System software: software_file.cc


0918 ● Configuration file: conf_file2.cfg

Configuration Roadmap
The configuration roadmap is as follows:

1. Edit the intermediate file usb.ini to enable the devices to obtain their system
software and configuration files according to the intermediate file.

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 301


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

2. Save the usb.ini file to the root directory of the USB flash drive and system
software and configuration files to the USB flash drive path specified in the
intermediate file.
3. Insert the USB flash drive into the devices and power them on.

Procedure
Step 1 Edit the intermediate file usb.ini according to the file format requirements in 6.7.3
Intermediate File for USB-based Deployment. The file format is as follows:
;BEGIN USB
[GLOBAL CONFIG]
*TIME_SN=20200526120159
*DEVICE_TYPE_NUM=2

[DEVICE_TYPE_1 DESCRIPTION]
DEVICE_TYPE=
ESN=2102311LDL0000000806
MAC=
VRPVER=
SPACE_CLEAR=1
DIRECTORY=
ACTIVE_DELAYTIME=10
ACTIVE_INTIME=
*FILETYPENUM=2
*FILENAME_1=software_file.cc
*TYPE_1=SOFTWARE
*EFFECTIVE_MODE_1=0
ISBATCHPROCESS_1=0
SHA256_1=
HMAC_1=
COMPRESS_ENCRYTION_1=
*FILENAME_2=conf_file1.cfg
*TYPE_2=CFG
*EFFECTIVE_MODE_2=0
ISBATCHPROCESS_2=0
SHA256_2=
HMAC_2=
COMPRESS_ENCRYTION_2=

[DEVICE_TYPE_2 DESCRIPTION]
DEVICE_TYPE=
ESN=2102311LDL0000000918
MAC=
VRPVER=
SPACE_CLEAR=1
DIRECTORY=
ACTIVE_DELAYTIME=10
ACTIVE_INTIME=
*FILETYPENUM=2
*FILENAME_1=software_file.cc
*TYPE_1=SOFTWARE
*EFFECTIVE_MODE_1=0
ISBATCHPROCESS_1=0
SHA256_1=
HMAC_1=
COMPRESS_ENCRYTION_1=
*FILENAME_2=conf_file2.cfg
*TYPE_2=CFG
*EFFECTIVE_MODE_2=0
ISBATCHPROCESS_2=0
SHA256_2=
HMAC_2=
COMPRESS_ENCRYTION_2=
;END USB CONFIG

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 302


CloudEngine S16700 Series Switches
Configuration Guide - Basic Configuration 6 ZTP Configuration

Step 2 Save the usb.ini file to the root directory of the USB flash drive and system
software and configuration files to the USB flash drive path specified in the
intermediate file.
Step 3 Insert the USB flash drive to DeviceA and power on the device.
Step 4 After DeviceA completes automatic deployment, remove the USB flash drive and
insert it to DeviceB. Then power on DeviceB to start automatic deployment.

----End

Verifying the Configuration


# The devices complete the USB-based deployment process within about 15
minutes after they are powered on. Log in to the devices and run the display
startup command to check whether the current system software and
configuration files are the required ones. The following shows the command
output of DeviceA.
<DeviceA> display startup
MainBoard:
Configured startup system software: flash:/software_file.cc
Startup system software: flash:/software_file.cc
Next startup system software: flash:/software_file.cc
Startup saved-configuration file: flash:/conf_file1.cfg
Next startup saved-configuration file: flash:/conf_file1.cfg
Startup paf file: default
Next startup paf file: default
Startup patch package: NULL
Next startup patch package: NULL
Startup feature software: NULL
Next startup feature software: NULL

Configuration Scripts
N/A

Issue 04 (2025-03-03) Copyright © Huawei Technologies Co., Ltd. 303

You might also like