diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6b37cbb..00e9223 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -16,28 +16,28 @@ jobs: steps: - uses: actions/checkout@v2 with: - path: ansible_collections/ciena/saos10 + path: ansible_collections/ciena/waveserverai - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} - name: Install collections run: | - ansible-galaxy collection install ansible.netcommon + ansible-galaxy collection install ansible.netcommon - name: Install dependencies - working-directory: ./ansible_collections/ciena/saos10 + working-directory: ./ansible_collections/ciena/waveserverai run: | pip install -r requirements.txt pip install -r requirements-test.txt - name: test - working-directory: ./ansible_collections/ciena/saos10 + working-directory: ./ansible_collections/ciena/waveserverai run: | ansible-test integration - name: build - working-directory: ./ansible_collections/ciena/saos10 + working-directory: ./ansible_collections/ciena/waveserverai run: | ansible-galaxy collection build - name: release - working-directory: ./ansible_collections/ciena/saos10 + working-directory: ./ansible_collections/ciena/waveserverai run: | ls *.tar.gz | xargs ansible-galaxy collection publish --api-key ${{ secrets.GALAXY_API_KEY }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 05c7caa..ec9ba6a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,17 @@ # Ciena WaveserverAi Collection Release Notes -## v1.0.3 +## v1.1.0 +### Added +- Added support for Waveserver Ai 2.5.0 +- System Module +- Xcvrs Module +- Ports Module +- Ptps Module +## v1.0.3 ### Fixed - Moved config_is_diff method to utils ## v1.0.0 - ### Added - Initial diff --git a/README.md b/README.md index 49828d8..43c67aa 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,17 @@ This collection has been tested against ## Ansible version compatibility -This collection has been tested against following Ansible versions: **>=2.9.10,<2.11**. + +## Ansible version compatibility + +This collection has been tested against following Ansible versions: **>=2.15.0**. + +For collections that support Ansible 2.9, please ensure you update your `network_os` to use the +fully qualified collection name (for example, `cisco.ios.ios`). +Plugins and modules within a collection may be tested with only specific Ansible versions. +A collection may contain metadata that identifies these versions. +PEP440 is the schema used to describe the versions of Ansible. + ### Supported connections @@ -15,12 +25,19 @@ Supports ``netconf`` connections. ## Included content +### Netconf plugins +Name | Description +--- | --- +[ciena.waveserverai.waveserverai](https://github.com/ciena/ciena.waveserverai/blob/master/docs/ciena.waveserverai.waveserverai_netconf.rst)|Use waveserverai netconf plugin to run netconf commands on Ciena waveserverai platform ### Modules -| Name | Description | -| ------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------- | -| [ciena.waveserverai.waveserverai_facts](https://github.com/ciena/ciena.waveserverai/blob/master/docs/waveserverai_facts.txt) | Collect facts from remote devices | -| [ciena.waveserverai.waveserverai_xcvrs](https://github.com/ciena/ciena.waveserverai/blob/master/docs/waveserverai_command.txt) | Set xcvr settings on remote devices | +Name | Description +--- | --- +[ciena.waveserverai.waveserverai_facts](https://github.com/ciena/ciena.waveserverai/blob/master/docs/ciena.waveserverai.waveserverai_facts_module.rst)|Get facts about waveserverai devices. +[ciena.waveserverai.waveserverai_ports](https://github.com/ciena/ciena.waveserverai/blob/master/docs/ciena.waveserverai.waveserverai_ports_module.rst)|Waveserver port configuration and operational data.Manage the ports ports configuration of a Ciena waveserverai device +[ciena.waveserverai.waveserverai_ptps](https://github.com/ciena/ciena.waveserverai/blob/master/docs/ciena.waveserverai.waveserverai_ptps_module.rst)|Waveserver Physical Termination Point (PTP) configuration and operational data.Manage the ptps ptps configuration of a Ciena waveserverai device +[ciena.waveserverai.waveserverai_system](https://github.com/ciena/ciena.waveserverai/blob/master/docs/ciena.waveserverai.waveserverai_system_module.rst)|Waveserver System configuration data and operational data.Manage the system configuration of a Ciena waveserverai device +[ciena.waveserverai.waveserverai_xcvrs](https://github.com/ciena/ciena.waveserverai/blob/master/docs/ciena.waveserverai.waveserverai_xcvrs_module.rst)|Waveserver transceivers (XCVR) configuration and operational data.Manage the xcvrs xcvrs configuration of a Ciena waveserverai device ## Installing this collection @@ -94,3 +111,8 @@ ansible-playbook -e rm_dest=$PATH_TO_ANSIBLE_COLLECTIONS_DIR \ ## Licensing See [LICENSE](LICENSE) to see the full text. + + + + + diff --git a/docs/ciena.waveserverai.waveserverai_facts_module.rst b/docs/ciena.waveserverai.waveserverai_facts_module.rst new file mode 100644 index 0000000..6a0ac0e --- /dev/null +++ b/docs/ciena.waveserverai.waveserverai_facts_module.rst @@ -0,0 +1,113 @@ +.. _ciena.waveserverai.waveserverai_facts_module: + + +************************************* +ciena.waveserverai.waveserverai_facts +************************************* + +**Get facts about waveserverai devices.** + + +Version added: 2.9 + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- Collects facts from network devices running the waveserverai operating system. This module places the facts gathered in the fact tree keyed by the respective resource name. The facts module will always collect a base set of facts from the device and can enable or disable collection of additional facts. + + + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsComments
+
+ gather_network_resources + +
+ - +
+
added in 2.9
+
+ +
When supplied, this argument will restrict the facts collected to a given subset. Possible values for this argument include all and the resources like interfaces, vlans etc. Can specify a list of values to include a larger subset. Values can also be used with an initial ! to specify that a specific subset should not be collected.
+
+
+ gather_subset + +
+ - +
+
added in 2.2
+
+ Default:
"all"
+
+
When supplied, this argument will restrict the facts collected to a given subset. Possible values for this argument include all, min, hardware, config, legacy, and interfaces. Can specify a list of values to include a larger subset. Values can also be used with an initial ! to specify that a specific subset should not be collected.
+
+
+ + + + +Examples +-------- + +.. code-block:: yaml + + # Gather all facts + - waveserverai_facts: + gather_subset: all + gather_network_resources: all + + # Collect only the xcvrs facts + - waveserverai_facts: + gather_subset: + - !all + - !min + gather_network_resources: + - xcvrs + + # Do not collect xcvrs facts + - waveserverai_facts: + gather_network_resources: + - "!xcvrs" + + # Collect xcvrs and minimal default facts + - waveserverai_facts: + gather_subset: min + gather_network_resources: xcvrs + + + + +Status +------ + + +Authors +~~~~~~~ + +- Ciena diff --git a/docs/ciena.waveserverai.waveserverai_netconf.rst b/docs/ciena.waveserverai.waveserverai_netconf.rst new file mode 100644 index 0000000..dd9a75e --- /dev/null +++ b/docs/ciena.waveserverai.waveserverai_netconf.rst @@ -0,0 +1,76 @@ +.. _ciena.waveserverai.waveserverai_netconf: + + +******************************* +ciena.waveserverai.waveserverai +******************************* + +**Use waveserverai netconf plugin to run netconf commands on Ciena waveserverai platform** + + +Version added: 1.0.0 + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- This waveserverai plugin provides low level abstraction apis for sending and receiving netconf commands from Ciena waveserverai network devices. + + + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + +
ParameterChoices/DefaultsConfigurationComments
+
+ ncclient_device_handler + +
+ string +
+
+ Default:
"default"
+
+ +
Specifies the ncclient device handler name for Ciena waveserverai network os. To identify the ncclient device handler name refer ncclient library documentation.
+
+
+ + + + + + + + +Status +------ + + +Authors +~~~~~~~ + +- Ciena + + +.. hint:: + Configuration entries for each entry type have a low to high priority order. For example, a variable that is lower in the list will override a variable that is higher up. diff --git a/docs/ciena.waveserverai.waveserverai_ports_module.rst b/docs/ciena.waveserverai.waveserverai_ports_module.rst new file mode 100644 index 0000000..5992c57 --- /dev/null +++ b/docs/ciena.waveserverai.waveserverai_ports_module.rst @@ -0,0 +1,1375 @@ +.. _ciena.waveserverai.waveserverai_ports_module: + + +************************************* +ciena.waveserverai.waveserverai_ports +************************************* + +**Waveserver port configuration and operational data.Manage the ports ports configuration of a Ciena waveserverai device** + + + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- Waveserver port configuration and operational data. Configuration and operational data for the port. + + + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsComments
+
+ config + +
+ list + / elements=dictionary +
+
+ +
Configuration and operational data for the port.
+
+
+ channels + +
+ list + / elements=dictionary +
+
+ +
List of ODU4 channels within the parent OTU port object.
+
+
+ channel_id + +
+ integer + / required +
+
+ +
Channel number or ODU4 tributary number within the parent OTU port object. Key value for the channels list. (Key for list: channels)
+
+
+ id + +
+ dictionary +
+
+ +
Channel identification attributes.
+
+
+ label + +
+ string +
+
+ +
The user-specified label string for this channel object.
+
+
+ properties + +
+ dictionary +
+
+ +
Channel properties.
+
+
+ odu_sd_threshold + +
+ string +
+
+ +
ODU4 Signal Degrade threshold value.
+
+
+ trace + +
+ dictionary +
+
+ +
ODU4 path trace attributes for this channel.
+
+
+ exp_dapi + +
+ string +
+
+ +
The expected destination access point identifier (DAPI) portion of the received trace string, up to 15 characters, excluding the first byte in the TTI DAPI overhead, which is implicitly always null.
+
+
+ exp_oper + +
+ string +
+
+ +
The expected operator-specific portion of the received trace string, up to 32 characters.
+
+
+ exp_sapi + +
+ string +
+
+ +
The expected source access point identifier (SAPI) portion of the received trace string, up to 15 characters, excluding the first byte in the TTI SAPI overhead, which is implicitly always null.
+
+
+ mismatch_fail_mode + +
+ string +
+
+
    Choices: +
  • none
  • +
  • alarm-only
  • +
  • squelch-traffic
  • +
+
+
The trail trace identifier (TTI) mismatch failure mode. When TTI mismatch condition occurs, this indicates the consequent action taken, e.g. whether or not to raise an alarm.
+
+
+ mismatch_mode + +
+ string +
+
+
    Choices: +
  • operator-only
  • +
  • sapi
  • +
  • dapi
  • +
  • sapi-and-dapi
  • +
+
+
The trail trace identifier (TTI) mismatch mode, indicating which fields of the TTI overhead are used for trace mismatch detection.
+
+
+ tx_dapi + +
+ string +
+
+ +
The destination access point identifier (DAPI) portion of the transmitted trace string, up to 15 characters, excluding the first byte in the TTI DAPI overhead, which is implicitly always null.
+
+
+ tx_oper + +
+ string +
+
+ +
The operator-specific portion of the transmitted trace string, up to 32 characters. Ignored if tx-oper-mode is 'automatic'.
+
+
+ tx_oper_mode + +
+ string +
+
+
    Choices: +
  • manual
  • +
  • automatic
  • +
+
+
Specifies whether to allow manual provisioning of the transmitted TTI string, or let the system assign this value automatically based on a pre-defined format.
+
+
+ tx_sapi + +
+ string +
+
+ +
The source access point identifier (SAPI) portion of the transmitted trace string, up to 15 characters, excluding the first byte in the TTI SAPI overhead, which is implicitly always null.
+
+
+ state + +
+ dictionary +
+
+ +
Channel administrative and operational states.
+
+
+ admin_state + +
+ string +
+
+
    Choices: +
  • disabled
  • +
  • enabled
  • +
+
+
The configured administrative state of the channel.
+
+
+ id + +
+ dictionary +
+
+ +
Port identification attributes.
+
+
+ label + +
+ string +
+
+ +
The user-specified label string for this port interface.
+
+
+ type + +
+ string +
+
+
    Choices: +
  • unknown
  • +
  • ethernet
  • +
  • otn
  • +
  • OTUk
  • +
  • OTUCn
  • +
  • OTUCn-Flex
  • +
  • ET
  • +
+
+
The port interface type.
+
+
+ port_id + +
+ string + / required +
+
+ +
Unique, access identifier string of the port in '<slot>-<port>' format. (Key for list: ports)
+
+
+ properties + +
+ dictionary +
+
+ +
Port properties.
+
+
+ connection_peer + +
+ list + / elements=dictionary +
+
+ +
Port connection peer list. Indicates the client/line port/channel that may be connected to this line/client port. For certain client ports, the connection state is user-configurable or can be system assigned on port creation based on bandwidth availability. For other ports, the connection state is fixed and cannot be manually configured.
+
+
+ peer_id + +
+ string + / required +
+
+ +
Specifies the client/line connection information for the port or channel. Client ports can be connected to a line-side channel or port. Line ports can be connected to a client side port. Line channels can be connected to one or more client ports. The connection mappings are static and provided by the system based on XCVR configuration. (Key for list: connection-peer)
+
+
+ connection_state + +
+ string +
+
+
    Choices: +
  • disabled
  • +
  • enabled
  • +
+
+
Specifies whether the line-side bandwidth is allocated for the connection between this client port and its connection peer. For most client port types, this is enabled by default and cannot be disabled. For certain client ports that can share line-side bandwidth with other client ports (such as on MOTR-AGG modules), the connection state can be manually configured by the user in order to assign or release the line-side bandwidth to the desired client. On the line-side, the connection state is read-only.
+
+
+ ethernet + +
+ dictionary +
+
+ +
Ethernet-specific properties.
+
+
+ conditioning_holdoff + +
+ integer +
+
+ +
Number of milliseconds to delay Egress UNI port consequent action for an EPL service.
+
+
+ conditioning_type + +
+ string +
+
+
    Choices: +
  • none
  • +
  • laser-off
  • +
  • ethernet
  • +
  • otn
  • +
  • protocol-specific
  • +
+
+
Egress UNI port consequent action for an EPL service to be applied on a far-end ingress UNI failure or network failure. Supported values are 'none', 'laser-off', and 'ethernet'.
+
+
+ loopback + +
+ string +
+
+
    Choices: +
  • disabled
  • +
  • rx
  • +
  • tx
  • +
+
+
Port PHY layer loopback. RX loopback is a loopback forwarding ingress traffic from RX port directly to TX port. TX loopback is a loopback forwarding egress traffic from TX port directly to RX port, TX loopback is not supported in I-NNI ports. The RX/TX loopback can only be enabled when the port admin-state is disabled. Enable an RX/TX loopback shall fail when the port has its admin-state enabled. Users shall be able to disable the xcvr/ptp when its child port loopback enabled. Enable xcvr/ptp shall not enable its child port with loopback enabled. A port shall has its operational state rx loopback when rx loopback is enabled, and tx loopback when tx loopback is enabled.
+
+
+ otn + +
+ dictionary +
+
+ +
OTN-specific properties.
+
+
+ conditioning_type + +
+ string +
+
+
    Choices: +
  • none
  • +
  • laser-off
  • +
  • ethernet
  • +
  • otn
  • +
  • protocol-specific
  • +
+
+
Conditioning type for OTN ports. Supported values are 'laser-off' and 'otn'.
+
+
+ odu_sd_threshold + +
+ string +
+
+ +
ODUk Signal Degrade threshold value, e.g. '1E-05' to '1E-09'.
+
+
+ odu_termination + +
+ string +
+
+
    Choices: +
  • terminated
  • +
  • passthrough
  • +
+
+
ODUk termination mode.
+
+
+ otu_sd_threshold + +
+ string +
+
+ +
OTU Signal Degrade threshold value, e.g. '1E-06' to '1E-09'.
+
+
+ overhead_aggregation_mode + +
+ string +
+
+
    Choices: +
  • single-slice
  • +
  • automatic
  • +
+
+
Overhead aggregation mode.
+
+
+ trace + +
+ dictionary +
+
+ +
OTN port trace attributes
+
+
+ path + +
+ dictionary +
+
+ +
ODUk path trace attributes for this port.
+
+
+ exp_dapi + +
+ string +
+
+ +
The expected destination access point identifier (DAPI) portion of the received trace string, up to 15 characters, excluding the first byte in the TTI DAPI overhead, which is implicitly always null.
+
+
+ exp_oper + +
+ string +
+
+ +
The expected operator-specific portion of the received trace string, up to 32 characters.
+
+
+ exp_sapi + +
+ string +
+
+ +
The expected source access point identifier (SAPI) portion of the received trace string, up to 15 characters, excluding the first byte in the TTI SAPI overhead, which is implicitly always null.
+
+
+ mismatch_fail_mode + +
+ string +
+
+
    Choices: +
  • none
  • +
  • alarm-only
  • +
  • squelch-traffic
  • +
+
+
The trail trace identifier (TTI) mismatch failure mode. When TTI mismatch condition occurs, this indicates the consequent action taken, e.g. whether or not to raise an alarm.
+
+
+ mismatch_mode + +
+ string +
+
+
    Choices: +
  • operator-only
  • +
  • sapi
  • +
  • dapi
  • +
  • sapi-and-dapi
  • +
+
+
The trail trace identifier (TTI) mismatch mode, indicating which fields of the TTI overhead are used for trace mismatch detection.
+
+
+ tx_dapi + +
+ string +
+
+ +
The destination access point identifier (DAPI) portion of the transmitted trace string, up to 15 characters, excluding the first byte in the TTI DAPI overhead, which is implicitly always null.
+
+
+ tx_oper + +
+ string +
+
+ +
The operator-specific portion of the transmitted trace string, up to 32 characters. Ignored if tx-oper-mode is 'automatic'.
+
+
+ tx_oper_mode + +
+ string +
+
+
    Choices: +
  • manual
  • +
  • automatic
  • +
+
+
Specifies whether to allow manual provisioning of the transmitted TTI string, or let the system assign this value automatically based on a pre-defined format.
+
+
+ tx_sapi + +
+ string +
+
+ +
The source access point identifier (SAPI) portion of the transmitted trace string, up to 15 characters, excluding the first byte in the TTI SAPI overhead, which is implicitly always null.
+
+
+ section + +
+ dictionary +
+
+ +
OTUk section trace attributes for this port.
+
+
+ exp_dapi + +
+ string +
+
+ +
The expected destination access point identifier (DAPI) portion of the received trace string, up to 15 characters, excluding the first byte in the TTI DAPI overhead, which is implicitly always null.
+
+
+ exp_oper + +
+ string +
+
+ +
The expected operator-specific portion of the received trace string, up to 32 characters.
+
+
+ exp_sapi + +
+ string +
+
+ +
The expected source access point identifier (SAPI) portion of the received trace string, up to 15 characters, excluding the first byte in the TTI SAPI overhead, which is implicitly always null.
+
+
+ mismatch_fail_mode + +
+ string +
+
+
    Choices: +
  • none
  • +
  • alarm-only
  • +
  • squelch-traffic
  • +
+
+
The trail trace identifier (TTI) mismatch failure mode. When TTI mismatch condition occurs, this indicates the consequent action taken, e.g. whether or not to raise an alarm.
+
+
+ mismatch_mode + +
+ string +
+
+
    Choices: +
  • operator-only
  • +
  • sapi
  • +
  • dapi
  • +
  • sapi-and-dapi
  • +
+
+
The trail trace identifier (TTI) mismatch mode, indicating which fields of the TTI overhead are used for trace mismatch detection.
+
+
+ tx_dapi + +
+ string +
+
+ +
The destination access point identifier (DAPI) portion of the transmitted trace string, up to 15 characters, excluding the first byte in the TTI DAPI overhead, which is implicitly always null.
+
+
+ tx_oper + +
+ string +
+
+ +
The operator-specific portion of the transmitted trace string, up to 32 characters. Ignored if tx-oper-mode is 'automatic'.
+
+
+ tx_oper_mode + +
+ string +
+
+
    Choices: +
  • manual
  • +
  • automatic
  • +
+
+
Specifies whether to allow manual provisioning of the transmitted TTI string, or let the system assign this value automatically based on a pre-defined format.
+
+
+ tx_sapi + +
+ string +
+
+ +
The source access point identifier (SAPI) portion of the transmitted trace string, up to 15 characters, excluding the first byte in the TTI SAPI overhead, which is implicitly always null.
+
+
+ state + +
+ dictionary +
+
+ +
Port administrative and operational states.
+
+
+ admin_state + +
+ string +
+
+
    Choices: +
  • enabled
  • +
  • disabled
  • +
+
+
The configured administrative state of the port.
+
+
+ state + +
+ string +
+
+
    Choices: +
  • merged ←
  • +
+
+
The state of the configuration
+
+
+ + + + +Examples +-------- + +.. code-block:: yaml + + # Using merged + + - name: Disable port + ciena.waveserver5.waveserver5_ports: + config: + - port_id: 5-1 + state: + admin_state: disabled + state: merged + - name: Enable port + ciena.waveserver5.waveserver5_ports: + config: + - port_id: 5-1 + state: + admin_state: enabled + state: merged + + + +Return Values +------------- +Common return values are documented `here `_, the following are the fields unique to this module: + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + +
KeyReturnedDescription
+
+ after + +
+ dictionary +
+
when changed +
The resulting configuration model invocation.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ before + +
+ dictionary +
+
always +
The configuration prior to the model invocation.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ xml + +
+ list +
+
always +
The set of xml commands pushed to the remote device.
+
+
Sample:
+
['<system xmlns="http://openconfig.net/yang/system"><config><hostname>foo</hostname></config></system>']
+
+

+ + +Status +------ + + +Authors +~~~~~~~ + +- Ciena diff --git a/docs/ciena.waveserverai.waveserverai_ptps_module.rst b/docs/ciena.waveserverai.waveserverai_ptps_module.rst new file mode 100644 index 0000000..1b841f3 --- /dev/null +++ b/docs/ciena.waveserverai.waveserverai_ptps_module.rst @@ -0,0 +1,614 @@ +.. _ciena.waveserverai.waveserverai_ptps_module: + + +************************************ +ciena.waveserverai.waveserverai_ptps +************************************ + +**Waveserver Physical Termination Point (PTP) configuration and operational data.Manage the ptps ptps configuration of a Ciena waveserverai device** + + + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- Waveserver Physical Termination Point (PTP) configuration and operational data. List of PTP objects. + + + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsComments
+
+ config + +
+ list + / elements=dictionary +
+
+ +
List of PTP objects.
+
+
+ id + +
+ dictionary +
+
+ +
Identification information of this PTP instance.
+
+
+ label + +
+ string +
+
+ +
Label of the PTP instance
+
+
+ properties + +
+ dictionary +
+
+ +
All the configurable and operational data of this PTP instance.
+
+
+ forward_error_correction + +
+ string +
+
+
    Choices: +
  • disabled
  • +
  • enabled
  • +
  • automatic
  • +
+
+
FEC - disabled, enabled, automatic. FEC format is determined by modem
+
+
+ is_coherent + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Indicate whether or not this ptp can support coherent attributes
+
+
+ thresholds + +
+ dictionary +
+
+ +
Common container for PTP threshold configuration data.
+
+
+ fec_detected_degrade_threshold + +
+ string +
+
+ +
FEC Signal Degrade configurable threshold, expressed in exponential notation, e.g. '1E-06' to '1E-09'.
+
+
+ fec_excessive_degrade_threshold + +
+ string +
+
+ +
FEC Signal Fail configurable threshold, expressed in exponential notation, e.g. '1E-06' to '1E-09'.
+
+
+ hccs_db + +
+ float +
+
+ +
High Correction Count Second (HCCS) Threshold, expressed in dB notation.
+
+
+ pre_fec_sd_db + +
+ float +
+
+ +
Pre-FEC Signal Degrade threshold value, expressed in dB notation.
+
+
+ pre_fec_sf_db + +
+ float +
+
+ +
Pre-FEC Signal Fail threshold value, expressed in dB notation.
+
+
+ topology_adjacency + +
+ dictionary +
+
+ +
Container for PTP topology adjacency data.
+
+
+ port_in + +
+ string +
+
+ +
Port in.
+
+
+ port_out + +
+ string +
+
+ +
Port out.
+
+
+ transmitter + +
+ dictionary +
+
+ +
PTP transmitter related config and operational data fields.
+
+
+ state + +
+ string +
+
+
    Choices: +
  • disabled
  • +
  • enabled
  • +
  • not-applicable
  • +
+
+
Transmitter state (enabled or disabled) of the PTP. PTP Admin State cannot be changed to enabled unless the transmitter state is enabled.
+
+
+ type + +
+ string +
+
+
    Choices: +
  • unknown
  • +
  • WLAi
  • +
  • WLAi-iOPS
  • +
  • 4x25G
  • +
  • 10G
  • +
  • OCH
  • +
  • OSC
  • +
  • OSC-Add-Drop
  • +
  • OTM
  • +
  • WL5e
  • +
  • WL5n
  • +
  • 100G
  • +
  • 4x100G
  • +
  • 8x50G
  • +
  • 2x50G
  • +
  • 400ZR
  • +
+
+
Physical Termination Point type.
+
+
+ xcvr_type + +
+ string +
+
+
    Choices: +
  • not-available
  • +
  • unsupported
  • +
  • QSFPplus
  • +
  • QSFP28
  • +
  • WaveLogic 3 Extreme
  • +
  • WaveLogic Ai
  • +
  • SFP
  • +
  • none
  • +
  • QSFP-DD
  • +
  • WaveLogic 5e
  • +
  • CFP2-DCO
  • +
+
+
Transceiver type of the XCVR that's associated with this PTP. Type depends on what is physically plugged in. Read only attribute.
+
+
+ ptp_id + +
+ string + / required +
+
+ +
Unique, access identifier string of the PTP (e.g., '1-1'). Key value for the PTP list. Read-only attribute. (Key for list: ptps)
+
+
+ state + +
+ dictionary +
+
+ +
State information of this PTP instance.
+
+
+ admin_state + +
+ string +
+
+
    Choices: +
  • disabled
  • +
  • enabled
  • +
+
+
Administrative state (enabled or disabled) of the PTP. If Admin State is set to enabled, majority of the PTP fields will no longer be modifiable. When PTP Transmitter State is Disabled, PTP Admin State cannot be changed from Disabled to Enabled.
+
+
+ spli_management + +
+ string +
+
+
    Choices: +
  • disabled
  • +
  • enabled
  • +
+
+
Whether or not Service Photonic Layer Interoperations management protocol is enabled on this PTP.
+
+
+ state + +
+ string +
+
+
    Choices: +
  • merged ←
  • +
+
+
The state of the configuration
+
+
+ + + + +Examples +-------- + +.. code-block:: yaml + + # Using merged + + - name: Disable ptp + ciena.waveserver5.waveserver5_ptps: + config: + - ptp_id: 5-1 + state: + admin_state: disabled + state: merged + - name: Enable ptp + ciena.waveserver5.waveserver5_ptps: + config: + - ptp_id: 5-1 + state: + admin_state: enabled + state: merged + + + +Return Values +------------- +Common return values are documented `here `_, the following are the fields unique to this module: + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + +
KeyReturnedDescription
+
+ after + +
+ dictionary +
+
when changed +
The resulting configuration model invocation.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ before + +
+ dictionary +
+
always +
The configuration prior to the model invocation.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ xml + +
+ list +
+
always +
The set of xml commands pushed to the remote device.
+
+
Sample:
+
['<system xmlns="http://openconfig.net/yang/system"><config><hostname>foo</hostname></config></system>']
+
+

+ + +Status +------ + + +Authors +~~~~~~~ + +- Ciena diff --git a/docs/ciena.waveserverai.waveserverai_system_module.rst b/docs/ciena.waveserverai.waveserverai_system_module.rst new file mode 100644 index 0000000..2b6bc11 --- /dev/null +++ b/docs/ciena.waveserverai.waveserverai_system_module.rst @@ -0,0 +1,4400 @@ +.. _ciena.waveserverai.waveserverai_system_module: + + +************************************** +ciena.waveserverai.waveserverai_system +************************************** + +**Waveserver System configuration data and operational data.Manage the system configuration of a Ciena waveserverai device** + + + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- Waveserver System configuration data and operational data. + + + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsComments
+
+ config + +
+ dictionary +
+
+ +
Waveserver System configuration data and operational data.
+
+
+ auto_config_recovery + +
+ dictionary +
+
+ +
Waveserver system automatic configuration recovery for CP replacement attributes.
+
+
+ admin_state + +
+ string +
+
+
    Choices: +
  • disabled
  • +
  • enabled
  • +
+
+
Indicate whether auto config recovery is enabled.
+
+
+ audit_interval + +
+ integer +
+
+ +
Audit Interval in minutes.
+
+
+ config_mismatch_detection_state + +
+ string +
+
+
    Choices: +
  • disabled
  • +
  • enabled
  • +
+
+
Indicate whether config mismatch detection for CP replacement is enabled.
+
+
+ passphrase + +
+ string +
+
+ +
Passphrase used for backup encryption (Default; none, use builtin key).
+
+
+ client_config + +
+ dictionary +
+
+ +
Waveserver client configuration attributes.
+
+
+ dhcp + +
+ dictionary +
+
+ +
Waveserver DHCP client configuration attributes.
+
+
+ admin_state + +
+ string +
+
+
    Choices: +
  • disabled
  • +
  • enabled
  • +
+
+
DHCP client administrative atate
+
+
+ discovery_interval + +
+ integer +
+
+ +
DHCP client discovery interval in seconds.
+
+
+ interface_type + +
+ string +
+
+
    Choices: +
  • remote
  • +
  • active
  • +
+
+
DHCP client interface type.
+
+
+ options + +
+ dictionary +
+
+ +
DHCP Options. A list of the enabled/requested options configured on the DHCP client.
+
+
+ bootfile_name + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
DHCP Option 67 - Bootfile Name.
+
+
+ domain_name + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
DHCP Option 15 - Domain Name.
+
+
+ domain_server + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
DHCP Option 6 - Domain Name Server.
+
+
+ host_name + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
DHCP Option 12 - Host Name.
+
+
+ lease_time + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
DHCP Option 51 - Lease Time.
+
+
+ log_server + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
DHCP Option 7 - Log Server.
+
+
+ ntp_servers + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
DHCP Option 42 - Network Time Protocol Servers.
+
+
+ router + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
DHCP Option 3 - Router.
+
+
+ subnet_mask + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
DHCP Option 1 - Subnet Mask.
+
+
+ tftp_server_name + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
DHCP Option 66 - TFTP Server Name.
+
+
+ time_offset + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
DHCP Option 2 - Time Offset.
+
+
+ requested_lease_time + +
+ integer +
+
+ +
DHCP client requested lease time in seconds.
+
+
+ dhcpv6 + +
+ dictionary +
+
+ +
Waveserver DHCPv6 client configuration attributes.
+
+
+ admin_state + +
+ string +
+
+
    Choices: +
  • disabled
  • +
  • enabled
  • +
+
+
DHCPv6 client administrative atate
+
+
+ options_state + +
+ dictionary +
+
+ +
DHCPv6 Options. A list of the enabled/requested options configured on the DHCPv6 client.
+
+
+ bootfile_url + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
DHCPv6 Option 59 - Bootfile URL.
+
+
+ dns_servers + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
DHCPv6 Option 23 - Domain Name System Servers.
+
+
+ ntp_server + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
DHCPv6 Option 56 - Network Time Protocol Servers.
+
+
+ dns + +
+ dictionary +
+
+ +
Waveserver DNS client configuration attributes.
+
+
+ admin_state + +
+ string +
+
+
    Choices: +
  • disabled
  • +
  • enabled
  • +
+
+
DNS client administrative state.
+
+
+ server + +
+ list + / elements=dictionary +
+
+ +
List of DNS servers to use for domain name resolution. DNS servers can be manually created by the user, or dynamically created by via DHCP. Waveserver supports up to 3 manually provisioned DNS servers and up to 2 DHCP-assigned servers.
+
+
+ admin_state + +
+ string +
+
+
    Choices: +
  • disabled
  • +
  • enabled
  • +
+
+
DNS remote server administrative state.
+
+
+ ip_address + +
+ string + / required +
+
+ +
IP address associated with the remote DNS server. (Key for list: server)
+
+
+ user_priority + +
+ integer +
+
+ +
User-assigned DNS server priority. Only applicable when server source is 'user' or 'both'. Ignored otherwise.
+
+
+ grpc + +
+ dictionary +
+
+ +
Waveserver gRPC Client configuration attributes.
+
+
+ server + +
+ list + / elements=dictionary +
+
+ +
List of remote servers. Entries may be configured in this list to configure trusted-dns on a per-server basis, for example in certain dial-out telemetry operational workflows.
+
+
+ address + +
+ string + / required +
+
+ +
Configured IP address or Domain Name of the remote server/collector. (Key for list: server)
+
+
+ trusted_dns + +
+ string + / required +
+
+ +
Trusted DNS name used to check peer's certificate. The name should be a fully qualified domain name.
+
+
+ ntp + +
+ dictionary +
+
+ +
Waveserver NTP client configuration attributes.
+
+
+ admin_state + +
+ string +
+
+
    Choices: +
  • disabled
  • +
  • enabled
  • +
+
+
NTP client administrative state.
+
+
+ authentication_state + +
+ string +
+
+
    Choices: +
  • disabled
  • +
  • enabled
  • +
+
+
NTP client authentication state. When enabled, only MD5 authenticated packets will be used to synchronize the time.
+
+
+ autokey_authentication_state + +
+ string +
+
+
    Choices: +
  • disabled
  • +
  • enabled
  • +
+
+
NTP client autokey authentication state. A RSA host key and an X509 certificate (RSA-SHA1) will be created (if not exist) and saved. The host key and certificate will be loaded to NTP daemon only if the NTP autokey is enabled on Waveserver
+
+
+ mode + +
+ string +
+
+
    Choices: +
  • polling
  • +
  • broadcast
  • +
  • multicast
  • +
+
+
NTP client mode.
+
+
+ multicast_server + +
+ list + / elements=dictionary +
+
+ +
List of NTP multicast servers to use for time synchronization.
+
+
+ ip_address + +
+ string + / required +
+
+ +
Configured IPv6 address for NTP Multicast server. (Key for list: multicast-server)
+
+
+ ntp_key + +
+ list + / elements=dictionary +
+
+ +
List of NTP authentication keys.
+
+
+ key_id + +
+ integer + / required +
+
+ +
Unique index value for the NTP authentication key. (Key for list: ntp-key)
+
+
+ key_type + +
+ string +
+
+
    Choices: +
  • MD5
  • +
  • SHA1
  • +
+
+
Encryption type used for the NTP authentication key.
+
+
+ key_value + +
+ string +
+
+ +
NTP authentication key value.
+
+
+ polling_interval + +
+ integer +
+
+ +
The NTP client polling interval, in seconds. Applicable only when NTP client mode is set to 'polling'. This is a global setting that applies to all configured NTP peer servers.
+
+
+ server + +
+ list + / elements=dictionary +
+
+ +
List of NTP servers to use for time synchronization.
+
+
+ address + +
+ string + / required +
+
+ +
Configured IP address or Domain Name of the remote NTP server. (Key for list: server)
+
+
+ admin_state + +
+ string +
+
+
    Choices: +
  • disabled
  • +
  • enabled
  • +
+
+
NTP remote server administrative state.
+
+
+ autokey_authentication + +
+ string +
+
+
    Choices: +
  • disabled
  • +
  • enabled
  • +
+
+
Whether autokey authentication method is enabled for the server. The 'enabled' state will only be effective when the 'ntp/authentication-state' is 'enabled'.
+
+
+ key_id + +
+ string +
+
+ +
Leafref to 'ntp-key' list 'key-id' values.
+
+
+ sha1key_authentication_state + +
+ string +
+
+
    Choices: +
  • disabled
  • +
  • enabled
  • +
+
+
NTP SHA1 administrative state. When enabled, only SHA1 authenticated packets will be used to synchronize the time.
+
+
+ default_settings + +
+ dictionary +
+
+ +
Waveserver system default configuration values.
+
+
+ conditioning + +
+ dictionary +
+
+ +
Waveserver system default conditioning values. Ports are created with these values. When the system defaults are set, all existing ports have their values updated.
+
+
+ holdoff + +
+ integer +
+
+ +
Number of milliseconds the failure must be present before applying Egress UNI port consequent action for an EPL service.
+
+
+ type + +
+ string +
+
+
    Choices: +
  • none
  • +
  • laser-off
  • +
  • ethernet
  • +
  • otn
  • +
  • protocol-specific
  • +
+
+
Egress UNI port consequent action for an EPL service to be applied on a far-end ingress UNI failure or network failure.
+
+
+ remote_management_auto_enable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable GCC interfaces when module is created.
+
+
+ terrestrial_reach_limit + +
+ integer +
+
+ +
The maximum reach allowed in km. The possible values are [250, 500, 1000, 2000, 2100, 3000, 4000, 5000, 8000] for terrestrial modem class. [0] if the value is unknown/unavailable or inapplicable.
+
+
+ domain_name + +
+ dictionary +
+
+ +
Waveserver system domain name attributes.
+
+
+ config_domain_name + +
+ string +
+
+ +
User configured domain name.
+
+
+ environment + +
+ dictionary +
+
+ +
Waveserver system linux environment attributes.
+
+
+ diag + +
+ dictionary +
+
+ +
System level default environment configuration for diag level users.
+
+
+ shell + +
+ string +
+
+
    Choices: +
  • cli
  • +
  • system
  • +
+
+
The default shell session type for authenticated diag users.
+
+
+ sudo + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Specifies whether or not diag users will be automatically added to the sudoers list. Default is disabled.
+
+
+ root + +
+ dictionary +
+
+ +
Waveserver system user root configuration.
+
+
+ password + +
+ string +
+
+ +
User root password string.
+
+
+ secret + +
+ string +
+
+ +
The encrypted user password string, supplied as a hashed value.
+
+
+ shell + +
+ dictionary +
+
+ +
System level default environment configuration for diagnostic shell access.
+
+
+ admin_state + +
+ string +
+
+
    Choices: +
  • disabled
  • +
  • enabled
  • +
+
+
Diagnostic shell access control. Default value is enabled. Only super level user is allowed to change to disabled. Setting back to enabled state requires a reset-to-factory-defaults. When disabled, diag user cannot access the diagnostic shell. Root account is blocked from logging in to the console port. CLI commands to modify files on the filesystem are rejected.
+
+
+ global_provisioning + +
+ dictionary +
+
+ +
Waveserver system global provisioning attributes.
+
+
+ encryption_only + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
A boolean value indicating whether the current chassis configuration requires encryption modules only. If true, a user-initiated request to pre-create clear-text MOTR equipment will be rejected.
+
+
+ line_config + +
+ dictionary +
+
+ +
Waveserver system line configuration.
+
+
+ line_protection + +
+ string +
+
+
    Choices: +
  • unprotected
  • +
  • trunk-ops
  • +
+
+
Line protection settings. If line protection is enabled, this means that the photonic line the Waveserver is connected to has protection enabled. In the event of a line side fault, the protection card on the line side will select the protection path and the modems will reacquire the signal on the alternate path. While the switch is occuring, link state messaging will be disabled to the clients so that the connected devices do not attempt a switch or a restoration.
+
+
+ host_name + +
+ dictionary +
+
+ +
Waveserver system host name attributes.
+
+
+ config_host_name + +
+ string +
+
+ +
User configured host name.
+
+
+ id + +
+ dictionary +
+
+ +
Waveserver system identification attributes.
+
+
+ group + +
+ dictionary +
+
+ +
Waveserver system group attributes.
+
+
+ description + +
+ string +
+
+ +
A description for the group of Waveservers.
+
+
+ id + +
+ integer +
+
+ +
An integer to uniquely identify a group of Waveservers within a site.
+
+
+ name + +
+ string +
+
+ +
A name for the group of Waveservers.
+
+
+ member + +
+ dictionary +
+
+ +
Waveserver system member attributes.
+
+
+ cluster_enrollment + +
+ string +
+
+
    Choices: +
  • disabled
  • +
  • enabled
  • +
+
+
Attribute indicating if the waveserver member is enrolled into culster.
+
+
+ description + +
+ string +
+
+ +
A description for the Waveserver chassis.
+
+
+ frame_identification + +
+ string +
+
+ +
A description to identify the location of the Waveserver chassis within the data center. For example, the building, floor, aisle, frame number, etc.
+
+
+ id + +
+ integer +
+
+ +
An integer to uniquely identify a Waveserver chassis within a group of Waveservers.
+
+
+ name + +
+ string +
+
+ +
A name for the Waveserver chassis. Set to the host name by default.
+
+
+ rack_unit_number + +
+ integer +
+
+ +
A logical identifier for the location of the Waveserver within the frame or rack. For example, the device at the top could be labeled unit 1.
+
+
+ network + +
+ dictionary +
+
+ +
Waveserver system network attributes.
+
+
+ description + +
+ string +
+
+ +
A description for the sub-network domain.
+
+
+ id + +
+ integer +
+
+ +
An integer to uniquely identify the sub-network domain in which this Waveserver chassis is managed.
+
+
+ name + +
+ string +
+
+ +
A name for the sub-network domain.
+
+
+ site + +
+ dictionary +
+
+ +
Waveserver system site attributes.
+
+
+ address + +
+ string +
+
+ +
The street address of the site.
+
+
+ description + +
+ string +
+
+ +
The site description
+
+
+ id + +
+ integer +
+
+ +
An integer to uniquely identify the site where this Waveserver is located. This is used to help group Waveservers together with line system equipment. All equipment in a common site should share the same site identifier.
+
+
+ latitude + +
+ float +
+
+ +
Geographic coordinate for the site location in degrees.
+
+
+ longitude + +
+ float +
+
+ +
Geographic coordinate for the site location in degrees.
+
+
+ name + +
+ string +
+
+ +
The name for the site where the Waveserver is located.
+
+
+ lamp_test + +
+ dictionary +
+
+ +
Waveserver lamp test attributes.
+
+
+ admin_state + +
+ string +
+
+
    Choices: +
  • disabled
  • +
  • enabled
  • +
+
+
Enable or disable the system lamp test. The lamp-test admin-state will be automatically disabled once the timeout period has expired.
+
+
+ target_id + +
+ string +
+
+ +
Lamp testing target ID string. Must be specified when target-type is 'slot' or 'port'. When the target-type is 'slot' the target-id should be a slot number (e.g. 1, 2, or 3). When the target-type is 'port' the target-id should be a port-id (e.g. '1-1') or comma-separated list of port-id's (e.g. '1-1,1-2,1-3').
+
+
+ target_type + +
+ string +
+
+
    Choices: +
  • chassis
  • +
  • slot
  • +
  • port
  • +
+
+
Lamp testing target type. It can be chassis, slot, or port. The default type is chassis. When the target-type is slot or port, the slot/port identifier should also be set for the selected target(s) to be tested.
+
+
+ timeout + +
+ integer +
+
+ +
The number of seconds the lamp flash testing will be operating when enabled.
+
+
+ management + +
+ dictionary +
+
+ +
Waveserver system management configuration attributes.
+
+
+ caching + +
+ dictionary +
+
+ +
Run time cache setting for config operations on management interfaces.
+
+
+ openconfig + +
+ string +
+
+
    Choices: +
  • disabled
  • +
  • enabled
  • +
+
+
OpenConfig cache config enable or disable.
+
+
+ query_limits + +
+ dictionary +
+
+ +
Run time query limits for get operations on management interfaces.
+
+
+ gnmi + +
+ dictionary +
+
+ +
gNMI protocol source type.
+
+
+ pm_history_bins + +
+ integer +
+
+ +
Maximum query limit for PM history bins in gNMI get responses.
+
+
+ netconf + +
+ dictionary +
+
+ +
NETCONF protocol source type.
+
+
+ pm_history_bins + +
+ integer +
+
+ +
Maximum query limit for PM history bins in NETCONF get responses.
+
+
+ rest + +
+ dictionary +
+
+ +
REST protocol source type.
+
+
+ pm_history_bins + +
+ integer +
+
+ +
Maximum query limit for PM history bins in REST get responses.
+
+
+ root_scope + +
+ dictionary +
+
+ +
Control for root-level get and replace operations for management interfaces.
+
+
+ gnmi + +
+ dictionary +
+
+ +
gNMI protocol source type.
+
+
+ get + +
+ string +
+
+
    Choices: +
  • native
  • +
  • openconfig
  • +
  • all
  • +
+
+
Scope for gNMI root-level get operations.
+
+
+ replace + +
+ string +
+
+
    Choices: +
  • native
  • +
  • openconfig
  • +
  • all
  • +
+
+
Scope for gNMI root-level replace operations.
+
+
+ netconf + +
+ dictionary +
+
+ +
NETCONF protocol source type.
+
+
+ get + +
+ string +
+
+
    Choices: +
  • native
  • +
  • openconfig
  • +
  • all
  • +
+
+
Scope for NETCONF root-level get operations.
+
+
+ replace + +
+ string +
+
+
    Choices: +
  • native
  • +
  • openconfig
  • +
  • all
  • +
+
+
Scope for NETCONF root-level replace operations.
+
+
+ rest + +
+ dictionary +
+
+ +
REST protocol source type.
+
+
+ get + +
+ string +
+
+
    Choices: +
  • native
  • +
  • openconfig
  • +
  • all
  • +
+
+
Scope for REST root-level get operations.
+
+
+ replace + +
+ string +
+
+
    Choices: +
  • native
  • +
  • openconfig
  • +
  • all
  • +
+
+
Scope for REST root-level replace operations.
+
+
+ server_config + +
+ dictionary +
+
+ +
Waveserver system server configuration attributes.
+
+
+ global_inactivity_timeout + +
+ integer +
+
+ +
Global session inactivity timeout period, in minutes. Can be overridden by specific server type settings, if applicable.
+
+
+ global_inactivity_timer + +
+ string +
+
+
    Choices: +
  • disabled
  • +
  • enabled
  • +
+
+
Global session inactivity timer state.
+
+
+ grpc + +
+ dictionary +
+
+ +
gRPC server configuration.
+
+
+ admin_state + +
+ string +
+
+
    Choices: +
  • disabled
  • +
  • enabled
  • +
+
+
gRPC server administrative state.
+
+
+ certificate_verification + +
+ dictionary +
+
+ +
gRPC server configuration data for client certificate verification through mutual authentication.
+
+
+ certificate_name + +
+ string +
+
+ +
The certificate name used by the gRPC server.
+
+
+ mutual_authentication + +
+ dictionary +
+
+ +
gRPC server mutual authentication configuration data.
+
+
+ admin_state + +
+ string +
+
+
    Choices: +
  • disabled
  • +
  • enabled
  • +
+
+
Whether gRPC server mutual authentication verification is enabled or disabled.
+
+
+ grpc_server_state + +
+ string +
+
+
    Choices: +
  • disabled
  • +
  • enabled
  • +
+
+
Indicate whether gRPC server is enabled. This leaf is deprecated, replaced by admin-state in grpc container.
+
+
+ https + +
+ dictionary +
+
+ +
HTTPS server configuration.
+
+
+ admin_state + +
+ string +
+
+
    Choices: +
  • disabled
  • +
  • enabled
  • +
+
+
HTTPS server administrative state.
+
+
+ certificate_verification + +
+ dictionary +
+
+ +
The HTTPS server configuration data for client certificate verification through mutual authentication and Online Certificate Status Protocol(OCSP).
+
+
+ certificate_name + +
+ string +
+
+ +
The certificate name used by the HTTPS server.
+
+
+ mutual_authentication + +
+ dictionary +
+
+ +
HTTPS server mutual authentication configuration data.
+
+
+ admin_state + +
+ string +
+
+
    Choices: +
  • disabled
  • +
  • enabled
  • +
+
+
Whether apache HTTPS server mutual authentication verification is enabled or disabled.
+
+
+ ocsp + +
+ dictionary +
+
+ +
HTTPS server configuration data for OCSP verification.
+
+
+ admin_state + +
+ string +
+
+
    Choices: +
  • disabled
  • +
  • enabled
  • +
+
+
Whether OCSP verification is enabled or disabled.
+
+
+ default_responder + +
+ string +
+
+ +
Default OCSP responder. It should be in URL format. e.g. https;//192.168.20.2;2440. If the 'responder-preference' is not set to 'default-responder', the URL given will be used only if no responder URL (AIA extension) is specified in the client certificate being verified.
+
+
+ nonce + +
+ string +
+
+
    Choices: +
  • off
  • +
  • on
  • +
+
+
Determine whether queries to OCSP responders should contain a nonce or not. By default nonce option is turned on.
+
+
+ responder_preference + +
+ string +
+
+
    Choices: +
  • aia
  • +
  • default-responder
  • +
+
+
If 'responder-preference' is set to aia, the OCSP responder referred in client certificate AIA extension will be used first during OCSP certificate validation. If it is set to 'default-responder', the configured default OCSP responder is used first.
+
+
+ trusted_dns + +
+ string +
+
+ +
Trusted DNS name used to check peer's certificate. The name should be fully qualified whenever possible, and can accept a leading period as wildcard.
+
+
+ craft_gui_admin_state + +
+ string +
+
+
    Choices: +
  • disabled
  • +
  • enabled
  • +
+
+
Craft GUI administrative state.
+
+
+ inactivity_timeout + +
+ integer +
+
+ +
HTTPS inactivity timeout period, in minutes.
+
+
+ web_ui_file_transfer_admin_state + +
+ string +
+
+
    Choices: +
  • disabled
  • +
  • enabled
  • +
+
+
Web Ui File Transfer administrative state.
+
+
+ netconf + +
+ dictionary +
+
+ +
NETCONF server configuration.
+
+
+ admin_state + +
+ string +
+
+
    Choices: +
  • disabled
  • +
  • enabled
  • +
+
+
Indicate whether NETCONF server is enabled.
+
+
+ candidate_advertisement + +
+ string +
+
+
    Choices: +
  • disabled
  • +
  • enabled
  • +
+
+
Whether NETCONF candidate advertisement is enabled or disabled.
+
+
+ netconf_server_state + +
+ string +
+
+
    Choices: +
  • disabled
  • +
  • enabled
  • +
+
+
Indicate whether NETCONF server is enabled.
+
+
+ scp_server_state + +
+ string +
+
+
    Choices: +
  • disabled
  • +
  • enabled
  • +
+
+
Indicate whether SCP server is enabled.
+
+
+ sftp_server_state + +
+ string +
+
+
    Choices: +
  • disabled
  • +
  • enabled
  • +
+
+
Indicate whether SFTP server is enabled.
+
+
+ ssh + +
+ dictionary +
+
+ +
SSH server configuration.
+
+
+ algorithms + +
+ dictionary +
+
+ +
Waveserver SSH algorithm lists.
+
+
+ encryption + +
+ list + / elements=dictionary +
+
+ +
List of SSH encryption algorithms. The algorithm names are system assigned.
+
+
+ admin_state + +
+ string +
+
+
    Choices: +
  • disabled
  • +
  • enabled
  • +
+
+
SSH encryption algorithm administrative state.
+
+
+ algorithm_name + +
+ string + / required +
+
+ +
The SSH encryption algorithm name. (Key for list: encryption)
+
+
+ key_exchange + +
+ list + / elements=dictionary +
+
+ +
List of SSH key exchange algorithms. The algorithm names are system assigned.
+
+
+ admin_state + +
+ string +
+
+
    Choices: +
  • disabled
  • +
  • enabled
  • +
+
+
SSH key exchange algorithm administrative state.
+
+
+ algorithm_name + +
+ string + / required +
+
+ +
The SSH key exchange algorithm name. (Key for list: key-exchange)
+
+
+ message_authentication_code + +
+ list + / elements=dictionary +
+
+ +
List of SSH message authentication code algorithms. The algorithm names are system assigned.
+
+
+ admin_state + +
+ string +
+
+
    Choices: +
  • disabled
  • +
  • enabled
  • +
+
+
SSH message authentication code algorithm administrative state.
+
+
+ algorithm_name + +
+ string + / required +
+
+ +
The SSH message authentication code algorithm name. (Key for list: message-authentication-code)
+
+
+ public_key_authentication + +
+ list + / elements=dictionary +
+
+ +
List of SSH public key authentication algorithms. The algorithm names are system assigned.
+
+
+ admin_state + +
+ string +
+
+
    Choices: +
  • disabled
  • +
  • enabled
  • +
+
+
SSH public key authentication algorithm administrative state.
+
+
+ algorithm_name + +
+ string + / required +
+
+ +
The SSH public key authentication algorithm name. (Key for list: public-key-authentication)
+
+
+ allowed_clients + +
+ list + / elements=dictionary +
+
+ +
List of allowed client IP addresses.
+
+
+ ip_address + +
+ string + / required +
+
+ +
IP address for allowed SSH clients. When the list is not empty, only the clients in the list can login to the SSH server. (Key for list: allowed-clients)
+
+
+ authentication_retries + +
+ integer +
+
+ +
Number of authentication retries allowed before the SSH connection is dropped.
+
+
+ listener_port + +
+ integer +
+
+ +
Configured SSH listener port. Default is port 22.
+
+
+ web_server_state + +
+ string +
+
+
    Choices: +
  • disabled
  • +
  • enabled
  • +
+
+
Indicate whether web server is enabled, HTTPS only. This leaf is deprecated, replaced by admin-state in https container.
+
+
+ shell + +
+ dictionary +
+
+ +
Waveserver system CLI shell/session attributes.
+
+
+ inactivity_timeout + +
+ string +
+
+ +
Leafref to global session inactivity timeout period, in minutes. This attribute is deprecated. Has been moved to server-config container.
+
+
+ inactivity_timer + +
+ string +
+
+ +
Leafref to global session inactivity timer state. This attribute is deprecated. Has been moved to server-config container.
+
+
+ login_authentication_message + +
+ string +
+
+
    Choices: +
  • disabled
  • +
  • enabled
  • +
+
+
Toggles the authentication message for CLI/shell session logins.
+
+
+ login_banner_file + +
+ string +
+
+ +
Local file name containing the banner text to be displayed prior to CLI/shell session logins.
+
+
+ more + +
+ string +
+
+
    Choices: +
  • disabled
  • +
  • enabled
  • +
+
+
Global CLI/shell session pagination (more) behavior.
+
+
+ more_lines + +
+ integer +
+
+ +
Global CLI/shell session pagination (more) number of lines per page.
+
+
+ welcome_banner_file + +
+ string +
+
+ +
Local file name containing the welcome banner text to be displayed upon successful CLI/shell session logins.
+
+
+ ssl + +
+ dictionary +
+
+ +
Waveserver SSL security configuration and operational data.
+
+
+ tls_cipher_suite_algorithms + +
+ list + / elements=dictionary +
+
+ +
List of transport layer security(TLS) cipher suite algorithms. The algorithm names are system assigned.
+
+
+ admin_state + +
+ string +
+
+
    Choices: +
  • disabled
  • +
  • enabled
  • +
+
+
TLS cipher suite algorithm administrative state.
+
+
+ algorithm_name + +
+ string + / required +
+
+ +
The TLS cipher suite algorithm name. (Key for list: tls-cipher-suite-algorithms)
+
+
+ state_dump_config + +
+ dictionary +
+
+ +
Configurable field about an active or recently completed state-dump collection operation.
+
+
+ exclude_corefiles + +
+ string +
+
+
    Choices: +
  • disabled
  • +
  • enabled
  • +
+
+
Indicates that exclude-corefiles is enabled or disabled.
+
+
+ time_config + +
+ dictionary +
+
+ +
Waveserver system time configuration attributes.
+
+
+ time_offset + +
+ integer +
+
+ +
System time-offset from UTC in seconds.
+
+
+ time_stamp + +
+ string +
+
+
    Choices: +
  • utc
  • +
  • local
  • +
+
+
System time stamp format; local time or UTC time.
+
+
+ xftp_config + +
+ dictionary +
+
+ +
Waveserver system XFTP configuration attributes.
+
+
+ ftp + +
+ dictionary +
+
+ +
Waveserver system FTP configuration.
+
+
+ host_name + +
+ string +
+
+ +
FTP host name. Format is an IP address (with optional port) or host name.
+
+
+ password + +
+ string +
+
+ +
FTP password string.
+
+
+ secret + +
+ string +
+
+ +
FTP secret string.
+
+
+ user_name + +
+ string +
+
+ +
FTP user name.
+
+
+ mode + +
+ string +
+
+
    Choices: +
  • none
  • +
  • tftp
  • +
  • ftp
  • +
  • sftp
  • +
  • scp
  • +
+
+
Identifies which file transfer protocol to user when default-server is specified in a command - FTP, SFTP, TFTP or SCP.
+
+
+ scp + +
+ dictionary +
+
+ +
Waveserver system SCP configuration.
+
+
+ host_name + +
+ string +
+
+ +
SCP host name. Format is an IP address (with optional port) or host name.
+
+
+ password + +
+ string +
+
+ +
SCP password string.
+
+
+ secret + +
+ string +
+
+ +
SCP secret string.
+
+
+ user_name + +
+ string +
+
+ +
SCP user name.
+
+
+ sftp + +
+ dictionary +
+
+ +
Waveserver system SFTP configuration.
+
+
+ host_name + +
+ string +
+
+ +
SFTP host name. Format is an IP address (with optional port) or host name.
+
+
+ password + +
+ string +
+
+ +
SFTP password string.
+
+
+ secret + +
+ string +
+
+ +
SFTP secret string.
+
+
+ user_name + +
+ string +
+
+ +
SFTP user name.
+
+
+ tftp + +
+ dictionary +
+
+ +
Waveserver system TFTP configuration.
+
+
+ config_host_name + +
+ string +
+
+ +
TFTP host name configured by user. Format is an IP address (with optional port) or host name.
+
+
+ state + +
+ string +
+
+
    Choices: +
  • merged ←
  • +
+
+
The state of the configuration
+
+
+ + + + +Examples +-------- + +.. code-block:: yaml + + # Using merged + + - name: Configure system hostname + ciena.waveserver5.waveserver5_system: + config: + host_name: + config_host_name: foo + state: merged + + + +Return Values +------------- +Common return values are documented `here `_, the following are the fields unique to this module: + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + +
KeyReturnedDescription
+
+ after + +
+ dictionary +
+
when changed +
The resulting configuration model invocation.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ before + +
+ dictionary +
+
always +
The configuration prior to the model invocation.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ xml + +
+ list +
+
always +
The set of xml commands pushed to the remote device.
+
+
Sample:
+
['<system xmlns="http://openconfig.net/yang/system"><config><hostname>foo</hostname></config></system>']
+
+

+ + +Status +------ + + +Authors +~~~~~~~ + +- Ciena diff --git a/docs/ciena.waveserverai.waveserverai_xcvrs_module.rst b/docs/ciena.waveserverai.waveserverai_xcvrs_module.rst new file mode 100644 index 0000000..fb6636c --- /dev/null +++ b/docs/ciena.waveserverai.waveserverai_xcvrs_module.rst @@ -0,0 +1,556 @@ +.. _ciena.waveserverai.waveserverai_xcvrs_module: + + +************************************* +ciena.waveserverai.waveserverai_xcvrs +************************************* + +**Waveserver transceivers (XCVR) configuration and operational data.Manage the xcvrs xcvrs configuration of a Ciena waveserverai device** + + + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- Waveserver transceivers (XCVR) configuration and operational data. Waveserver transceiver (XCVR) list. + + + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsComments
+
+ config + +
+ list + / elements=dictionary +
+
+ +
Waveserver transceiver (XCVR) list.
+
+
+ properties + +
+ dictionary +
+
+ +
All the Configurable and operational data of this XCVR instance.
+
+
+ mode + +
+ string + / required +
+
+
    Choices: +
  • blank
  • +
  • OCH
  • +
  • OTM
  • +
  • OSC
  • +
  • OSC-Add-Drop
  • +
  • 10GE
  • +
  • 4x10GE
  • +
  • 40GE
  • +
  • 100GE
  • +
  • 400GE
  • +
  • 400GE-ZR
  • +
  • 400GE-ZR+
  • +
  • 4x100GE
  • +
  • 4x100GE-ZR
  • +
  • 4x100GE-ZR+
  • +
  • OTL4.4
  • +
  • OTLC.4
  • +
  • FOIC1.4
  • +
  • FOIC4.8
  • +
  • 35-100
  • +
  • 35-150
  • +
  • 35-200
  • +
  • 35-250
  • +
  • 56-100
  • +
  • 56-150
  • +
  • 56-200
  • +
  • 56-250
  • +
  • 56-300
  • +
  • 56-350
  • +
  • 56-400
  • +
  • 70-300-O
  • +
  • 70-400-O
  • +
  • 70-400-E
  • +
  • 65-300-E
  • +
  • 65-400-E
  • +
  • 63-200-O
  • +
  • 63-400-O
  • +
  • 60-400-E-ZR
  • +
  • 60-400-E-ZR+
  • +
  • 60-200-E
  • +
  • 58-200-O
  • +
  • 35-200-O
  • +
  • 31.5-100-O
  • +
  • 31.5-200-O
  • +
  • 95-200-O
  • +
  • 95-250-O
  • +
  • 95-300-O
  • +
  • 95-350-O
  • +
  • 95-400-O
  • +
  • 95-450-O
  • +
  • 95-500-O
  • +
  • 95-550-O
  • +
  • 95-600-O
  • +
  • 95-650-O
  • +
  • 95-700-O
  • +
  • 95-750-O
  • +
  • 95-800-O
  • +
  • 95-200-E
  • +
  • 95-250-E
  • +
  • 95-300-E
  • +
  • 95-350-E
  • +
  • 95-400-E
  • +
  • 95-450-E
  • +
  • 95-500-E
  • +
  • 95-550-E
  • +
  • 95-600-E
  • +
  • 95-650-E
  • +
  • 95-700-E
  • +
  • 95-750-E
  • +
  • 95-800-E
  • +
  • 91.6-200-O
  • +
  • 91.6-250-O
  • +
  • 91.6-300-O
  • +
  • 91.6-350-O
  • +
  • 91.6-400-O
  • +
  • 91.6-450-O
  • +
  • 91.6-500-O
  • +
  • 91.6-550-O
  • +
  • 91.6-600-O
  • +
  • 91.6-650-O
  • +
  • 91.6-700-O
  • +
  • 91.6-750-O
  • +
  • 91.6-800-O
  • +
  • 91.6-200-E
  • +
  • 91.6-250-E
  • +
  • 91.6-300-E
  • +
  • 91.6-350-E
  • +
  • 91.6-400-E
  • +
  • 91.6-450-E
  • +
  • 91.6-500-E
  • +
  • 91.6-550-E
  • +
  • 91.6-600-E
  • +
  • 91.6-650-E
  • +
  • 91.6-700-E
  • +
  • 91.6-750-E
  • +
  • 91.6-800-E
  • +
  • 89.3-200-O
  • +
  • 89.3-250-O
  • +
  • 89.3-300-O
  • +
  • 89.3-350-O
  • +
  • 89.3-400-O
  • +
  • 89.3-450-O
  • +
  • 89.3-500-O
  • +
  • 89.3-550-O
  • +
  • 89.3-600-O
  • +
  • 89.3-650-O
  • +
  • 89.3-700-O
  • +
  • 89.3-750-O
  • +
  • 89.3-800-O
  • +
  • 89.3-200-E
  • +
  • 89.3-250-E
  • +
  • 89.3-300-E
  • +
  • 89.3-350-E
  • +
  • 89.3-400-E
  • +
  • 89.3-450-E
  • +
  • 89.3-500-E
  • +
  • 89.3-550-E
  • +
  • 89.3-600-E
  • +
  • 89.3-650-E
  • +
  • 89.3-700-E
  • +
  • 89.3-750-E
  • +
  • 89.3-800-E
  • +
  • 71.3-200-O
  • +
  • 71.3-250-O
  • +
  • 71.3-300-O
  • +
  • 71.3-350-O
  • +
  • 71.3-400-O
  • +
  • 71.3-450-O
  • +
  • 71.3-500-O
  • +
  • 71.3-550-O
  • +
  • 71.3-600-O
  • +
  • 71.3-200-E
  • +
  • 71.3-250-E
  • +
  • 71.3-300-E
  • +
  • 71.3-350-E
  • +
  • 71.3-400-E
  • +
  • 71.3-450-E
  • +
  • 71.3-500-E
  • +
  • 71.3-550-E
  • +
  • 71.3-600-E
  • +
  • 69.5-200-O
  • +
  • 69.5-250-O
  • +
  • 69.5-300-O
  • +
  • 69.5-350-O
  • +
  • 69.5-400-O
  • +
  • 69.5-450-O
  • +
  • 69.5-500-O
  • +
  • 69.5-550-O
  • +
  • 69.5-600-O
  • +
  • 69.5-200-E
  • +
  • 69.5-250-E
  • +
  • 69.5-300-E
  • +
  • 69.5-350-E
  • +
  • 69.5-400-E
  • +
  • 69.5-450-E
  • +
  • 69.5-500-E
  • +
  • 69.5-550-E
  • +
  • 69.5-600-E
  • +
  • 93.3-200-O
  • +
  • 93.3-250-O
  • +
  • 93.3-300-O
  • +
  • 93.3-350-O
  • +
  • 93.3-400-O
  • +
  • 93.3-450-O
  • +
  • 93.3-500-O
  • +
  • 93.3-550-O
  • +
  • 93.3-600-O
  • +
  • 93.3-650-O
  • +
  • 93.3-700-O
  • +
  • 93.3-750-O
  • +
  • 93.3-800-O
  • +
  • 93.3-200-E
  • +
  • 93.3-250-E
  • +
  • 93.3-300-E
  • +
  • 93.3-350-E
  • +
  • 93.3-400-E
  • +
  • 93.3-450-E
  • +
  • 93.3-500-E
  • +
  • 93.3-550-E
  • +
  • 93.3-600-E
  • +
  • 93.3-650-E
  • +
  • 93.3-700-E
  • +
  • 93.3-750-E
  • +
  • 93.3-800-E
  • +
  • 90-200-O
  • +
  • 90-250-O
  • +
  • 90-300-O
  • +
  • 90-350-O
  • +
  • 90-400-O
  • +
  • 90-450-O
  • +
  • 90-500-O
  • +
  • 90-550-O
  • +
  • 90-600-O
  • +
  • 90-650-O
  • +
  • 90-700-O
  • +
  • 90-750-O
  • +
  • 90-800-O
  • +
  • 90-200-E
  • +
  • 90-250-E
  • +
  • 90-300-E
  • +
  • 90-350-E
  • +
  • 90-400-E
  • +
  • 90-450-E
  • +
  • 90-500-E
  • +
  • 90-550-E
  • +
  • 90-600-E
  • +
  • 90-650-E
  • +
  • 90-700-E
  • +
  • 90-750-E
  • +
  • 90-800-E
  • +
  • 85-200-O
  • +
  • 85-250-O
  • +
  • 85-300-O
  • +
  • 85-350-O
  • +
  • 85-400-O
  • +
  • 85-450-O
  • +
  • 85-500-O
  • +
  • 85-550-O
  • +
  • 85-600-O
  • +
  • 85-650-O
  • +
  • 85-700-O
  • +
  • 85-750-O
  • +
  • 85-800-O
  • +
  • 85-200-E
  • +
  • 85-250-E
  • +
  • 85-300-E
  • +
  • 85-350-E
  • +
  • 85-400-E
  • +
  • 85-450-E
  • +
  • 85-500-E
  • +
  • 85-550-E
  • +
  • 85-600-E
  • +
  • 85-650-E
  • +
  • 85-700-E
  • +
  • 85-750-E
  • +
  • 85-800-E
  • +
  • 82-200-O
  • +
  • 82-250-O
  • +
  • 82-300-O
  • +
  • 82-350-O
  • +
  • 82-400-O
  • +
  • 82-450-O
  • +
  • 82-500-O
  • +
  • 82-550-O
  • +
  • 82-600-O
  • +
  • 82-650-O
  • +
  • 82-700-O
  • +
  • 82-750-O
  • +
  • 82-800-O
  • +
  • 82-200-E
  • +
  • 82-250-E
  • +
  • 82-300-E
  • +
  • 82-350-E
  • +
  • 82-400-E
  • +
  • 82-450-E
  • +
  • 82-500-E
  • +
  • 82-550-E
  • +
  • 82-600-E
  • +
  • 82-650-E
  • +
  • 82-700-E
  • +
  • 82-750-E
  • +
  • 82-800-E
  • +
  • 107-200-O
  • +
  • 107-200-E
  • +
  • 107-250-O
  • +
  • 107-250-E
  • +
  • 107-300-O
  • +
  • 107-300-E
  • +
  • 107-350-O
  • +
  • 107-350-E
  • +
  • 107-400-O
  • +
  • 107-400-E
  • +
  • 107-450-O
  • +
  • 107-450-E
  • +
  • 107-500-O
  • +
  • 107-500-E
  • +
  • 107-550-O
  • +
  • 107-550-E
  • +
  • 107-600-O
  • +
  • 107-600-E
  • +
  • 107-650-O
  • +
  • 107-650-E
  • +
  • 107-700-O
  • +
  • 107-700-E
  • +
  • 107-750-O
  • +
  • 107-750-E
  • +
  • 107-800-O
  • +
  • 107-800-E
  • +
+
+
Mode of the XCVR.
+
+
+ state + +
+ dictionary +
+
+ +
State information of this XCVR instance.
+
+
+ admin_state + +
+ string +
+
+
    Choices: +
  • disabled
  • +
  • enabled
  • +
+
+
Whether Admin State is enabled or disabled for this XCVR's PTP.
+
+
+ xcvr_id + +
+ string + / required +
+
+ +
Unique, access identifier string of the XCVR (e.g. '1-1'). Key value for the XCVR List. (Key for list: xcvrs)
+
+
+ state + +
+ string +
+
+
    Choices: +
  • merged ←
  • +
+
+
The state of the configuration
+
+
+ + + + +Examples +-------- + +.. code-block:: yaml + + # Using merged + + - name: Disable xcvr + ciena.waveserverai.xcvrs: + config: + - xcvr_id: 5-1 + state: + admin_state: disabled + state: merged + - name: Enable xcvr + ciena.waveserverai.xcvrs: + config: + - xcvr_id: 5-1 + state: + admin_state: enabled + state: merged + + + +Return Values +------------- +Common return values are documented `here `_, the following are the fields unique to this module: + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + +
KeyReturnedDescription
+
+ after + +
+ dictionary +
+
when changed +
The resulting configuration model invocation.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ before + +
+ dictionary +
+
always +
The configuration prior to the model invocation.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ xml + +
+ list +
+
always +
The set of xml commands pushed to the remote device.
+
+
Sample:
+
['<system xmlns="http://openconfig.net/yang/system"><config><hostname>foo</hostname></config></system>']
+
+

+ + +Status +------ + + +Authors +~~~~~~~ + +- Ciena diff --git a/galaxy.yml b/galaxy.yml index ece8916..8e8948e 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,5 +1,5 @@ --- -version: 1.0.3 +version: 1.1.0 authors: - Santiago Echevarria (sechevar@ciena.com) - Jeff Groom (jgroom@ciena.com) diff --git a/meta/runtime.yml b/meta/runtime.yml index 3284f20..d168bfd 100644 --- a/meta/runtime.yml +++ b/meta/runtime.yml @@ -1,8 +1,14 @@ --- -requires_ansible: '>=2.9.10,<2.11' +requires_ansible: '>=2.15.0' plugin_routing: action: - waveserverai_facts: - redirect: ciena.waveserverai - waveserverai_xcvrs: - redirect: ciena.waveserverai + facts: + redirect: ciena.waveserverai.waveserverai_facts + ports: + redirect: ciena.waveserverai.waveserverai_ports + ptps: + redirect: ciena.waveserverai.waveserverai_ptps + system: + redirect: ciena.waveserverai.waveserverai_system + xcvrs: + redirect: ciena.waveserverai.waveserverai_xcvrs diff --git a/plugins/module_utils/network/waveserverai/argspec/ports/ports.py b/plugins/module_utils/network/waveserverai/argspec/ports/ports.py new file mode 100755 index 0000000..5182d42 --- /dev/null +++ b/plugins/module_utils/network/waveserverai/argspec/ports/ports.py @@ -0,0 +1,181 @@ +# +# -*- coding: utf-8 -*- +# Copyright 2025 Ciena +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +############################################# +# WARNING # +############################################# +# +# This file is auto generated by the resource +# module builder playbook. +# +# Do not edit this file manually. +# +# Changes to this file will be over written +# by the resource module builder. +# +# Changes should be made in the model used to +# generate this file or in the resource module +# builder template. +# +############################################# + +""" +The arg spec for the waveserverai_ports module +""" +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + + +class PortsArgs(object): # pylint: disable=R0903 + """The arg spec for the waveserverai_ports module""" + + def __init__(self, **kwargs): + pass + + argument_spec = { + "config": { + "type": "list", + "elements": "dict", + "options": { + "port_id": {"type": "str", "required": True}, + "channels": { + "type": "list", + "elements": "dict", + "options": { + "channel_id": {"type": "int", "required": True}, + "id": {"type": "dict", "options": {"label": {"type": "str"}}}, + "properties": { + "type": "dict", + "options": { + "odu_sd_threshold": {"type": "str"}, + "trace": { + "type": "dict", + "options": { + "exp_dapi": {"type": "str"}, + "exp_oper": {"type": "str"}, + "exp_sapi": {"type": "str"}, + "mismatch_fail_mode": { + "type": "str", + "choices": ["none", "alarm-only", "squelch-traffic"], + }, + "mismatch_mode": { + "type": "str", + "choices": ["operator-only", "sapi", "dapi", "sapi-and-dapi"], + }, + "tx_dapi": {"type": "str"}, + "tx_oper": {"type": "str"}, + "tx_oper_mode": {"type": "str", "choices": ["manual", "automatic"]}, + "tx_sapi": {"type": "str"}, + }, + }, + }, + }, + "state": { + "type": "dict", + "options": {"admin_state": {"type": "str", "choices": ["disabled", "enabled"]}}, + }, + }, + }, + "id": { + "type": "dict", + "options": { + "type": { + "type": "str", + "choices": ["unknown", "ethernet", "otn", "OTUk", "OTUCn", "OTUCn-Flex", "ET"], + }, + "label": {"type": "str"}, + }, + }, + "properties": { + "type": "dict", + "options": { + "connection_peer": { + "type": "list", + "elements": "dict", + "options": {"peer_id": {"type": "str", "required": True}}, + }, + "connection_state": {"type": "str", "choices": ["disabled", "enabled"]}, + "ethernet": { + "type": "dict", + "options": { + "conditioning_holdoff": {"type": "int"}, + "conditioning_type": { + "type": "str", + "choices": ["none", "laser-off", "ethernet", "otn", "protocol-specific"], + }, + }, + }, + "loopback": {"type": "str", "choices": ["disabled", "rx", "tx"]}, + "otn": { + "type": "dict", + "options": { + "conditioning_type": { + "type": "str", + "choices": ["none", "laser-off", "ethernet", "otn", "protocol-specific"], + }, + "odu_sd_threshold": {"type": "str"}, + "odu_termination": {"type": "str", "choices": ["terminated", "passthrough"]}, + "otu_sd_threshold": {"type": "str"}, + "overhead_aggregation_mode": {"type": "str", "choices": ["single-slice", "automatic"]}, + "trace": { + "type": "dict", + "options": { + "path": { + "type": "dict", + "options": { + "exp_dapi": {"type": "str"}, + "exp_oper": {"type": "str"}, + "exp_sapi": {"type": "str"}, + "mismatch_fail_mode": { + "type": "str", + "choices": ["none", "alarm-only", "squelch-traffic"], + }, + "mismatch_mode": { + "type": "str", + "choices": ["operator-only", "sapi", "dapi", "sapi-and-dapi"], + }, + "tx_dapi": {"type": "str"}, + "tx_oper": {"type": "str"}, + "tx_oper_mode": {"type": "str", "choices": ["manual", "automatic"]}, + "tx_sapi": {"type": "str"}, + }, + }, + "section": { + "type": "dict", + "options": { + "exp_dapi": {"type": "str"}, + "exp_oper": {"type": "str"}, + "exp_sapi": {"type": "str"}, + "mismatch_fail_mode": { + "type": "str", + "choices": ["none", "alarm-only", "squelch-traffic"], + }, + "mismatch_mode": { + "type": "str", + "choices": ["operator-only", "sapi", "dapi", "sapi-and-dapi"], + }, + "tx_dapi": {"type": "str"}, + "tx_oper": {"type": "str"}, + "tx_oper_mode": {"type": "str", "choices": ["manual", "automatic"]}, + "tx_sapi": {"type": "str"}, + }, + }, + }, + }, + }, + }, + }, + }, + "state": { + "type": "dict", + "options": {"admin_state": {"type": "str", "choices": ["enabled", "disabled"]}}, + }, + }, + }, + "state": {"type": "str", "default": "merged", "choices": ["merged"]}, + } # pylint: disable=C0301 diff --git a/plugins/module_utils/network/waveserverai/argspec/ptps/ptps.py b/plugins/module_utils/network/waveserverai/argspec/ptps/ptps.py new file mode 100755 index 0000000..a15bf05 --- /dev/null +++ b/plugins/module_utils/network/waveserverai/argspec/ptps/ptps.py @@ -0,0 +1,119 @@ +# +# -*- coding: utf-8 -*- +# Copyright 2025 Ciena +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +############################################# +# WARNING # +############################################# +# +# This file is auto generated by the resource +# module builder playbook. +# +# Do not edit this file manually. +# +# Changes to this file will be over written +# by the resource module builder. +# +# Changes should be made in the model used to +# generate this file or in the resource module +# builder template. +# +############################################# + +""" +The arg spec for the waveserverai_ptps module +""" +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + + +class PtpsArgs(object): # pylint: disable=R0903 + """The arg spec for the waveserverai_ptps module""" + + def __init__(self, **kwargs): + pass + + argument_spec = { + "config": { + "type": "list", + "elements": "dict", + "options": { + "ptp_id": {"type": "str", "required": True}, + "id": {"type": "dict", "options": {"label": {"type": "str"}}}, + "properties": { + "type": "dict", + "options": { + "type": { + "type": "str", + "choices": [ + "unknown", + "WLAi", + "WLAi-iOPS", + "4x25G", + "10G", + "OCH", + "OSC", + "OSC-Add-Drop", + "OTM", + "WL5e", + "WL5n", + "100G", + "4x100G", + "8x50G", + "2x50G", + "400ZR", + ], + }, + "forward_error_correction": {"type": "str", "choices": ["disabled", "enabled", "automatic"]}, + "is_coherent": {"type": "bool"}, + "thresholds": { + "type": "dict", + "options": { + "fec_detected_degrade_threshold": {"type": "str"}, + "fec_excessive_degrade_threshold": {"type": "str"}, + "hccs_db": {"type": "float"}, + "pre_fec_sd_db": {"type": "float"}, + "pre_fec_sf_db": {"type": "float"}, + }, + }, + "topology_adjacency": { + "type": "dict", + "options": {"port_in": {"type": "str"}, "port_out": {"type": "str"}}, + }, + "transmitter": { + "type": "dict", + "options": {"state": {"type": "str", "choices": ["disabled", "enabled", "not-applicable"]}}, + }, + "xcvr_type": { + "type": "str", + "choices": [ + "not-available", + "unsupported", + "QSFPplus", + "QSFP28", + "WaveLogic 3 Extreme", + "WaveLogic Ai", + "SFP", + "none", + "QSFP-DD", + "WaveLogic 5e", + "CFP2-DCO", + ], + }, + }, + }, + "state": { + "type": "dict", + "options": { + "admin_state": {"type": "str", "choices": ["disabled", "enabled"]}, + "spli_management": {"type": "str", "choices": ["disabled", "enabled"]}, + }, + }, + }, + }, + "state": {"type": "str", "default": "merged", "choices": ["merged"]}, + } # pylint: disable=C0301 diff --git a/plugins/module_utils/network/waveserverai/argspec/system/system.py b/plugins/module_utils/network/waveserverai/argspec/system/system.py new file mode 100755 index 0000000..4b67667 --- /dev/null +++ b/plugins/module_utils/network/waveserverai/argspec/system/system.py @@ -0,0 +1,494 @@ +# +# -*- coding: utf-8 -*- +# Copyright 2025 Ciena +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +############################################# +# WARNING # +############################################# +# +# This file is auto generated by the resource +# module builder playbook. +# +# Do not edit this file manually. +# +# Changes to this file will be over written +# by the resource module builder. +# +# Changes should be made in the model used to +# generate this file or in the resource module +# builder template. +# +############################################# + +""" +The arg spec for the waveserverai_system module +""" +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + + +class SystemArgs(object): # pylint: disable=R0903 + """The arg spec for the waveserverai_system module""" + + def __init__(self, **kwargs): + pass + + argument_spec = { + "config": { + "type": "dict", + "options": { + "auto_config_recovery": { + "type": "dict", + "options": { + "admin_state": {"type": "str", "choices": ["disabled", "enabled"]}, + "audit_interval": {"type": "int"}, + "config_mismatch_detection_state": {"type": "str", "choices": ["disabled", "enabled"]}, + "passphrase": {"type": "str", "no_log": True}, + }, + }, + "client_config": { + "type": "dict", + "options": { + "dhcp": { + "type": "dict", + "options": { + "admin_state": {"type": "str", "choices": ["disabled", "enabled"]}, + "discovery_interval": {"type": "int"}, + "interface_type": {"type": "str", "choices": ["remote", "active"]}, + "options": { + "type": "dict", + "options": { + "bootfile_name": {"type": "bool"}, + "domain_name": {"type": "bool"}, + "domain_server": {"type": "bool"}, + "host_name": {"type": "bool"}, + "lease_time": {"type": "bool"}, + "log_server": {"type": "bool"}, + "ntp_servers": {"type": "bool"}, + "router": {"type": "bool"}, + "subnet_mask": {"type": "bool"}, + "tftp_server_name": {"type": "bool"}, + "time_offset": {"type": "bool"}, + }, + }, + "requested_lease_time": {"type": "int"}, + }, + }, + "dhcpv6": { + "type": "dict", + "options": { + "admin_state": {"type": "str", "choices": ["disabled", "enabled"]}, + "options_state": { + "type": "dict", + "options": { + "bootfile_url": {"type": "bool"}, + "dns_servers": {"type": "bool"}, + "ntp_server": {"type": "bool"}, + }, + }, + }, + }, + "dns": { + "type": "dict", + "options": { + "admin_state": {"type": "str", "choices": ["disabled", "enabled"]}, + "server": { + "type": "list", + "elements": "dict", + "options": { + "ip_address": {"type": "str", "required": True}, + "admin_state": {"type": "str", "choices": ["disabled", "enabled"]}, + "user_priority": {"type": "int"}, + }, + }, + }, + }, + "grpc": { + "type": "dict", + "options": { + "server": { + "type": "list", + "elements": "dict", + "options": { + "address": {"type": "str", "required": True}, + "trusted_dns": {"type": "str", "required": True}, + }, + } + }, + }, + "ntp": { + "type": "dict", + "options": { + "admin_state": {"type": "str", "choices": ["disabled", "enabled"]}, + "authentication_state": {"type": "str", "choices": ["disabled", "enabled"]}, + "autokey_authentication_state": {"type": "str", "choices": ["disabled", "enabled"]}, + "mode": {"type": "str", "choices": ["polling", "broadcast", "multicast"]}, + "multicast_server": { + "type": "list", + "elements": "dict", + "options": {"ip_address": {"type": "str", "required": True}}, + }, + "ntp_key": { + "type": "list", + "elements": "dict", + "no_log": True, + "options": { + "key_id": {"type": "int", "required": True}, + "key_type": {"type": "str", "choices": ["MD5", "SHA1"]}, + "key_value": {"type": "str", "no_log": True}, + }, + }, + "polling_interval": {"type": "int"}, + "server": { + "type": "list", + "elements": "dict", + "options": { + "address": {"type": "str", "required": True}, + "admin_state": {"type": "str", "choices": ["disabled", "enabled"]}, + "autokey_authentication": {"type": "str", "choices": ["disabled", "enabled"]}, + "key_id": {"type": "str"}, + }, + }, + "sha1key_authentication_state": {"type": "str", "choices": ["disabled", "enabled"]}, + }, + }, + }, + }, + "default_settings": { + "type": "dict", + "options": { + "conditioning": { + "type": "dict", + "options": { + "type": { + "type": "str", + "choices": ["none", "laser-off", "ethernet", "otn", "protocol-specific"], + }, + "holdoff": {"type": "int"}, + }, + }, + "remote_management_auto_enable": {"type": "bool"}, + "terrestrial_reach_limit": {"type": "int"}, + }, + }, + "domain_name": {"type": "dict", "options": {"config_domain_name": {"type": "str"}}}, + "environment": { + "type": "dict", + "options": { + "diag": { + "type": "dict", + "options": { + "shell": {"type": "str", "choices": ["cli", "system"]}, + "sudo": {"type": "bool"}, + }, + }, + "root": { + "type": "dict", + "options": { + "password": {"type": "str", "no_log": True}, + "secret": {"type": "str", "no_log": True}, + }, + }, + "shell": { + "type": "dict", + "options": {"admin_state": {"type": "str", "choices": ["disabled", "enabled"]}}, + }, + }, + }, + "global_provisioning": { + "type": "dict", + "options": { + "encryption_only": {"type": "bool"}, + "line_config": { + "type": "dict", + "options": {"line_protection": {"type": "str", "choices": ["unprotected", "trunk-ops"]}}, + }, + }, + }, + "host_name": {"type": "dict", "options": {"config_host_name": {"type": "str"}}}, + "id": { + "type": "dict", + "options": { + "group": { + "type": "dict", + "options": {"description": {"type": "str"}, "id": {"type": "int"}, "name": {"type": "str"}}, + }, + "member": { + "type": "dict", + "options": { + "description": {"type": "str"}, + "cluster_enrollment": {"type": "str", "choices": ["disabled", "enabled"]}, + "frame_identification": {"type": "str"}, + "id": {"type": "int"}, + "name": {"type": "str"}, + "rack_unit_number": {"type": "int"}, + }, + }, + "network": { + "type": "dict", + "options": {"description": {"type": "str"}, "id": {"type": "int"}, "name": {"type": "str"}}, + }, + "site": { + "type": "dict", + "options": { + "description": {"type": "str"}, + "address": {"type": "str"}, + "id": {"type": "int"}, + "latitude": {"type": "float"}, + "longitude": {"type": "float"}, + "name": {"type": "str"}, + }, + }, + }, + }, + "lamp_test": { + "type": "dict", + "options": { + "admin_state": {"type": "str", "choices": ["disabled", "enabled"]}, + "target_id": {"type": "str"}, + "target_type": {"type": "str", "choices": ["chassis", "slot", "port"]}, + "timeout": {"type": "int"}, + }, + }, + "management": { + "type": "dict", + "options": { + "caching": { + "type": "dict", + "options": {"openconfig": {"type": "str", "choices": ["disabled", "enabled"]}}, + }, + "query_limits": { + "type": "dict", + "options": { + "gnmi": {"type": "dict", "options": {"pm_history_bins": {"type": "int"}}}, + "netconf": {"type": "dict", "options": {"pm_history_bins": {"type": "int"}}}, + "rest": {"type": "dict", "options": {"pm_history_bins": {"type": "int"}}}, + }, + }, + "root_scope": { + "type": "dict", + "options": { + "gnmi": { + "type": "dict", + "options": { + "get": {"type": "str", "choices": ["native", "openconfig", "all"]}, + "replace": {"type": "str", "choices": ["native", "openconfig", "all"]}, + }, + }, + "netconf": { + "type": "dict", + "options": { + "get": {"type": "str", "choices": ["native", "openconfig", "all"]}, + "replace": {"type": "str", "choices": ["native", "openconfig", "all"]}, + }, + }, + "rest": { + "type": "dict", + "options": { + "get": {"type": "str", "choices": ["native", "openconfig", "all"]}, + "replace": {"type": "str", "choices": ["native", "openconfig", "all"]}, + }, + }, + }, + }, + }, + }, + "server_config": { + "type": "dict", + "options": { + "global_inactivity_timeout": {"type": "int"}, + "global_inactivity_timer": {"type": "str", "choices": ["disabled", "enabled"]}, + "grpc": { + "type": "dict", + "options": { + "admin_state": {"type": "str", "choices": ["disabled", "enabled"]}, + "certificate_verification": { + "type": "dict", + "options": { + "certificate_name": {"type": "str"}, + "mutual_authentication": { + "type": "dict", + "options": { + "admin_state": {"type": "str", "choices": ["disabled", "enabled"]} + }, + }, + }, + }, + }, + }, + "grpc_server_state": {"type": "str", "choices": ["disabled", "enabled"]}, + "https": { + "type": "dict", + "options": { + "admin_state": {"type": "str", "choices": ["disabled", "enabled"]}, + "certificate_verification": { + "type": "dict", + "options": { + "certificate_name": {"type": "str"}, + "mutual_authentication": { + "type": "dict", + "options": { + "admin_state": {"type": "str", "choices": ["disabled", "enabled"]} + }, + }, + "ocsp": { + "type": "dict", + "options": { + "admin_state": {"type": "str", "choices": ["disabled", "enabled"]}, + "default_responder": {"type": "str"}, + "nonce": {"type": "str", "choices": ["off", "on"]}, + "responder_preference": { + "type": "str", + "choices": ["aia", "default-responder"], + }, + }, + }, + "trusted_dns": {"type": "str"}, + }, + }, + "craft_gui_admin_state": {"type": "str", "choices": ["disabled", "enabled"]}, + "inactivity_timeout": {"type": "int"}, + "web_ui_file_transfer_admin_state": {"type": "str", "choices": ["disabled", "enabled"]}, + }, + }, + "netconf": { + "type": "dict", + "options": { + "admin_state": {"type": "str", "choices": ["disabled", "enabled"]}, + "candidate_advertisement": {"type": "str", "choices": ["disabled", "enabled"]}, + }, + }, + "netconf_server_state": {"type": "str", "choices": ["disabled", "enabled"]}, + "scp_server_state": {"type": "str", "choices": ["disabled", "enabled"]}, + "sftp_server_state": {"type": "str", "choices": ["disabled", "enabled"]}, + "ssh": { + "type": "dict", + "options": { + "algorithms": { + "type": "dict", + "options": { + "encryption": { + "type": "list", + "elements": "dict", + "options": { + "algorithm_name": {"type": "str", "required": True}, + "admin_state": {"type": "str", "choices": ["disabled", "enabled"]}, + }, + }, + "key_exchange": { + "type": "list", + "elements": "dict", + "no_log": True, + "options": { + "algorithm_name": {"type": "str", "required": True}, + "admin_state": {"type": "str", "choices": ["disabled", "enabled"]}, + }, + }, + "message_authentication_code": { + "type": "list", + "elements": "dict", + "options": { + "algorithm_name": {"type": "str", "required": True}, + "admin_state": {"type": "str", "choices": ["disabled", "enabled"]}, + }, + }, + "public_key_authentication": { + "type": "list", + "elements": "dict", + "options": { + "algorithm_name": {"type": "str", "required": True}, + "admin_state": {"type": "str", "choices": ["disabled", "enabled"]}, + }, + }, + }, + }, + "allowed_clients": { + "type": "list", + "elements": "dict", + "options": {"ip_address": {"type": "str", "required": True}}, + }, + "authentication_retries": {"type": "int"}, + "listener_port": {"type": "int"}, + }, + }, + "web_server_state": {"type": "str", "choices": ["disabled", "enabled"]}, + }, + }, + "shell": { + "type": "dict", + "options": { + "inactivity_timeout": {"type": "str"}, + "inactivity_timer": {"type": "str"}, + "login_authentication_message": {"type": "str", "choices": ["disabled", "enabled"]}, + "login_banner_file": {"type": "str"}, + "more": {"type": "str", "choices": ["disabled", "enabled"]}, + "more_lines": {"type": "int"}, + "welcome_banner_file": {"type": "str"}, + }, + }, + "ssl": { + "type": "dict", + "options": { + "tls_cipher_suite_algorithms": { + "type": "list", + "elements": "dict", + "options": { + "algorithm_name": {"type": "str", "required": True}, + "admin_state": {"type": "str", "choices": ["disabled", "enabled"]}, + }, + } + }, + }, + "state_dump_config": { + "type": "dict", + "options": {"exclude_corefiles": {"type": "str", "choices": ["disabled", "enabled"]}}, + }, + "time_config": { + "type": "dict", + "options": { + "time_offset": {"type": "int"}, + "time_stamp": {"type": "str", "choices": ["utc", "local"]}, + }, + }, + "xftp_config": { + "type": "dict", + "options": { + "ftp": { + "type": "dict", + "options": { + "host_name": {"type": "str"}, + "password": {"type": "str", "no_log": True}, + "secret": {"type": "str", "no_log": True}, + "user_name": {"type": "str"}, + }, + }, + "mode": {"type": "str", "choices": ["none", "tftp", "ftp", "sftp", "scp"]}, + "scp": { + "type": "dict", + "options": { + "host_name": {"type": "str"}, + "password": {"type": "str", "no_log": True}, + "secret": {"type": "str", "no_log": True}, + "user_name": {"type": "str"}, + }, + }, + "sftp": { + "type": "dict", + "options": { + "host_name": {"type": "str"}, + "password": {"type": "str", "no_log": True}, + "secret": {"type": "str", "no_log": True}, + "user_name": {"type": "str"}, + }, + }, + "tftp": {"type": "dict", "options": {"config_host_name": {"type": "str"}}}, + }, + }, + }, + }, + "state": {"type": "str", "default": "merged", "choices": ["merged"]}, + } # pylint: disable=C0301 diff --git a/plugins/module_utils/network/waveserverai/argspec/xcvrs/xcvrs.py b/plugins/module_utils/network/waveserverai/argspec/xcvrs/xcvrs.py old mode 100644 new mode 100755 index e8aaad5..55db0ed --- a/plugins/module_utils/network/waveserverai/argspec/xcvrs/xcvrs.py +++ b/plugins/module_utils/network/waveserverai/argspec/xcvrs/xcvrs.py @@ -1,6 +1,6 @@ # # -*- coding: utf-8 -*- -# Copyright 2021 Ciena +# Copyright 2025 Ciena # GNU General Public License v3.0+ # (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) @@ -25,6 +25,10 @@ """ The arg spec for the waveserverai_xcvrs module """ +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type class XcvrsArgs(object): # pylint: disable=R0903 @@ -35,14 +39,39 @@ def __init__(self, **kwargs): argument_spec = { "config": { + "type": "list", "elements": "dict", "options": { + "xcvr_id": {"type": "str", "required": True}, "properties": { + "type": "dict", "options": { "mode": { + "type": "str", "choices": [ + "blank", + "OCH", + "OTM", + "OSC", + "OSC-Add-Drop", + "10GE", + "4x10GE", + "40GE", "100GE", + "400GE", + "400GE-ZR", + "400GE-ZR+", + "4x100GE", + "4x100GE-ZR", + "4x100GE-ZR+", "OTL4.4", + "OTLC.4", + "FOIC1.4", + "FOIC4.8", + "35-100", + "35-150", + "35-200", + "35-250", "56-100", "56-150", "56-200", @@ -50,29 +79,274 @@ def __init__(self, **kwargs): "56-300", "56-350", "56-400", - "35-100", - "35-150", - "35-250", - "OCH", - "OTM", - "4x10GE", - "35-200", - "OSC", - "OTLC.4", - "OSC-ADD-DROP", + "70-300-O", + "70-400-O", + "70-400-E", + "65-300-E", + "65-400-E", + "63-200-O", + "63-400-O", + "60-400-E-ZR", + "60-400-E-ZR+", + "60-200-E", + "58-200-O", + "35-200-O", + "31.5-100-O", + "31.5-200-O", + "95-200-O", + "95-250-O", + "95-300-O", + "95-350-O", + "95-400-O", + "95-450-O", + "95-500-O", + "95-550-O", + "95-600-O", + "95-650-O", + "95-700-O", + "95-750-O", + "95-800-O", + "95-200-E", + "95-250-E", + "95-300-E", + "95-350-E", + "95-400-E", + "95-450-E", + "95-500-E", + "95-550-E", + "95-600-E", + "95-650-E", + "95-700-E", + "95-750-E", + "95-800-E", + "91.6-200-O", + "91.6-250-O", + "91.6-300-O", + "91.6-350-O", + "91.6-400-O", + "91.6-450-O", + "91.6-500-O", + "91.6-550-O", + "91.6-600-O", + "91.6-650-O", + "91.6-700-O", + "91.6-750-O", + "91.6-800-O", + "91.6-200-E", + "91.6-250-E", + "91.6-300-E", + "91.6-350-E", + "91.6-400-E", + "91.6-450-E", + "91.6-500-E", + "91.6-550-E", + "91.6-600-E", + "91.6-650-E", + "91.6-700-E", + "91.6-750-E", + "91.6-800-E", + "89.3-200-O", + "89.3-250-O", + "89.3-300-O", + "89.3-350-O", + "89.3-400-O", + "89.3-450-O", + "89.3-500-O", + "89.3-550-O", + "89.3-600-O", + "89.3-650-O", + "89.3-700-O", + "89.3-750-O", + "89.3-800-O", + "89.3-200-E", + "89.3-250-E", + "89.3-300-E", + "89.3-350-E", + "89.3-400-E", + "89.3-450-E", + "89.3-500-E", + "89.3-550-E", + "89.3-600-E", + "89.3-650-E", + "89.3-700-E", + "89.3-750-E", + "89.3-800-E", + "71.3-200-O", + "71.3-250-O", + "71.3-300-O", + "71.3-350-O", + "71.3-400-O", + "71.3-450-O", + "71.3-500-O", + "71.3-550-O", + "71.3-600-O", + "71.3-200-E", + "71.3-250-E", + "71.3-300-E", + "71.3-350-E", + "71.3-400-E", + "71.3-450-E", + "71.3-500-E", + "71.3-550-E", + "71.3-600-E", + "69.5-200-O", + "69.5-250-O", + "69.5-300-O", + "69.5-350-O", + "69.5-400-O", + "69.5-450-O", + "69.5-500-O", + "69.5-550-O", + "69.5-600-O", + "69.5-200-E", + "69.5-250-E", + "69.5-300-E", + "69.5-350-E", + "69.5-400-E", + "69.5-450-E", + "69.5-500-E", + "69.5-550-E", + "69.5-600-E", + "93.3-200-O", + "93.3-250-O", + "93.3-300-O", + "93.3-350-O", + "93.3-400-O", + "93.3-450-O", + "93.3-500-O", + "93.3-550-O", + "93.3-600-O", + "93.3-650-O", + "93.3-700-O", + "93.3-750-O", + "93.3-800-O", + "93.3-200-E", + "93.3-250-E", + "93.3-300-E", + "93.3-350-E", + "93.3-400-E", + "93.3-450-E", + "93.3-500-E", + "93.3-550-E", + "93.3-600-E", + "93.3-650-E", + "93.3-700-E", + "93.3-750-E", + "93.3-800-E", + "90-200-O", + "90-250-O", + "90-300-O", + "90-350-O", + "90-400-O", + "90-450-O", + "90-500-O", + "90-550-O", + "90-600-O", + "90-650-O", + "90-700-O", + "90-750-O", + "90-800-O", + "90-200-E", + "90-250-E", + "90-300-E", + "90-350-E", + "90-400-E", + "90-450-E", + "90-500-E", + "90-550-E", + "90-600-E", + "90-650-E", + "90-700-E", + "90-750-E", + "90-800-E", + "85-200-O", + "85-250-O", + "85-300-O", + "85-350-O", + "85-400-O", + "85-450-O", + "85-500-O", + "85-550-O", + "85-600-O", + "85-650-O", + "85-700-O", + "85-750-O", + "85-800-O", + "85-200-E", + "85-250-E", + "85-300-E", + "85-350-E", + "85-400-E", + "85-450-E", + "85-500-E", + "85-550-E", + "85-600-E", + "85-650-E", + "85-700-E", + "85-750-E", + "85-800-E", + "82-200-O", + "82-250-O", + "82-300-O", + "82-350-O", + "82-400-O", + "82-450-O", + "82-500-O", + "82-550-O", + "82-600-O", + "82-650-O", + "82-700-O", + "82-750-O", + "82-800-O", + "82-200-E", + "82-250-E", + "82-300-E", + "82-350-E", + "82-400-E", + "82-450-E", + "82-500-E", + "82-550-E", + "82-600-E", + "82-650-E", + "82-700-E", + "82-750-E", + "82-800-E", + "107-200-O", + "107-200-E", + "107-250-O", + "107-250-E", + "107-300-O", + "107-300-E", + "107-350-O", + "107-350-E", + "107-400-O", + "107-400-E", + "107-450-O", + "107-450-E", + "107-500-O", + "107-500-E", + "107-550-O", + "107-550-E", + "107-600-O", + "107-600-E", + "107-650-O", + "107-650-E", + "107-700-O", + "107-700-E", + "107-750-O", + "107-750-E", + "107-800-O", + "107-800-E", ], - "type": "str", + "required": True, } }, + }, + "state": { "type": "dict", + "options": {"admin_state": {"type": "str", "choices": ["disabled", "enabled"]}}, }, - "xcvr-id": {"required": True, "type": "str"}, }, - "type": "list", - }, - "state": { - "choices": ["merged", "overridden"], - "default": "merged", - "type": "str", }, + "state": {"type": "str", "default": "merged", "choices": ["merged"]}, } # pylint: disable=C0301 diff --git a/plugins/module_utils/network/waveserverai/config/ports/ports.py b/plugins/module_utils/network/waveserverai/config/ports/ports.py new file mode 100755 index 0000000..1798b1d --- /dev/null +++ b/plugins/module_utils/network/waveserverai/config/ports/ports.py @@ -0,0 +1,198 @@ +# +# -*- coding: utf-8 -*- +# Copyright 2025 Ciena +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +""" +The waveserverai_ports class +It is in this file where the current configuration (as dict) +is compared to the provided configuration (as dict) and the command set +necessary to bring the current configuration to it's desired end-state is +created +""" +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +try: + from lxml.etree import tostring as xml_to_string, Element + + HAS_LXML = True +except ImportError: + from xml.etree.ElementTree import Element + from xml.etree.ElementTree import tostring as xml_to_string + + HAS_LXML = False + + +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base import ( + ConfigBase, +) +from ansible_collections.ciena.waveserverai.plugins.module_utils.network.waveserverai.facts.facts import ( + Facts, +) +from ansible_collections.ciena.waveserverai.plugins.module_utils.network.waveserverai.utils.utils import ( + config_is_diff, +) + +NAMESPACE = "urn:ciena:params:xml:ns:yang:ciena-ws:ciena-waveserver-port" +ROOT_KEY = "waveserver-ports" +RESOURCE = "ports" +XML_ITEMS = "ports" +XML_ITEMS_KEY = "port-id" + + +class Ports(ConfigBase): + """ + The waveserverai_ports class + """ + + gather_subset = ["!all", "!min"] + gather_network_resources = [RESOURCE] + + def __init__(self, module): + super(Ports, self).__init__(module) + + def get_facts(self): + """Get the 'facts' (the current configuration) + + :rtype: A dictionary + :returns: The current configuration as a dictionary + """ + facts, _warnings = Facts(self._module).get_facts(self.gather_subset, self.gather_network_resources) + result = facts["ansible_network_resources"].get(RESOURCE) + if not result: + return [] + return result + + def execute_module(self): + """Execute the module + + :rtype: A dictionary + :returns: The result from module execution + """ + result = {"changed": False} + have = self.get_facts() + config_dict = self.set_config(have) + + if config_dict: + config_xml = self._create_xml_config_generic(config_dict) + config = '' f"{config_xml}" "" + try: + self._module._connection.edit_config(config=config, target="running") + except Exception as e: + return {"failed": True, "msg": str(e)} + + result["changed"] = True + result["xml"] = config_xml + + changed_facts = self.get_facts() + + result["changed"] = config_is_diff(have, changed_facts) + + result["before"] = have + if self.state in self.ACTION_STATES: + if result["changed"]: + result["after"] = changed_facts + + elif self.state == "gathered": + result["gathered"] = have + + return result + + def set_config(self, have): + """Collect the configuration from the args passed to the module, + collect the current configuration (as a dict from facts) + + :rtype: A list + :returns: the commands necessary to migrate the current configuration + to the desired configuration + """ + want = self._module.params["config"] + state = self._module.params["state"] + state_methods = { + "merged": self._state_merged, + "deleted": self._state_deleted, + } + config_dict = state_methods[state](want, have) if state in self.ACTION_STATES else {} + return config_dict + + def _populate_xml_subtree(self, parent: Element, data: dict): + for key, value in data.items(): + sanitized_key = key.replace("_", "-") + if isinstance(value, dict): + subelem = Element(sanitized_key) + self._populate_xml_subtree(subelem, value) + parent.append(subelem) + elif isinstance(value, list): + for list_item in value: + subelem = Element(sanitized_key) + self._populate_xml_subtree(subelem, list_item) + parent.append(subelem) + else: + subelem = Element(sanitized_key) + subelem.text = str(value) + if value is not None: + parent.append(subelem) + + def _create_xml_config_generic(self, config_dict_or_list): + if isinstance(config_dict_or_list, dict): + return self.create_xml_config_from_dict(config_dict_or_list) + elif isinstance(config_dict_or_list, list): + return self.create_xml_config_from_list(config_dict_or_list) + else: + raise TypeError(f"Expected a dictionary or a list, got a {type(config_dict_or_list)}") + + def _init_xml_root(self): + return Element("{%s}%s" % (NAMESPACE, ROOT_KEY), nsmap={None: NAMESPACE}) + + def create_xml_config_from_dict(self, config_dict: dict) -> str: + root = self._init_xml_root() + self._populate_xml_subtree(root, config_dict) + return xml_to_string(root).decode() + + def create_xml_config_from_list(self, config_list: list) -> str: + root = self._init_xml_root() + for list_item in config_list: + if not isinstance(list_item, dict): + raise ValueError("List items must be dictionaries.") + subroot = Element(XML_ITEMS) + operation = list_item.pop("operation", None) + self._populate_xml_subtree(subroot, list_item) + if operation: + subroot.set("operation", operation) + root.append(subroot) + return xml_to_string(root).decode() + + def _state_merged(self, want, have): + if isinstance(want, list): + return self._state_merged_list(want, have) + elif isinstance(want, dict): + return self._state_merged_dict(want, have) + + def _state_merged_dict(self, want, have) -> dict: + response = {} + for key, value in want.items(): + if value is None: + continue + if key in have and have[key] == value: + continue + response[key] = value + return response + + def _state_merged_list(self, want, have) -> list: + response = [] + for w_item in want: + if w_item in have: + continue + response.append(w_item) + return response + + def _state_deleted(self, want, have): + response = [] + if not want: + want = have + for config in want: + response.append({"port-id": config["port-id"], "operation": "delete"}) + return response diff --git a/plugins/module_utils/network/waveserverai/config/ptps/ptps.py b/plugins/module_utils/network/waveserverai/config/ptps/ptps.py new file mode 100755 index 0000000..687ab2b --- /dev/null +++ b/plugins/module_utils/network/waveserverai/config/ptps/ptps.py @@ -0,0 +1,198 @@ +# +# -*- coding: utf-8 -*- +# Copyright 2025 Ciena +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +""" +The waveserverai_ptps class +It is in this file where the current configuration (as dict) +is compared to the provided configuration (as dict) and the command set +necessary to bring the current configuration to it's desired end-state is +created +""" +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +try: + from lxml.etree import tostring as xml_to_string, Element + + HAS_LXML = True +except ImportError: + from xml.etree.ElementTree import Element + from xml.etree.ElementTree import tostring as xml_to_string + + HAS_LXML = False + + +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base import ( + ConfigBase, +) +from ansible_collections.ciena.waveserverai.plugins.module_utils.network.waveserverai.facts.facts import ( + Facts, +) +from ansible_collections.ciena.waveserverai.plugins.module_utils.network.waveserverai.utils.utils import ( + config_is_diff, +) + +NAMESPACE = "urn:ciena:params:xml:ns:yang:ciena-ws:ciena-waveserver-ptp" +ROOT_KEY = "waveserver-ptps" +RESOURCE = "ptps" +XML_ITEMS = "ptps" +XML_ITEMS_KEY = "ptp-id" + + +class Ptps(ConfigBase): + """ + The waveserverai_ptps class + """ + + gather_subset = ["!all", "!min"] + gather_network_resources = [RESOURCE] + + def __init__(self, module): + super(Ptps, self).__init__(module) + + def get_facts(self): + """Get the 'facts' (the current configuration) + + :rtype: A dictionary + :returns: The current configuration as a dictionary + """ + facts, _warnings = Facts(self._module).get_facts(self.gather_subset, self.gather_network_resources) + result = facts["ansible_network_resources"].get(RESOURCE) + if not result: + return [] + return result + + def execute_module(self): + """Execute the module + + :rtype: A dictionary + :returns: The result from module execution + """ + result = {"changed": False} + have = self.get_facts() + config_dict = self.set_config(have) + + if config_dict: + config_xml = self._create_xml_config_generic(config_dict) + config = '' f"{config_xml}" "" + try: + self._module._connection.edit_config(config=config, target="running") + except Exception as e: + return {"failed": True, "msg": str(e)} + + result["changed"] = True + result["xml"] = config_xml + + changed_facts = self.get_facts() + + result["changed"] = config_is_diff(have, changed_facts) + + result["before"] = have + if self.state in self.ACTION_STATES: + if result["changed"]: + result["after"] = changed_facts + + elif self.state == "gathered": + result["gathered"] = have + + return result + + def set_config(self, have): + """Collect the configuration from the args passed to the module, + collect the current configuration (as a dict from facts) + + :rtype: A list + :returns: the commands necessary to migrate the current configuration + to the desired configuration + """ + want = self._module.params["config"] + state = self._module.params["state"] + state_methods = { + "merged": self._state_merged, + "deleted": self._state_deleted, + } + config_dict = state_methods[state](want, have) if state in self.ACTION_STATES else {} + return config_dict + + def _populate_xml_subtree(self, parent: Element, data: dict): + for key, value in data.items(): + sanitized_key = key.replace("_", "-") + if isinstance(value, dict): + subelem = Element(sanitized_key) + self._populate_xml_subtree(subelem, value) + parent.append(subelem) + elif isinstance(value, list): + for list_item in value: + subelem = Element(sanitized_key) + self._populate_xml_subtree(subelem, list_item) + parent.append(subelem) + else: + subelem = Element(sanitized_key) + subelem.text = str(value) + if value is not None: + parent.append(subelem) + + def _create_xml_config_generic(self, config_dict_or_list): + if isinstance(config_dict_or_list, dict): + return self.create_xml_config_from_dict(config_dict_or_list) + elif isinstance(config_dict_or_list, list): + return self.create_xml_config_from_list(config_dict_or_list) + else: + raise TypeError(f"Expected a dictionary or a list, got a {type(config_dict_or_list)}") + + def _init_xml_root(self): + return Element("{%s}%s" % (NAMESPACE, ROOT_KEY), nsmap={None: NAMESPACE}) + + def create_xml_config_from_dict(self, config_dict: dict) -> str: + root = self._init_xml_root() + self._populate_xml_subtree(root, config_dict) + return xml_to_string(root).decode() + + def create_xml_config_from_list(self, config_list: list) -> str: + root = self._init_xml_root() + for list_item in config_list: + if not isinstance(list_item, dict): + raise ValueError("List items must be dictionaries.") + subroot = Element(XML_ITEMS) + operation = list_item.pop("operation", None) + self._populate_xml_subtree(subroot, list_item) + if operation: + subroot.set("operation", operation) + root.append(subroot) + return xml_to_string(root).decode() + + def _state_merged(self, want, have): + if isinstance(want, list): + return self._state_merged_list(want, have) + elif isinstance(want, dict): + return self._state_merged_dict(want, have) + + def _state_merged_dict(self, want, have) -> dict: + response = {} + for key, value in want.items(): + if value is None: + continue + if key in have and have[key] == value: + continue + response[key] = value + return response + + def _state_merged_list(self, want, have) -> list: + response = [] + for w_item in want: + if w_item in have: + continue + response.append(w_item) + return response + + def _state_deleted(self, want, have): + response = [] + if not want: + want = have + for config in want: + response.append({"ptp-id": config["ptp-id"], "operation": "delete"}) + return response diff --git a/plugins/module_utils/network/waveserverai/config/system/system.py b/plugins/module_utils/network/waveserverai/config/system/system.py new file mode 100755 index 0000000..a52b3cf --- /dev/null +++ b/plugins/module_utils/network/waveserverai/config/system/system.py @@ -0,0 +1,198 @@ +# +# -*- coding: utf-8 -*- +# Copyright 2025 Ciena +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +""" +The waveserverai_system class +It is in this file where the current configuration (as dict) +is compared to the provided configuration (as dict) and the command set +necessary to bring the current configuration to it's desired end-state is +created +""" +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +try: + from lxml.etree import tostring as xml_to_string, Element + + HAS_LXML = True +except ImportError: + from xml.etree.ElementTree import Element + from xml.etree.ElementTree import tostring as xml_to_string + + HAS_LXML = False + + +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base import ( + ConfigBase, +) +from ansible_collections.ciena.waveserverai.plugins.module_utils.network.waveserverai.facts.facts import ( + Facts, +) +from ansible_collections.ciena.waveserverai.plugins.module_utils.network.waveserverai.utils.utils import ( + config_is_diff, +) + +NAMESPACE = "urn:ciena:params:xml:ns:yang:ciena-ws:ciena-waveserver-system" +ROOT_KEY = "waveserver-system" +RESOURCE = "system" +XML_ITEMS = "None" +XML_ITEMS_KEY = "None" + + +class System(ConfigBase): + """ + The waveserverai_system class + """ + + gather_subset = ["!all", "!min"] + gather_network_resources = [RESOURCE] + + def __init__(self, module): + super(System, self).__init__(module) + + def get_facts(self): + """Get the 'facts' (the current configuration) + + :rtype: A dictionary + :returns: The current configuration as a dictionary + """ + facts, _warnings = Facts(self._module).get_facts(self.gather_subset, self.gather_network_resources) + result = facts["ansible_network_resources"].get(RESOURCE) + if not result: + return [] + return result + + def execute_module(self): + """Execute the module + + :rtype: A dictionary + :returns: The result from module execution + """ + result = {"changed": False} + have = self.get_facts() + config_dict = self.set_config(have) + + if config_dict: + config_xml = self._create_xml_config_generic(config_dict) + config = '' f"{config_xml}" "" + try: + self._module._connection.edit_config(config=config, target="running") + except Exception as e: + return {"failed": True, "msg": str(e)} + + result["changed"] = True + result["xml"] = config_xml + + changed_facts = self.get_facts() + + result["changed"] = config_is_diff(have, changed_facts) + + result["before"] = have + if self.state in self.ACTION_STATES: + if result["changed"]: + result["after"] = changed_facts + + elif self.state == "gathered": + result["gathered"] = have + + return result + + def set_config(self, have): + """Collect the configuration from the args passed to the module, + collect the current configuration (as a dict from facts) + + :rtype: A list + :returns: the commands necessary to migrate the current configuration + to the desired configuration + """ + want = self._module.params["config"] + state = self._module.params["state"] + state_methods = { + "merged": self._state_merged, + "deleted": self._state_deleted, + } + config_dict = state_methods[state](want, have) if state in self.ACTION_STATES else {} + return config_dict + + def _populate_xml_subtree(self, parent: Element, data: dict): + for key, value in data.items(): + sanitized_key = key.replace("_", "-") + if isinstance(value, dict): + subelem = Element(sanitized_key) + self._populate_xml_subtree(subelem, value) + parent.append(subelem) + elif isinstance(value, list): + for list_item in value: + subelem = Element(sanitized_key) + self._populate_xml_subtree(subelem, list_item) + parent.append(subelem) + else: + subelem = Element(sanitized_key) + subelem.text = str(value) + if value is not None: + parent.append(subelem) + + def _create_xml_config_generic(self, config_dict_or_list): + if isinstance(config_dict_or_list, dict): + return self.create_xml_config_from_dict(config_dict_or_list) + elif isinstance(config_dict_or_list, list): + return self.create_xml_config_from_list(config_dict_or_list) + else: + raise TypeError(f"Expected a dictionary or a list, got a {type(config_dict_or_list)}") + + def _init_xml_root(self): + return Element("{%s}%s" % (NAMESPACE, ROOT_KEY), nsmap={None: NAMESPACE}) + + def create_xml_config_from_dict(self, config_dict: dict) -> str: + root = self._init_xml_root() + self._populate_xml_subtree(root, config_dict) + return xml_to_string(root).decode() + + def create_xml_config_from_list(self, config_list: list) -> str: + root = self._init_xml_root() + for list_item in config_list: + if not isinstance(list_item, dict): + raise ValueError("List items must be dictionaries.") + subroot = Element(XML_ITEMS) + operation = list_item.pop("operation", None) + self._populate_xml_subtree(subroot, list_item) + if operation: + subroot.set("operation", operation) + root.append(subroot) + return xml_to_string(root).decode() + + def _state_merged(self, want, have): + if isinstance(want, list): + return self._state_merged_list(want, have) + elif isinstance(want, dict): + return self._state_merged_dict(want, have) + + def _state_merged_dict(self, want, have) -> dict: + response = {} + for key, value in want.items(): + if value is None: + continue + if key in have and have[key] == value: + continue + response[key] = value + return response + + def _state_merged_list(self, want, have) -> list: + response = [] + for w_item in want: + if w_item in have: + continue + response.append(w_item) + return response + + def _state_deleted(self, want, have): + response = [] + if not want: + want = have + for config in want: + response.append({"None": config["None"], "operation": "delete"}) + return response diff --git a/plugins/module_utils/network/waveserverai/config/xcvrs/xcvrs.py b/plugins/module_utils/network/waveserverai/config/xcvrs/xcvrs.py old mode 100644 new mode 100755 index 6eaccab..33c9ffd --- a/plugins/module_utils/network/waveserverai/config/xcvrs/xcvrs.py +++ b/plugins/module_utils/network/waveserverai/config/xcvrs/xcvrs.py @@ -1,6 +1,6 @@ # # -*- coding: utf-8 -*- -# Copyright 2021 Ciena +# Copyright 2025 Ciena # GNU General Public License v3.0+ # (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) """ @@ -10,174 +10,189 @@ necessary to bring the current configuration to it's desired end-state is created """ -from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base import ( - ConfigBase, -) -from ansible.module_utils._text import to_text, to_bytes +from __future__ import absolute_import, division, print_function -from ansible_collections.ciena.waveserverai.plugins.module_utils.network.waveserverai.waveserverai import ( - xml_to_string, - fromstring, -) -from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import ( - to_list, +__metaclass__ = type + +try: + from lxml.etree import tostring as xml_to_string, Element + + HAS_LXML = True +except ImportError: + from xml.etree.ElementTree import Element + from xml.etree.ElementTree import tostring as xml_to_string + + HAS_LXML = False + + +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base import ( + ConfigBase, ) from ansible_collections.ciena.waveserverai.plugins.module_utils.network.waveserverai.facts.facts import ( Facts, ) -from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.netconf import ( - remove_namespaces, - build_root_xml_node, - build_child_xml_node, -) - from ansible_collections.ciena.waveserverai.plugins.module_utils.network.waveserverai.utils.utils import ( - config_is_diff + config_is_diff, ) +NAMESPACE = "urn:ciena:params:xml:ns:yang:ciena-ws:ciena-waveserver-xcvr" +ROOT_KEY = "waveserver-xcvrs" +RESOURCE = "xcvrs" +XML_ITEMS = "xcvrs" +XML_ITEMS_KEY = "xcvr-id" + class Xcvrs(ConfigBase): """ The waveserverai_xcvrs class """ - gather_subset = ['!all', '!min'] - gather_network_resources = ['xcvrs'] + gather_subset = ["!all", "!min"] + gather_network_resources = [RESOURCE] def __init__(self, module): super(Xcvrs, self).__init__(module) - def get_xcvrs_facts(self): - """ Get the 'facts' (the current configuration) + def get_facts(self): + """Get the 'facts' (the current configuration) :rtype: A dictionary :returns: The current configuration as a dictionary """ - facts, _warnings = Facts(self._module).get_facts( - self.gather_subset, self.gather_network_resources - ) - xcvrs_facts = facts['ansible_network_resources'].get('xcvrs') - if not xcvrs_facts: + facts, _warnings = Facts(self._module).get_facts(self.gather_subset, self.gather_network_resources) + result = facts["ansible_network_resources"].get(RESOURCE) + if not result: return [] - return xcvrs_facts + return result def execute_module(self): - """ Execute the module + """Execute the module :rtype: A dictionary :returns: The result from module execution """ - result = {'changed': False} - existing_xcvrs_facts = self.get_xcvrs_facts() - config_xmls = self.set_config(existing_xcvrs_facts) + result = {"changed": False} + have = self.get_facts() + config_dict = self.set_config(have) - for config_xml in to_list(config_xmls): - config = f'{config_xml.decode("utf-8")}' - kwargs = { - "config": config, - "target": "running", - "default_operation": "merge", - "format": "xml", - } + if config_dict: + config_xml = self._create_xml_config_generic(config_dict) + config = '' f"{config_xml}" "" + try: + self._module._connection.edit_config(config=config, target="running") + except Exception as e: + return {"failed": True, "msg": str(e)} - self._module._connection.edit_config(**kwargs) - result["xml"] = config_xmls - changed_xcvrs_facts = self.get_xcvrs_facts() + result["changed"] = True + result["xml"] = config_xml - result["changed"] = not config_is_diff(existing_xcvrs_facts, changed_xcvrs_facts) + changed_facts = self.get_facts() - result["before"] = existing_xcvrs_facts - if result["changed"]: - result["after"] = changed_xcvrs_facts + result["changed"] = config_is_diff(have, changed_facts) - return result + result["before"] = have + if self.state in self.ACTION_STATES: + if result["changed"]: + result["after"] = changed_facts - def set_config(self, existing_xcvrs_facts): - """ Collect the configuration from the args passed to the module, - collect the current configuration (as a dict from facts) + elif self.state == "gathered": + result["gathered"] = have - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the desired configuration - """ - want = self._module.params['config'] - have = existing_xcvrs_facts - resp = self.set_state(want, have) - return to_list(resp) + return result - def set_state(self, want, have): - """ Select the appropriate function based on the state provided + def set_config(self, have): + """Collect the configuration from the args passed to the module, + collect the current configuration (as a dict from facts) - :param want: the desired configuration as a dictionary - :param have: the current configuration as a dictionary :rtype: A list :returns: the commands necessary to migrate the current configuration to the desired configuration """ - root = build_root_xml_node("waveserver-xcvrs") + want = self._module.params["config"] state = self._module.params["state"] - if state == "overridden": - config_xmls = self._state_overridden(want, have) - elif state == 'deleted': - config_xmls = self._state_deleted(want, have) - elif state == 'merged': - config_xmls = self._state_merged(want, have) - elif state == 'replaced': - config_xmls = self._state_replaced(want, have) - - for xml in config_xmls: - root.append(xml) - data = remove_namespaces(xml_to_string(root)) - root = fromstring(to_bytes(data, errors="surrogate_then_replace")) - - return xml_to_string(root) - - def _state_replaced(self, want, have): - """ The command generator when state is replaced - - :rtype: A list - :returns: the xml necessary to migrate the current configuration - to the desired configuration - """ - intf_xml = [] - return intf_xml - - def _state_overridden(self, want, have): - """ The command generator when state is overridden - - :rtype: A list - :returns: the xml necessary to migrate the current configuration - to the desired configuration - """ - intf_xml = [] - return intf_xml - - def _state_deleted(self, want, have): - """ The command generator when state is deleted - - :rtype: A list - :returns: the xml necessary to migrate the current configuration - to the desired configuration - """ - intf_xml = [] - return intf_xml + state_methods = { + "merged": self._state_merged, + "deleted": self._state_deleted, + } + config_dict = state_methods[state](want, have) if state in self.ACTION_STATES else {} + return config_dict + + def _populate_xml_subtree(self, parent: Element, data: dict): + for key, value in data.items(): + sanitized_key = key.replace("_", "-") + if isinstance(value, dict): + subelem = Element(sanitized_key) + self._populate_xml_subtree(subelem, value) + parent.append(subelem) + elif isinstance(value, list): + for list_item in value: + subelem = Element(sanitized_key) + self._populate_xml_subtree(subelem, list_item) + parent.append(subelem) + else: + subelem = Element(sanitized_key) + subelem.text = str(value) + if value is not None: + parent.append(subelem) + + def _create_xml_config_generic(self, config_dict_or_list): + if isinstance(config_dict_or_list, dict): + return self.create_xml_config_from_dict(config_dict_or_list) + elif isinstance(config_dict_or_list, list): + return self.create_xml_config_from_list(config_dict_or_list) + else: + raise TypeError(f"Expected a dictionary or a list, got a {type(config_dict_or_list)}") + + def _init_xml_root(self): + return Element("{%s}%s" % (NAMESPACE, ROOT_KEY), nsmap={None: NAMESPACE}) + + def create_xml_config_from_dict(self, config_dict: dict) -> str: + root = self._init_xml_root() + self._populate_xml_subtree(root, config_dict) + return xml_to_string(root).decode() + + def create_xml_config_from_list(self, config_list: list) -> str: + root = self._init_xml_root() + for list_item in config_list: + if not isinstance(list_item, dict): + raise ValueError("List items must be dictionaries.") + subroot = Element(XML_ITEMS) + operation = list_item.pop("operation", None) + self._populate_xml_subtree(subroot, list_item) + if operation: + subroot.set("operation", operation) + root.append(subroot) + return xml_to_string(root).decode() def _state_merged(self, want, have): - """The command generator when state is merged + if isinstance(want, list): + return self._state_merged_list(want, have) + elif isinstance(want, dict): + return self._state_merged_dict(want, have) + + def _state_merged_dict(self, want, have) -> dict: + response = {} + for key, value in want.items(): + if value is None: + continue + if key in have and have[key] == value: + continue + response[key] = value + return response + + def _state_merged_list(self, want, have) -> list: + response = [] + for w_item in want: + if w_item in have: + continue + response.append(w_item) + return response - :rtype: A list - :returns: the xml necessary to migrate the current configuration - to the desired configuration - """ - xcvrs_xml = [] - for child in want: - xcvrs_root = build_root_xml_node("xcvrs") - xcvrs = build_child_xml_node(xcvrs_root, "xcvrs") - build_child_xml_node(xcvrs, "xcvr-id", child["xcvr-id"]) - properties = build_child_xml_node(xcvrs, "properties") - build_child_xml_node( - properties, "mode", child["properties"]["mode"] - ) - xcvrs_xml.append(xcvrs) - return xcvrs_xml + def _state_deleted(self, want, have): + response = [] + if not want: + want = have + for config in want: + response.append({"xcvr-id": config["xcvr-id"], "operation": "delete"}) + return response diff --git a/plugins/module_utils/network/waveserverai/facts/facts.py b/plugins/module_utils/network/waveserverai/facts/facts.py index 3bc4a68..9531040 100644 --- a/plugins/module_utils/network/waveserverai/facts/facts.py +++ b/plugins/module_utils/network/waveserverai/facts/facts.py @@ -21,9 +21,26 @@ ) +from ansible_collections.ciena.waveserverai.plugins.module_utils.network.waveserverai.facts.system.system import ( + SystemFacts, +) + +from ansible_collections.ciena.waveserverai.plugins.module_utils.network.waveserverai.facts.ptps.ptps import ( + PtpsFacts, +) + +from ansible_collections.ciena.waveserverai.plugins.module_utils.network.waveserverai.facts.ports.ports import ( + PortsFacts, +) + FACT_LEGACY_SUBSETS = dict(default=Default, config=Config) -FACT_RESOURCE_SUBSETS = dict(xcvrs=XcvrsFacts) +FACT_RESOURCE_SUBSETS = dict( + ports=PortsFacts, + ptps=PtpsFacts, + xcvrs=XcvrsFacts, + system=SystemFacts, +) class Facts(FactsBase): @@ -35,9 +52,7 @@ class Facts(FactsBase): def __init__(self, module): super(Facts, self).__init__(module) - def get_facts( - self, legacy_facts_type=None, resource_facts_type=None, data=None - ): + def get_facts(self, legacy_facts_type=None, resource_facts_type=None, data=None): """Collect the facts for waveserverai :param legacy_facts_type: List of legacy facts types @@ -48,13 +63,9 @@ def get_facts( """ # netres_choices = FactsArgs.argument_spec['gather_network_resources'].get('choices', []) if self.VALID_RESOURCE_SUBSETS: - self.get_network_resources_facts( - FACT_RESOURCE_SUBSETS, resource_facts_type, data - ) + self.get_network_resources_facts(FACT_RESOURCE_SUBSETS, resource_facts_type, data) if self.VALID_LEGACY_GATHER_SUBSETS: - self.get_network_legacy_facts( - FACT_LEGACY_SUBSETS, legacy_facts_type - ) + self.get_network_legacy_facts(FACT_LEGACY_SUBSETS, legacy_facts_type) return self.ansible_facts, self._warnings diff --git a/plugins/module_utils/network/waveserverai/facts/legacy/base.py b/plugins/module_utils/network/waveserverai/facts/legacy/base.py index 224dfae..e4ef562 100644 --- a/plugins/module_utils/network/waveserverai/facts/legacy/base.py +++ b/plugins/module_utils/network/waveserverai/facts/legacy/base.py @@ -54,9 +54,7 @@ def populate(self): """ reply = get(self.module, filter=("subtree", config_filter)) root = remove_ns(reply) - network_os_version = root.xpath( - "/data/waveserver-software/active/version" - )[0].text + network_os_version = root.xpath("/data/waveserver-software/active/version")[0].text self.facts["version"] = network_os_version config_filter = """ @@ -66,12 +64,8 @@ def populate(self): """ reply = get(self.module, filter=("subtree", config_filter)) root = remove_ns(reply) - serial_number = root.xpath( - "/data/waveserver-chassis/identification/serial-number" - )[0].text - model = root.xpath("/data/waveserver-chassis/identification/model")[ - 0 - ].text + serial_number = root.xpath("/data/waveserver-chassis/identification/serial-number")[0].text + model = root.xpath("/data/waveserver-chassis/identification/model")[0].text self.facts["serialnum"] = serial_number self.facts["model"] = model self.facts["platform"] = "Waveserver Ai" diff --git a/plugins/module_utils/network/waveserverai/facts/ports/ports.py b/plugins/module_utils/network/waveserverai/facts/ports/ports.py new file mode 100755 index 0000000..6c22b0d --- /dev/null +++ b/plugins/module_utils/network/waveserverai/facts/ports/ports.py @@ -0,0 +1,132 @@ +# +# -*- coding: utf-8 -*- +# Copyright 2025 Ciena +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +""" +The waveserverai ports fact class +It is in this file the configuration is collected from the device +for a given resource, parsed, and the facts tree is populated +based on the configuration. +""" +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + + +from copy import deepcopy + +import re # pylint: disable=unused-import +from ansible.module_utils._text import to_bytes +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.netconf import ( + remove_namespaces, +) +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import ( + utils, +) +from ansible_collections.ansible.netcommon.plugins.module_utils.network.netconf.netconf import ( + get, +) +from ansible_collections.ciena.waveserverai.plugins.module_utils.network.waveserverai.argspec.ports.ports import ( + PortsArgs, +) + +try: + from lxml.etree import tostring as xml_to_string, fromstring + + HAS_LXML = True +except ImportError: + from xml.etree.ElementTree import tostring as xml_to_string, fromstring + + HAS_LXML = False + + +class PortsFacts(object): + """The waveserverai ports fact class""" + + def __init__(self, module, subspec="config", options="options"): + self._module = module + self.argument_spec = PortsArgs.argument_spec + spec = deepcopy(self.argument_spec) + if subspec: + if options: + facts_argument_spec = spec[subspec][options] + else: + facts_argument_spec = spec[subspec] + else: + facts_argument_spec = spec + + self.generated_spec = utils.generate_dict(facts_argument_spec) + + def populate_facts(self, connection, ansible_facts, data=None): + """Populate the facts for ports + :param connection: the device connection + :param ansible_facts: Facts dictionary + :param data: previously collected conf + :rtype: dictionary + :returns: facts + """ + if not HAS_LXML: + self._module.fail_json(msg="lxml is not installed.") + + if not data: + config_filter = """ + + + """ + data = get(self._module, filter=("subtree", config_filter)) + + stripped = remove_namespaces(xml_to_string(data)) + data = fromstring(to_bytes(stripped, errors="surrogate_then_replace")) + + resources = data.xpath("//waveserver-ports/ports") + objs = [] + for resource in resources: + if resource: + obj = self.render_config(self.generated_spec, resource) + if obj: + objs.append(obj) + + facts = {} + if objs: + facts["ports"] = [] + params = utils.validate_config(self.argument_spec, {"config": objs}) + for cfg in params["config"]: + facts["ports"].append(utils.remove_empties(cfg)) + + ansible_facts["ansible_network_resources"].update(facts) + return ansible_facts + + def get_xml_value(self, xml_obj, xpath): + result = xml_obj.xpath(xpath) + return result[0].text if result else None + + def recursive_config_fill(self, config, conf, spec, xml_base_path=""): + for key, unused in spec.items(): + modified_key = key.replace("_", "-") + new_base_path = f"{xml_base_path}/{modified_key}" if xml_base_path else modified_key + + if isinstance(spec[key], dict): + config[key] = {} + self.recursive_config_fill(config[key], conf, spec[key], new_base_path) + else: + extracted_value = self.get_xml_value(conf, new_base_path) + if extracted_value is not None: + config[key] = extracted_value + + def render_config(self, spec, conf): + """ + Render config as dictionary structure and delete keys + from spec for null values + + :param spec: The facts tree, generated from the argspec + :param conf: The configuration + :rtype: dictionary + :returns: The generated config + """ + if isinstance(conf, str): + conf = fromstring(conf) + config = {} + self.recursive_config_fill(config, conf, spec) + return utils.remove_empties(config) diff --git a/plugins/module_utils/network/waveserverai/facts/ptps/ptps.py b/plugins/module_utils/network/waveserverai/facts/ptps/ptps.py new file mode 100755 index 0000000..5c28226 --- /dev/null +++ b/plugins/module_utils/network/waveserverai/facts/ptps/ptps.py @@ -0,0 +1,132 @@ +# +# -*- coding: utf-8 -*- +# Copyright 2025 Ciena +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +""" +The waveserverai ptps fact class +It is in this file the configuration is collected from the device +for a given resource, parsed, and the facts tree is populated +based on the configuration. +""" +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + + +from copy import deepcopy + +import re # pylint: disable=unused-import +from ansible.module_utils._text import to_bytes +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.netconf import ( + remove_namespaces, +) +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import ( + utils, +) +from ansible_collections.ansible.netcommon.plugins.module_utils.network.netconf.netconf import ( + get, +) +from ansible_collections.ciena.waveserverai.plugins.module_utils.network.waveserverai.argspec.ptps.ptps import ( + PtpsArgs, +) + +try: + from lxml.etree import tostring as xml_to_string, fromstring + + HAS_LXML = True +except ImportError: + from xml.etree.ElementTree import tostring as xml_to_string, fromstring + + HAS_LXML = False + + +class PtpsFacts(object): + """The waveserverai ptps fact class""" + + def __init__(self, module, subspec="config", options="options"): + self._module = module + self.argument_spec = PtpsArgs.argument_spec + spec = deepcopy(self.argument_spec) + if subspec: + if options: + facts_argument_spec = spec[subspec][options] + else: + facts_argument_spec = spec[subspec] + else: + facts_argument_spec = spec + + self.generated_spec = utils.generate_dict(facts_argument_spec) + + def populate_facts(self, connection, ansible_facts, data=None): + """Populate the facts for ptps + :param connection: the device connection + :param ansible_facts: Facts dictionary + :param data: previously collected conf + :rtype: dictionary + :returns: facts + """ + if not HAS_LXML: + self._module.fail_json(msg="lxml is not installed.") + + if not data: + config_filter = """ + + + """ + data = get(self._module, filter=("subtree", config_filter)) + + stripped = remove_namespaces(xml_to_string(data)) + data = fromstring(to_bytes(stripped, errors="surrogate_then_replace")) + + resources = data.xpath("//waveserver-ptps/ptps") + objs = [] + for resource in resources: + if resource: + obj = self.render_config(self.generated_spec, resource) + if obj: + objs.append(obj) + + facts = {} + if objs: + facts["ptps"] = [] + params = utils.validate_config(self.argument_spec, {"config": objs}) + for cfg in params["config"]: + facts["ptps"].append(utils.remove_empties(cfg)) + + ansible_facts["ansible_network_resources"].update(facts) + return ansible_facts + + def get_xml_value(self, xml_obj, xpath): + result = xml_obj.xpath(xpath) + return result[0].text if result else None + + def recursive_config_fill(self, config, conf, spec, xml_base_path=""): + for key, unused in spec.items(): + modified_key = key.replace("_", "-") + new_base_path = f"{xml_base_path}/{modified_key}" if xml_base_path else modified_key + + if isinstance(spec[key], dict): + config[key] = {} + self.recursive_config_fill(config[key], conf, spec[key], new_base_path) + else: + extracted_value = self.get_xml_value(conf, new_base_path) + if extracted_value is not None: + config[key] = extracted_value + + def render_config(self, spec, conf): + """ + Render config as dictionary structure and delete keys + from spec for null values + + :param spec: The facts tree, generated from the argspec + :param conf: The configuration + :rtype: dictionary + :returns: The generated config + """ + if isinstance(conf, str): + conf = fromstring(conf) + config = {} + self.recursive_config_fill(config, conf, spec) + return utils.remove_empties(config) diff --git a/plugins/module_utils/network/waveserverai/facts/system/system.py b/plugins/module_utils/network/waveserverai/facts/system/system.py new file mode 100755 index 0000000..93144ab --- /dev/null +++ b/plugins/module_utils/network/waveserverai/facts/system/system.py @@ -0,0 +1,125 @@ +# +# -*- coding: utf-8 -*- +# Copyright 2025 Ciena +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +""" +The waveserverai system fact class +It is in this file the configuration is collected from the device +for a given resource, parsed, and the facts tree is populated +based on the configuration. +""" +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + + +from copy import deepcopy + +import re # pylint: disable=unused-import +from ansible.module_utils._text import to_bytes +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.netconf import ( + remove_namespaces, +) +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import ( + utils, +) +from ansible_collections.ansible.netcommon.plugins.module_utils.network.netconf.netconf import ( + get, +) +from ansible_collections.ciena.waveserverai.plugins.module_utils.network.waveserverai.argspec.system.system import ( + SystemArgs, +) + +try: + from lxml.etree import tostring as xml_to_string, fromstring + + HAS_LXML = True +except ImportError: + from xml.etree.ElementTree import tostring as xml_to_string, fromstring + + HAS_LXML = False + + +class SystemFacts(object): + """The waveserverai system fact class""" + + def __init__(self, module, subspec="config", options="options"): + self._module = module + self.argument_spec = SystemArgs.argument_spec + spec = deepcopy(self.argument_spec) + if subspec: + if options: + facts_argument_spec = spec[subspec][options] + else: + facts_argument_spec = spec[subspec] + else: + facts_argument_spec = spec + + self.generated_spec = utils.generate_dict(facts_argument_spec) + + def populate_facts(self, connection, ansible_facts, data=None): + """Populate the facts for system + :param connection: the device connection + :param ansible_facts: Facts dictionary + :param data: previously collected conf + :rtype: dictionary + :returns: facts + """ + if not HAS_LXML: + self._module.fail_json(msg="lxml is not installed.") + + if not data: + config_filter = """ + + + """ + data = get(self._module, filter=("subtree", config_filter)) + + stripped = remove_namespaces(xml_to_string(data)) + data = fromstring(to_bytes(stripped, errors="surrogate_then_replace")) + + resource = data.xpath("//waveserver-system")[0] + obj = self.render_config(self.generated_spec, resource) + + facts = {} + facts["system"] = {} + params = utils.validate_config(self.argument_spec, {"config": obj}) + facts["system"] = params["config"] + + ansible_facts["ansible_network_resources"].update(facts) + return ansible_facts + + def get_xml_value(self, xml_obj, xpath): + result = xml_obj.xpath(xpath) + return result[0].text if result else None + + def recursive_config_fill(self, config, conf, spec, xml_base_path=""): + for key, unused in spec.items(): + modified_key = key.replace("_", "-") + new_base_path = f"{xml_base_path}/{modified_key}" if xml_base_path else modified_key + + if isinstance(spec[key], dict): + config[key] = {} + self.recursive_config_fill(config[key], conf, spec[key], new_base_path) + else: + extracted_value = self.get_xml_value(conf, new_base_path) + if extracted_value is not None: + config[key] = extracted_value + + def render_config(self, spec, conf): + """ + Render config as dictionary structure and delete keys + from spec for null values + + :param spec: The facts tree, generated from the argspec + :param conf: The configuration + :rtype: dictionary + :returns: The generated config + """ + if isinstance(conf, str): + conf = fromstring(conf) + config = {} + self.recursive_config_fill(config, conf, spec) + return utils.remove_empties(config) diff --git a/plugins/module_utils/network/waveserverai/facts/xcvrs/xcvrs.py b/plugins/module_utils/network/waveserverai/facts/xcvrs/xcvrs.py old mode 100644 new mode 100755 index 46292f3..e0846de --- a/plugins/module_utils/network/waveserverai/facts/xcvrs/xcvrs.py +++ b/plugins/module_utils/network/waveserverai/facts/xcvrs/xcvrs.py @@ -1,6 +1,6 @@ # # -*- coding: utf-8 -*- -# Copyright 2021 Ciena +# Copyright 2025 Ciena # GNU General Public License v3.0+ # (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) """ @@ -9,26 +9,35 @@ for a given resource, parsed, and the facts tree is populated based on the configuration. """ +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + + from copy import deepcopy -from ansible.module_utils._text import to_text, to_bytes + +import re # pylint: disable=unused-import +from ansible.module_utils._text import to_bytes +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.netconf import ( + remove_namespaces, +) from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import ( utils, ) from ansible_collections.ansible.netcommon.plugins.module_utils.network.netconf.netconf import ( get, ) -from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.netconf import ( - remove_namespaces, -) from ansible_collections.ciena.waveserverai.plugins.module_utils.network.waveserverai.argspec.xcvrs.xcvrs import ( XcvrsArgs, ) + try: from lxml.etree import tostring as xml_to_string, fromstring HAS_LXML = True except ImportError: - from xml.etree.ElementTree import fromstring, tostring as xml_to_string + from xml.etree.ElementTree import tostring as xml_to_string, fromstring HAS_LXML = False @@ -58,39 +67,54 @@ def populate_facts(self, connection, ansible_facts, data=None): :rtype: dictionary :returns: facts """ + if not HAS_LXML: + self._module.fail_json(msg="lxml is not installed.") + if not data: config_filter = """ - - - - - + + """ data = get(self._module, filter=("subtree", config_filter)) stripped = remove_namespaces(xml_to_string(data)) data = fromstring(to_bytes(stripped, errors="surrogate_then_replace")) - resources = data.xpath("/data/waveserver-xcvrs/xcvrs") - + resources = data.xpath("//waveserver-xcvrs/xcvrs") objs = [] for resource in resources: if resource: obj = self.render_config(self.generated_spec, resource) if obj: objs.append(obj) + facts = {} if objs: facts["xcvrs"] = [] - params = utils.validate_config( - self.argument_spec, {"config": objs} - ) + params = utils.validate_config(self.argument_spec, {"config": objs}) for cfg in params["config"]: facts["xcvrs"].append(utils.remove_empties(cfg)) ansible_facts["ansible_network_resources"].update(facts) return ansible_facts + def get_xml_value(self, xml_obj, xpath): + result = xml_obj.xpath(xpath) + return result[0].text if result else None + + def recursive_config_fill(self, config, conf, spec, xml_base_path=""): + for key, unused in spec.items(): + modified_key = key.replace("_", "-") + new_base_path = f"{xml_base_path}/{modified_key}" if xml_base_path else modified_key + + if isinstance(spec[key], dict): + config[key] = {} + self.recursive_config_fill(config[key], conf, spec[key], new_base_path) + else: + extracted_value = self.get_xml_value(conf, new_base_path) + if extracted_value is not None: + config[key] = extracted_value + def render_config(self, spec, conf): """ Render config as dictionary structure and delete keys @@ -101,9 +125,8 @@ def render_config(self, spec, conf): :rtype: dictionary :returns: The generated config """ - config = deepcopy(spec) - config["xcvr-id"] = utils.get_xml_conf_arg(conf, "xcvr-id") - config["properties"]["mode"] = utils.get_xml_conf_arg( - conf, "state/actual-mode" - ) + if isinstance(conf, str): + conf = fromstring(conf) + config = {} + self.recursive_config_fill(config, conf, spec) return utils.remove_empties(config) diff --git a/plugins/module_utils/network/waveserverai/utils/utils.py b/plugins/module_utils/network/waveserverai/utils/utils.py index 1f8195e..3cf8323 100644 --- a/plugins/module_utils/network/waveserverai/utils/utils.py +++ b/plugins/module_utils/network/waveserverai/utils/utils.py @@ -11,7 +11,7 @@ def config_is_diff(new_config, actual_config): """Compares actual configuration with intended new :rtype: Bool - :returns: True if configs are equal, False if not. + :returns: True if configs are equal, False if not. """ - return new_config == actual_config \ No newline at end of file + return new_config == actual_config diff --git a/plugins/module_utils/network/waveserverai/waveserverai.py b/plugins/module_utils/network/waveserverai/waveserverai.py index 03d2b95..d18eddb 100644 --- a/plugins/module_utils/network/waveserverai/waveserverai.py +++ b/plugins/module_utils/network/waveserverai/waveserverai.py @@ -48,12 +48,8 @@ "host": dict(), "port": dict(type="int"), "username": dict(fallback=(env_fallback, ["ANSIBLE_NET_USERNAME"])), - "password": dict( - fallback=(env_fallback, ["ANSIBLE_NET_PASSWORD"]), no_log=True - ), - "ssh_keyfile": dict( - fallback=(env_fallback, ["ANSIBLE_NET_SSH_KEYFILE"]), type="path" - ), + "password": dict(fallback=(env_fallback, ["ANSIBLE_NET_PASSWORD"]), no_log=True), + "ssh_keyfile": dict(fallback=(env_fallback, ["ANSIBLE_NET_SSH_KEYFILE"]), type="path"), "timeout": dict(type="int"), "transport": dict(default="netconf", choices=["cli", "netconf"]), } @@ -93,9 +89,7 @@ def get_connection(module): if network_api == "cliconf": module._waveserverai_connection = Connection(module._socket_path) elif network_api == "netconf": - module._waveserverai_connection = NetconfConnection( - module._socket_path - ) + module._waveserverai_connection = NetconfConnection(module._socket_path) else: module.fail_json(msg="Invalid connection type %s" % network_api) diff --git a/plugins/modules/waveserverai_facts.py b/plugins/modules/waveserverai_facts.py index c226be9..58281d2 100644 --- a/plugins/modules/waveserverai_facts.py +++ b/plugins/modules/waveserverai_facts.py @@ -94,13 +94,8 @@ def main(): :returns: ansible_facts """ - module = AnsibleModule( - argument_spec=FactsArgs.argument_spec, supports_check_mode=True - ) - warnings = [ - "default value for `gather_subset` " - "will be changed to `min` from `!config` v2.11 onwards" - ] + module = AnsibleModule(argument_spec=FactsArgs.argument_spec, supports_check_mode=True) + warnings = ["default value for `gather_subset` " "will be changed to `min` from `!config` v2.11 onwards"] result = Facts(module).get_facts() diff --git a/plugins/modules/waveserverai_ports.py b/plugins/modules/waveserverai_ports.py new file mode 100755 index 0000000..ef60141 --- /dev/null +++ b/plugins/modules/waveserverai_ports.py @@ -0,0 +1,472 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# Copyright 2025 Ciena +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +############################################# +# WARNING # +############################################# +# +# This file is auto generated by the resource +# module builder playbook. +# +# Do not edit this file manually. +# +# Changes to this file will be over written +# by the resource module builder. +# +# Changes should be made in the model used to +# generate this file or in the resource module +# builder template. +# +############################################# + +""" +The module file for waveserverai_ports +""" + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + + +DOCUMENTATION = """ +--- +module: waveserverai_ports +short_description: Waveserver port configuration and operational data.Manage the ports ports configuration of a Ciena waveserverai device +description: "Waveserver port configuration and operational data.\n Configuration and operational data for the port." +author: Ciena +options: + config: + description: Configuration and operational data for the port. + type: list + elements: dict + suboptions: + channels: + description: List of ODU4 channels within the parent OTU port object. + type: list + elements: dict + suboptions: + channel_id: + description: 'Channel number or ODU4 tributary number within the parent OTU port object. Key value for the channels list. (Key for + list: channels)' + type: int + required: true + id: + description: Channel identification attributes. + type: dict + suboptions: + label: + description: The user-specified label string for this channel object. + type: str + required: false + properties: + description: Channel properties. + type: dict + suboptions: + odu_sd_threshold: + description: ODU4 Signal Degrade threshold value. + type: str + required: false + trace: + description: ODU4 path trace attributes for this channel. + type: dict + suboptions: + exp_dapi: + description: The expected destination access point identifier (DAPI) portion of the received trace string, up to 15 characters, + excluding the first byte in the TTI DAPI overhead, which is implicitly always null. + type: str + required: false + exp_oper: + description: The expected operator-specific portion of the received trace string, up to 32 characters. + type: str + required: false + exp_sapi: + description: The expected source access point identifier (SAPI) portion of the received trace string, up to 15 characters, + excluding the first byte in the TTI SAPI overhead, which is implicitly always null. + type: str + required: false + mismatch_fail_mode: + description: The trail trace identifier (TTI) mismatch failure mode. When TTI mismatch condition occurs, this indicates the + consequent action taken, e.g. whether or not to raise an alarm. + type: str + required: false + choices: + - none + - alarm-only + - squelch-traffic + mismatch_mode: + description: The trail trace identifier (TTI) mismatch mode, indicating which fields of the TTI overhead are used for trace + mismatch detection. + type: str + required: false + choices: + - operator-only + - sapi + - dapi + - sapi-and-dapi + tx_dapi: + description: The destination access point identifier (DAPI) portion of the transmitted trace string, up to 15 characters, + excluding the first byte in the TTI DAPI overhead, which is implicitly always null. + type: str + required: false + tx_oper: + description: The operator-specific portion of the transmitted trace string, up to 32 characters. Ignored if tx-oper-mode is + 'automatic'. + type: str + required: false + tx_oper_mode: + description: Specifies whether to allow manual provisioning of the transmitted TTI string, or let the system assign this value + automatically based on a pre-defined format. + type: str + required: false + choices: + - manual + - automatic + tx_sapi: + description: The source access point identifier (SAPI) portion of the transmitted trace string, up to 15 characters, excluding + the first byte in the TTI SAPI overhead, which is implicitly always null. + type: str + required: false + state: + description: Channel administrative and operational states. + type: dict + suboptions: + admin_state: + description: The configured administrative state of the channel. + type: str + required: false + choices: + - disabled + - enabled + key: channel-id + id: + description: Port identification attributes. + type: dict + suboptions: + type: + description: The port interface type. + type: str + required: false + choices: + - unknown + - ethernet + - otn + - OTUk + - OTUCn + - OTUCn-Flex + - ET + label: + description: The user-specified label string for this port interface. + type: str + required: false + port_id: + description: 'Unique, access identifier string of the port in ''-'' format. (Key for list: ports)' + type: str + required: true + properties: + description: Port properties. + type: dict + suboptions: + connection_peer: + description: Port connection peer list. Indicates the client/line port/channel that may be connected to this line/client port. For + certain client ports, the connection state is user-configurable or can be system assigned on port creation based on bandwidth availability. + For other ports, the connection state is fixed and cannot be manually configured. + type: list + elements: dict + suboptions: + peer_id: + description: 'Specifies the client/line connection information for the port or channel. Client ports can be connected to a line-side + channel or port. Line ports can be connected to a client side port. Line channels can be connected to one or more client ports. + The connection mappings are static and provided by the system based on XCVR configuration. (Key for list: connection-peer)' + type: str + required: true + key: peer-id + connection_state: + description: Specifies whether the line-side bandwidth is allocated for the connection between this client port and its connection + peer. For most client port types, this is enabled by default and cannot be disabled. For certain client ports that can share line-side + bandwidth with other client ports (such as on MOTR-AGG modules), the connection state can be manually configured by the user in + order to assign or release the line-side bandwidth to the desired client. On the line-side, the connection state is read-only. + type: str + required: false + choices: + - disabled + - enabled + ethernet: + description: Ethernet-specific properties. + type: dict + suboptions: + conditioning_holdoff: + description: Number of milliseconds to delay Egress UNI port consequent action for an EPL service. + type: int + required: false + conditioning_type: + description: Egress UNI port consequent action for an EPL service to be applied on a far-end ingress UNI failure or network failure. + Supported values are 'none', 'laser-off', and 'ethernet'. + type: str + required: false + choices: + - none + - laser-off + - ethernet + - otn + - protocol-specific + loopback: + description: Port PHY layer loopback. RX loopback is a loopback forwarding ingress traffic from RX port directly to TX port. TX loopback + is a loopback forwarding egress traffic from TX port directly to RX port, TX loopback is not supported in I-NNI ports. The RX/TX + loopback can only be enabled when the port admin-state is disabled. Enable an RX/TX loopback shall fail when the port has its admin-state + enabled. Users shall be able to disable the xcvr/ptp when its child port loopback enabled. Enable xcvr/ptp shall not enable its + child port with loopback enabled. A port shall has its operational state rx loopback when rx loopback is enabled, and tx loopback + when tx loopback is enabled. + type: str + required: false + choices: + - disabled + - rx + - tx + otn: + description: OTN-specific properties. + type: dict + suboptions: + conditioning_type: + description: Conditioning type for OTN ports. Supported values are 'laser-off' and 'otn'. + type: str + required: false + choices: + - none + - laser-off + - ethernet + - otn + - protocol-specific + odu_sd_threshold: + description: ODUk Signal Degrade threshold value, e.g. '1E-05' to '1E-09'. + type: str + required: false + odu_termination: + description: ODUk termination mode. + type: str + required: false + choices: + - terminated + - passthrough + otu_sd_threshold: + description: OTU Signal Degrade threshold value, e.g. '1E-06' to '1E-09'. + type: str + required: false + overhead_aggregation_mode: + description: Overhead aggregation mode. + type: str + required: false + choices: + - single-slice + - automatic + trace: + description: OTN port trace attributes + type: dict + suboptions: + path: + description: ODUk path trace attributes for this port. + type: dict + suboptions: + exp_dapi: + description: The expected destination access point identifier (DAPI) portion of the received trace string, up to 15 characters, + excluding the first byte in the TTI DAPI overhead, which is implicitly always null. + type: str + required: false + exp_oper: + description: The expected operator-specific portion of the received trace string, up to 32 characters. + type: str + required: false + exp_sapi: + description: The expected source access point identifier (SAPI) portion of the received trace string, up to 15 characters, + excluding the first byte in the TTI SAPI overhead, which is implicitly always null. + type: str + required: false + mismatch_fail_mode: + description: The trail trace identifier (TTI) mismatch failure mode. When TTI mismatch condition occurs, this indicates + the consequent action taken, e.g. whether or not to raise an alarm. + type: str + required: false + choices: + - none + - alarm-only + - squelch-traffic + mismatch_mode: + description: The trail trace identifier (TTI) mismatch mode, indicating which fields of the TTI overhead are used for + trace mismatch detection. + type: str + required: false + choices: + - operator-only + - sapi + - dapi + - sapi-and-dapi + tx_dapi: + description: The destination access point identifier (DAPI) portion of the transmitted trace string, up to 15 characters, + excluding the first byte in the TTI DAPI overhead, which is implicitly always null. + type: str + required: false + tx_oper: + description: The operator-specific portion of the transmitted trace string, up to 32 characters. Ignored if tx-oper-mode + is 'automatic'. + type: str + required: false + tx_oper_mode: + description: Specifies whether to allow manual provisioning of the transmitted TTI string, or let the system assign this + value automatically based on a pre-defined format. + type: str + required: false + choices: + - manual + - automatic + tx_sapi: + description: The source access point identifier (SAPI) portion of the transmitted trace string, up to 15 characters, excluding + the first byte in the TTI SAPI overhead, which is implicitly always null. + type: str + required: false + section: + description: OTUk section trace attributes for this port. + type: dict + suboptions: + exp_dapi: + description: The expected destination access point identifier (DAPI) portion of the received trace string, up to 15 characters, + excluding the first byte in the TTI DAPI overhead, which is implicitly always null. + type: str + required: false + exp_oper: + description: The expected operator-specific portion of the received trace string, up to 32 characters. + type: str + required: false + exp_sapi: + description: The expected source access point identifier (SAPI) portion of the received trace string, up to 15 characters, + excluding the first byte in the TTI SAPI overhead, which is implicitly always null. + type: str + required: false + mismatch_fail_mode: + description: The trail trace identifier (TTI) mismatch failure mode. When TTI mismatch condition occurs, this indicates + the consequent action taken, e.g. whether or not to raise an alarm. + type: str + required: false + choices: + - none + - alarm-only + - squelch-traffic + mismatch_mode: + description: The trail trace identifier (TTI) mismatch mode, indicating which fields of the TTI overhead are used for + trace mismatch detection. + type: str + required: false + choices: + - operator-only + - sapi + - dapi + - sapi-and-dapi + tx_dapi: + description: The destination access point identifier (DAPI) portion of the transmitted trace string, up to 15 characters, + excluding the first byte in the TTI DAPI overhead, which is implicitly always null. + type: str + required: false + tx_oper: + description: The operator-specific portion of the transmitted trace string, up to 32 characters. Ignored if tx-oper-mode + is 'automatic'. + type: str + required: false + tx_oper_mode: + description: Specifies whether to allow manual provisioning of the transmitted TTI string, or let the system assign this + value automatically based on a pre-defined format. + type: str + required: false + choices: + - manual + - automatic + tx_sapi: + description: The source access point identifier (SAPI) portion of the transmitted trace string, up to 15 characters, excluding + the first byte in the TTI SAPI overhead, which is implicitly always null. + type: str + required: false + state: + description: Port administrative and operational states. + type: dict + suboptions: + admin_state: + description: The configured administrative state of the port. + type: str + required: false + choices: + - enabled + - disabled + key: port-id + state: + description: + - The state of the configuration + type: str + choices: + - merged + default: merged + +""" +EXAMPLES = """ +# Using merged + +- name: Disable port + ciena.waveserver5.waveserver5_ports: + config: + - port_id: 5-1 + state: + admin_state: disabled + state: merged +- name: Enable port + ciena.waveserver5.waveserver5_ports: + config: + - port_id: 5-1 + state: + admin_state: enabled + state: merged +""" + +RETURN = """ +before: + description: The configuration prior to the model invocation. + returned: always + type: dict + sample: > + The configuration returned will always be in the same format + of the parameters above. +after: + description: The resulting configuration model invocation. + returned: when changed + type: dict + sample: > + The configuration returned will always be in the same format + of the parameters above. +xml: + description: The set of xml commands pushed to the remote device. + returned: always + type: list + sample: ['foo'] +""" + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.ciena.waveserverai.plugins.module_utils.network.waveserverai.argspec.ports.ports import ( + PortsArgs, +) +from ansible_collections.ciena.waveserverai.plugins.module_utils.network.waveserverai.config.ports.ports import ( + Ports, +) + + +def main(): + """ + Main entry point for module execution + + :returns: the result form module invocation + """ + module = AnsibleModule(argument_spec=PortsArgs.argument_spec, supports_check_mode=True) + + result = Ports(module).execute_module() + module.exit_json(**result) + + +if __name__ == "__main__": + main() diff --git a/plugins/modules/waveserverai_ptps.py b/plugins/modules/waveserverai_ptps.py new file mode 100755 index 0000000..2755ce6 --- /dev/null +++ b/plugins/modules/waveserverai_ptps.py @@ -0,0 +1,255 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# Copyright 2025 Ciena +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +############################################# +# WARNING # +############################################# +# +# This file is auto generated by the resource +# module builder playbook. +# +# Do not edit this file manually. +# +# Changes to this file will be over written +# by the resource module builder. +# +# Changes should be made in the model used to +# generate this file or in the resource module +# builder template. +# +############################################# + +""" +The module file for waveserverai_ptps +""" + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + + +DOCUMENTATION = """ +--- +module: waveserverai_ptps +short_description: Waveserver Physical Termination Point (PTP) configuration and operational data.Manage the ptps ptps configuration of a Ciena + waveserverai device +description: "Waveserver Physical Termination Point (PTP) configuration and operational data.\n List of PTP objects." +author: Ciena +options: + config: + description: List of PTP objects. + type: list + elements: dict + suboptions: + id: + description: Identification information of this PTP instance. + type: dict + suboptions: + label: + description: Label of the PTP instance + type: str + required: false + properties: + description: All the configurable and operational data of this PTP instance. + type: dict + suboptions: + type: + description: Physical Termination Point type. + type: str + required: false + choices: + - unknown + - WLAi + - WLAi-iOPS + - 4x25G + - 10G + - OCH + - OSC + - OSC-Add-Drop + - OTM + - WL5e + - WL5n + - 100G + - 4x100G + - 8x50G + - 2x50G + - 400ZR + forward_error_correction: + description: FEC - disabled, enabled, automatic. FEC format is determined by modem + type: str + required: false + choices: + - disabled + - enabled + - automatic + is_coherent: + description: Indicate whether or not this ptp can support coherent attributes + type: bool + required: false + thresholds: + description: Common container for PTP threshold configuration data. + type: dict + suboptions: + fec_detected_degrade_threshold: + description: FEC Signal Degrade configurable threshold, expressed in exponential notation, e.g. '1E-06' to '1E-09'. + type: str + required: false + fec_excessive_degrade_threshold: + description: FEC Signal Fail configurable threshold, expressed in exponential notation, e.g. '1E-06' to '1E-09'. + type: str + required: false + hccs_db: + description: High Correction Count Second (HCCS) Threshold, expressed in dB notation. + type: float + required: false + pre_fec_sd_db: + description: Pre-FEC Signal Degrade threshold value, expressed in dB notation. + type: float + required: false + pre_fec_sf_db: + description: Pre-FEC Signal Fail threshold value, expressed in dB notation. + type: float + required: false + topology_adjacency: + description: Container for PTP topology adjacency data. + type: dict + suboptions: + port_in: + description: Port in. + type: str + required: false + port_out: + description: Port out. + type: str + required: false + transmitter: + description: PTP transmitter related config and operational data fields. + type: dict + suboptions: + state: + description: Transmitter state (enabled or disabled) of the PTP. PTP Admin State cannot be changed to enabled unless the transmitter + state is enabled. + type: str + required: false + choices: + - disabled + - enabled + - not-applicable + xcvr_type: + description: Transceiver type of the XCVR that's associated with this PTP. Type depends on what is physically plugged in. Read only + attribute. + type: str + required: false + choices: + - not-available + - unsupported + - QSFPplus + - QSFP28 + - WaveLogic 3 Extreme + - WaveLogic Ai + - SFP + - none + - QSFP-DD + - WaveLogic 5e + - CFP2-DCO + ptp_id: + description: 'Unique, access identifier string of the PTP (e.g., ''1-1''). Key value for the PTP list. Read-only attribute. (Key for list: + ptps)' + type: str + required: true + state: + description: State information of this PTP instance. + type: dict + suboptions: + admin_state: + description: Administrative state (enabled or disabled) of the PTP. If Admin State is set to enabled, majority of the PTP fields will + no longer be modifiable. When PTP Transmitter State is Disabled, PTP Admin State cannot be changed from Disabled to Enabled. + type: str + required: false + choices: + - disabled + - enabled + spli_management: + description: Whether or not Service Photonic Layer Interoperations management protocol is enabled on this PTP. + type: str + required: false + choices: + - disabled + - enabled + key: ptp-id + state: + description: + - The state of the configuration + type: str + choices: + - merged + default: merged + +""" +EXAMPLES = """ +# Using merged + +- name: Disable ptp + ciena.waveserver5.waveserver5_ptps: + config: + - ptp_id: 5-1 + state: + admin_state: disabled + state: merged +- name: Enable ptp + ciena.waveserver5.waveserver5_ptps: + config: + - ptp_id: 5-1 + state: + admin_state: enabled + state: merged +""" + +RETURN = """ +before: + description: The configuration prior to the model invocation. + returned: always + type: dict + sample: > + The configuration returned will always be in the same format + of the parameters above. +after: + description: The resulting configuration model invocation. + returned: when changed + type: dict + sample: > + The configuration returned will always be in the same format + of the parameters above. +xml: + description: The set of xml commands pushed to the remote device. + returned: always + type: list + sample: ['foo'] +""" + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.ciena.waveserverai.plugins.module_utils.network.waveserverai.argspec.ptps.ptps import ( + PtpsArgs, +) +from ansible_collections.ciena.waveserverai.plugins.module_utils.network.waveserverai.config.ptps.ptps import ( + Ptps, +) + + +def main(): + """ + Main entry point for module execution + + :returns: the result form module invocation + """ + module = AnsibleModule(argument_spec=PtpsArgs.argument_spec, supports_check_mode=True) + + result = Ptps(module).execute_module() + module.exit_json(**result) + + +if __name__ == "__main__": + main() diff --git a/plugins/modules/waveserverai_system.py b/plugins/modules/waveserverai_system.py new file mode 100755 index 0000000..377905f --- /dev/null +++ b/plugins/modules/waveserverai_system.py @@ -0,0 +1,1198 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# Copyright 2025 Ciena +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +############################################# +# WARNING # +############################################# +# +# This file is auto generated by the resource +# module builder playbook. +# +# Do not edit this file manually. +# +# Changes to this file will be over written +# by the resource module builder. +# +# Changes should be made in the model used to +# generate this file or in the resource module +# builder template. +# +############################################# + +""" +The module file for waveserverai_system +""" + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + + +DOCUMENTATION = """ +--- +module: waveserverai_system +short_description: Waveserver System configuration data and operational data.Manage the system configuration of a Ciena waveserverai device +description: Waveserver System configuration data and operational data. +author: Ciena +options: + config: + description: Waveserver System configuration data and operational data. + type: dict + suboptions: + auto_config_recovery: + description: Waveserver system automatic configuration recovery for CP replacement attributes. + type: dict + suboptions: + admin_state: + description: Indicate whether auto config recovery is enabled. + type: str + required: false + choices: + - disabled + - enabled + audit_interval: + description: Audit Interval in minutes. + type: int + required: false + config_mismatch_detection_state: + description: Indicate whether config mismatch detection for CP replacement is enabled. + type: str + required: false + choices: + - disabled + - enabled + passphrase: + description: Passphrase used for backup encryption (Default; none, use builtin key). + type: str + required: false + client_config: + description: Waveserver client configuration attributes. + type: dict + suboptions: + dhcp: + description: Waveserver DHCP client configuration attributes. + type: dict + suboptions: + admin_state: + description: DHCP client administrative atate + type: str + required: false + choices: + - disabled + - enabled + discovery_interval: + description: DHCP client discovery interval in seconds. + type: int + required: false + interface_type: + description: DHCP client interface type. + type: str + required: false + choices: + - remote + - active + options: + description: DHCP Options. A list of the enabled/requested options configured on the DHCP client. + type: dict + suboptions: + bootfile_name: + description: DHCP Option 67 - Bootfile Name. + type: bool + required: false + domain_name: + description: DHCP Option 15 - Domain Name. + type: bool + required: false + domain_server: + description: DHCP Option 6 - Domain Name Server. + type: bool + required: false + host_name: + description: DHCP Option 12 - Host Name. + type: bool + required: false + lease_time: + description: DHCP Option 51 - Lease Time. + type: bool + required: false + log_server: + description: DHCP Option 7 - Log Server. + type: bool + required: false + ntp_servers: + description: DHCP Option 42 - Network Time Protocol Servers. + type: bool + required: false + router: + description: DHCP Option 3 - Router. + type: bool + required: false + subnet_mask: + description: DHCP Option 1 - Subnet Mask. + type: bool + required: false + tftp_server_name: + description: DHCP Option 66 - TFTP Server Name. + type: bool + required: false + time_offset: + description: DHCP Option 2 - Time Offset. + type: bool + required: false + requested_lease_time: + description: DHCP client requested lease time in seconds. + type: int + required: false + dhcpv6: + description: Waveserver DHCPv6 client configuration attributes. + type: dict + suboptions: + admin_state: + description: DHCPv6 client administrative atate + type: str + required: false + choices: + - disabled + - enabled + options_state: + description: DHCPv6 Options. A list of the enabled/requested options configured on the DHCPv6 client. + type: dict + suboptions: + bootfile_url: + description: DHCPv6 Option 59 - Bootfile URL. + type: bool + required: false + dns_servers: + description: DHCPv6 Option 23 - Domain Name System Servers. + type: bool + required: false + ntp_server: + description: DHCPv6 Option 56 - Network Time Protocol Servers. + type: bool + required: false + dns: + description: Waveserver DNS client configuration attributes. + type: dict + suboptions: + admin_state: + description: DNS client administrative state. + type: str + required: false + choices: + - disabled + - enabled + server: + description: List of DNS servers to use for domain name resolution. DNS servers can be manually created by the user, or dynamically + created by via DHCP. Waveserver supports up to 3 manually provisioned DNS servers and up to 2 DHCP-assigned servers. + type: list + elements: dict + suboptions: + admin_state: + description: DNS remote server administrative state. + type: str + required: false + choices: + - disabled + - enabled + ip_address: + description: 'IP address associated with the remote DNS server. (Key for list: server)' + type: str + required: true + user_priority: + description: User-assigned DNS server priority. Only applicable when server source is 'user' or 'both'. Ignored otherwise. + type: int + required: false + key: ip-address + grpc: + description: Waveserver gRPC Client configuration attributes. + type: dict + suboptions: + server: + description: List of remote servers. Entries may be configured in this list to configure trusted-dns on a per-server basis, for + example in certain dial-out telemetry operational workflows. + type: list + elements: dict + suboptions: + address: + description: 'Configured IP address or Domain Name of the remote server/collector. (Key for list: server)' + type: str + required: true + trusted_dns: + description: Trusted DNS name used to check peer's certificate. The name should be a fully qualified domain name. + type: str + required: true + key: address + ntp: + description: Waveserver NTP client configuration attributes. + type: dict + suboptions: + admin_state: + description: NTP client administrative state. + type: str + required: false + choices: + - disabled + - enabled + authentication_state: + description: NTP client authentication state. When enabled, only MD5 authenticated packets will be used to synchronize the time. + type: str + required: false + choices: + - disabled + - enabled + autokey_authentication_state: + description: NTP client autokey authentication state. A RSA host key and an X509 certificate (RSA-SHA1) will be created (if not + exist) and saved. The host key and certificate will be loaded to NTP daemon only if the NTP autokey is enabled on Waveserver + type: str + required: false + choices: + - disabled + - enabled + mode: + description: NTP client mode. + type: str + required: false + choices: + - polling + - broadcast + - multicast + multicast_server: + description: List of NTP multicast servers to use for time synchronization. + type: list + elements: dict + suboptions: + ip_address: + description: 'Configured IPv6 address for NTP Multicast server. (Key for list: multicast-server)' + type: str + required: true + key: ip-address + ntp_key: + description: List of NTP authentication keys. + type: list + elements: dict + suboptions: + key_id: + description: 'Unique index value for the NTP authentication key. (Key for list: ntp-key)' + type: int + required: true + key_type: + description: Encryption type used for the NTP authentication key. + type: str + required: false + choices: + - MD5 + - SHA1 + key_value: + description: NTP authentication key value. + type: str + required: false + key: key-id + polling_interval: + description: The NTP client polling interval, in seconds. Applicable only when NTP client mode is set to 'polling'. This is a + global setting that applies to all configured NTP peer servers. + type: int + required: false + server: + description: List of NTP servers to use for time synchronization. + type: list + elements: dict + suboptions: + address: + description: 'Configured IP address or Domain Name of the remote NTP server. (Key for list: server)' + type: str + required: true + admin_state: + description: NTP remote server administrative state. + type: str + required: false + choices: + - disabled + - enabled + autokey_authentication: + description: Whether autokey authentication method is enabled for the server. The 'enabled' state will only be effective when + the 'ntp/authentication-state' is 'enabled'. + type: str + required: false + choices: + - disabled + - enabled + key_id: + description: Leafref to 'ntp-key' list 'key-id' values. + type: str + required: false + key: address + sha1key_authentication_state: + description: NTP SHA1 administrative state. When enabled, only SHA1 authenticated packets will be used to synchronize the time. + type: str + required: false + choices: + - disabled + - enabled + default_settings: + description: Waveserver system default configuration values. + type: dict + suboptions: + conditioning: + description: Waveserver system default conditioning values. Ports are created with these values. When the system defaults are set, + all existing ports have their values updated. + type: dict + suboptions: + type: + description: Egress UNI port consequent action for an EPL service to be applied on a far-end ingress UNI failure or network failure. + type: str + required: false + choices: + - none + - laser-off + - ethernet + - otn + - protocol-specific + holdoff: + description: Number of milliseconds the failure must be present before applying Egress UNI port consequent action for an EPL service. + type: int + required: false + remote_management_auto_enable: + description: Enable GCC interfaces when module is created. + type: bool + required: false + terrestrial_reach_limit: + description: The maximum reach allowed in km. The possible values are [250, 500, 1000, 2000, 2100, 3000, 4000, 5000, 8000] for terrestrial + modem class. [0] if the value is unknown/unavailable or inapplicable. + type: int + required: false + domain_name: + description: Waveserver system domain name attributes. + type: dict + suboptions: + config_domain_name: + description: User configured domain name. + type: str + required: false + environment: + description: Waveserver system linux environment attributes. + type: dict + suboptions: + diag: + description: System level default environment configuration for diag level users. + type: dict + suboptions: + shell: + description: The default shell session type for authenticated diag users. + type: str + required: false + choices: + - cli + - system + sudo: + description: Specifies whether or not diag users will be automatically added to the sudoers list. Default is disabled. + type: bool + required: false + root: + description: Waveserver system user root configuration. + type: dict + suboptions: + password: + description: User root password string. + type: str + required: false + secret: + description: The encrypted user password string, supplied as a hashed value. + type: str + required: false + shell: + description: System level default environment configuration for diagnostic shell access. + type: dict + suboptions: + admin_state: + description: Diagnostic shell access control. Default value is enabled. Only super level user is allowed to change to disabled. + Setting back to enabled state requires a reset-to-factory-defaults. When disabled, diag user cannot access the diagnostic shell. + Root account is blocked from logging in to the console port. CLI commands to modify files on the filesystem are rejected. + type: str + required: false + choices: + - disabled + - enabled + global_provisioning: + description: Waveserver system global provisioning attributes. + type: dict + suboptions: + encryption_only: + description: A boolean value indicating whether the current chassis configuration requires encryption modules only. If true, a user-initiated + request to pre-create clear-text MOTR equipment will be rejected. + type: bool + required: false + line_config: + description: Waveserver system line configuration. + type: dict + suboptions: + line_protection: + description: Line protection settings. If line protection is enabled, this means that the photonic line the Waveserver is connected + to has protection enabled. In the event of a line side fault, the protection card on the line side will select the protection + path and the modems will reacquire the signal on the alternate path. While the switch is occuring, link state messaging will + be disabled to the clients so that the connected devices do not attempt a switch or a restoration. + type: str + required: false + choices: + - unprotected + - trunk-ops + host_name: + description: Waveserver system host name attributes. + type: dict + suboptions: + config_host_name: + description: User configured host name. + type: str + required: false + id: + description: Waveserver system identification attributes. + type: dict + suboptions: + group: + description: Waveserver system group attributes. + type: dict + suboptions: + description: + description: 'A description for the group of Waveservers. ' + type: str + required: false + id: + description: An integer to uniquely identify a group of Waveservers within a site. + type: int + required: false + name: + description: A name for the group of Waveservers. + type: str + required: false + member: + description: Waveserver system member attributes. + type: dict + suboptions: + description: + description: A description for the Waveserver chassis. + type: str + required: false + cluster_enrollment: + description: Attribute indicating if the waveserver member is enrolled into culster. + type: str + required: false + choices: + - disabled + - enabled + frame_identification: + description: A description to identify the location of the Waveserver chassis within the data center. For example, the building, + floor, aisle, frame number, etc. + type: str + required: false + id: + description: An integer to uniquely identify a Waveserver chassis within a group of Waveservers. + type: int + required: false + name: + description: A name for the Waveserver chassis. Set to the host name by default. + type: str + required: false + rack_unit_number: + description: A logical identifier for the location of the Waveserver within the frame or rack. For example, the device at the + top could be labeled unit 1. + type: int + required: false + network: + description: Waveserver system network attributes. + type: dict + suboptions: + description: + description: A description for the sub-network domain. + type: str + required: false + id: + description: An integer to uniquely identify the sub-network domain in which this Waveserver chassis is managed. + type: int + required: false + name: + description: A name for the sub-network domain. + type: str + required: false + site: + description: Waveserver system site attributes. + type: dict + suboptions: + description: + description: The site description + type: str + required: false + address: + description: The street address of the site. + type: str + required: false + id: + description: 'An integer to uniquely identify the site where this Waveserver is located. This is used to help group Waveservers + together with line system equipment. All equipment in a common site should share the same site identifier. ' + type: int + required: false + latitude: + description: Geographic coordinate for the site location in degrees. + type: float + required: false + longitude: + description: Geographic coordinate for the site location in degrees. + type: float + required: false + name: + description: The name for the site where the Waveserver is located. + type: str + required: false + lamp_test: + description: Waveserver lamp test attributes. + type: dict + suboptions: + admin_state: + description: Enable or disable the system lamp test. The lamp-test admin-state will be automatically disabled once the timeout period + has expired. + type: str + required: false + choices: + - disabled + - enabled + target_id: + description: Lamp testing target ID string. Must be specified when target-type is 'slot' or 'port'. When the target-type is 'slot' + the target-id should be a slot number (e.g. 1, 2, or 3). When the target-type is 'port' the target-id should be a port-id (e.g. + '1-1') or comma-separated list of port-id's (e.g. '1-1,1-2,1-3'). + type: str + required: false + target_type: + description: Lamp testing target type. It can be chassis, slot, or port. The default type is chassis. When the target-type is slot + or port, the slot/port identifier should also be set for the selected target(s) to be tested. + type: str + required: false + choices: + - chassis + - slot + - port + timeout: + description: The number of seconds the lamp flash testing will be operating when enabled. + type: int + required: false + management: + description: Waveserver system management configuration attributes. + type: dict + suboptions: + caching: + description: Run time cache setting for config operations on management interfaces. + type: dict + suboptions: + openconfig: + description: OpenConfig cache config enable or disable. + type: str + required: false + choices: + - disabled + - enabled + query_limits: + description: Run time query limits for get operations on management interfaces. + type: dict + suboptions: + gnmi: + description: gNMI protocol source type. + type: dict + suboptions: + pm_history_bins: + description: Maximum query limit for PM history bins in gNMI get responses. + type: int + required: false + netconf: + description: NETCONF protocol source type. + type: dict + suboptions: + pm_history_bins: + description: Maximum query limit for PM history bins in NETCONF get responses. + type: int + required: false + rest: + description: REST protocol source type. + type: dict + suboptions: + pm_history_bins: + description: Maximum query limit for PM history bins in REST get responses. + type: int + required: false + root_scope: + description: Control for root-level get and replace operations for management interfaces. + type: dict + suboptions: + gnmi: + description: gNMI protocol source type. + type: dict + suboptions: + get: + description: Scope for gNMI root-level get operations. + type: str + required: false + choices: + - native + - openconfig + - all + replace: + description: Scope for gNMI root-level replace operations. + type: str + required: false + choices: + - native + - openconfig + - all + netconf: + description: NETCONF protocol source type. + type: dict + suboptions: + get: + description: Scope for NETCONF root-level get operations. + type: str + required: false + choices: + - native + - openconfig + - all + replace: + description: Scope for NETCONF root-level replace operations. + type: str + required: false + choices: + - native + - openconfig + - all + rest: + description: REST protocol source type. + type: dict + suboptions: + get: + description: Scope for REST root-level get operations. + type: str + required: false + choices: + - native + - openconfig + - all + replace: + description: Scope for REST root-level replace operations. + type: str + required: false + choices: + - native + - openconfig + - all + server_config: + description: Waveserver system server configuration attributes. + type: dict + suboptions: + global_inactivity_timeout: + description: Global session inactivity timeout period, in minutes. Can be overridden by specific server type settings, if applicable. + type: int + required: false + global_inactivity_timer: + description: Global session inactivity timer state. + type: str + required: false + choices: + - disabled + - enabled + grpc: + description: gRPC server configuration. + type: dict + suboptions: + admin_state: + description: gRPC server administrative state. + type: str + required: false + choices: + - disabled + - enabled + certificate_verification: + description: gRPC server configuration data for client certificate verification through mutual authentication. + type: dict + suboptions: + certificate_name: + description: The certificate name used by the gRPC server. + type: str + required: false + mutual_authentication: + description: gRPC server mutual authentication configuration data. + type: dict + suboptions: + admin_state: + description: Whether gRPC server mutual authentication verification is enabled or disabled. + type: str + required: false + choices: + - disabled + - enabled + grpc_server_state: + description: Indicate whether gRPC server is enabled. This leaf is deprecated, replaced by admin-state in grpc container. + type: str + required: false + choices: + - disabled + - enabled + https: + description: HTTPS server configuration. + type: dict + suboptions: + admin_state: + description: HTTPS server administrative state. + type: str + required: false + choices: + - disabled + - enabled + certificate_verification: + description: The HTTPS server configuration data for client certificate verification through mutual authentication and Online + Certificate Status Protocol(OCSP). + type: dict + suboptions: + certificate_name: + description: The certificate name used by the HTTPS server. + type: str + required: false + mutual_authentication: + description: HTTPS server mutual authentication configuration data. + type: dict + suboptions: + admin_state: + description: Whether apache HTTPS server mutual authentication verification is enabled or disabled. + type: str + required: false + choices: + - disabled + - enabled + ocsp: + description: HTTPS server configuration data for OCSP verification. + type: dict + suboptions: + admin_state: + description: Whether OCSP verification is enabled or disabled. + type: str + required: false + choices: + - disabled + - enabled + default_responder: + description: Default OCSP responder. It should be in URL format. e.g. https;//192.168.20.2;2440. If the 'responder-preference' + is not set to 'default-responder', the URL given will be used only if no responder URL (AIA extension) is specified + in the client certificate being verified. + type: str + required: false + nonce: + description: Determine whether queries to OCSP responders should contain a nonce or not. By default nonce option is turned + on. + type: str + required: false + choices: + - 'off' + - 'on' + responder_preference: + description: If 'responder-preference' is set to aia, the OCSP responder referred in client certificate AIA extension + will be used first during OCSP certificate validation. If it is set to 'default-responder', the configured default OCSP + responder is used first. + type: str + required: false + choices: + - aia + - default-responder + trusted_dns: + description: Trusted DNS name used to check peer's certificate. The name should be fully qualified whenever possible, and + can accept a leading period as wildcard. + type: str + required: false + craft_gui_admin_state: + description: Craft GUI administrative state. + type: str + required: false + choices: + - disabled + - enabled + inactivity_timeout: + description: HTTPS inactivity timeout period, in minutes. + type: int + required: false + web_ui_file_transfer_admin_state: + description: Web Ui File Transfer administrative state. + type: str + required: false + choices: + - disabled + - enabled + netconf: + description: NETCONF server configuration. + type: dict + suboptions: + admin_state: + description: Indicate whether NETCONF server is enabled. + type: str + required: false + choices: + - disabled + - enabled + candidate_advertisement: + description: Whether NETCONF candidate advertisement is enabled or disabled. + type: str + required: false + choices: + - disabled + - enabled + netconf_server_state: + description: Indicate whether NETCONF server is enabled. + type: str + required: false + choices: + - disabled + - enabled + scp_server_state: + description: Indicate whether SCP server is enabled. + type: str + required: false + choices: + - disabled + - enabled + sftp_server_state: + description: Indicate whether SFTP server is enabled. + type: str + required: false + choices: + - disabled + - enabled + ssh: + description: SSH server configuration. + type: dict + suboptions: + algorithms: + description: Waveserver SSH algorithm lists. + type: dict + suboptions: + encryption: + description: List of SSH encryption algorithms. The algorithm names are system assigned. + type: list + elements: dict + suboptions: + admin_state: + description: SSH encryption algorithm administrative state. + type: str + required: false + choices: + - disabled + - enabled + algorithm_name: + description: 'The SSH encryption algorithm name. (Key for list: encryption)' + type: str + required: true + key: algorithm-name + key_exchange: + description: List of SSH key exchange algorithms. The algorithm names are system assigned. + type: list + elements: dict + suboptions: + admin_state: + description: SSH key exchange algorithm administrative state. + type: str + required: false + choices: + - disabled + - enabled + algorithm_name: + description: 'The SSH key exchange algorithm name. (Key for list: key-exchange)' + type: str + required: true + key: algorithm-name + message_authentication_code: + description: List of SSH message authentication code algorithms. The algorithm names are system assigned. + type: list + elements: dict + suboptions: + admin_state: + description: SSH message authentication code algorithm administrative state. + type: str + required: false + choices: + - disabled + - enabled + algorithm_name: + description: 'The SSH message authentication code algorithm name. (Key for list: message-authentication-code)' + type: str + required: true + key: algorithm-name + public_key_authentication: + description: List of SSH public key authentication algorithms. The algorithm names are system assigned. + type: list + elements: dict + suboptions: + admin_state: + description: SSH public key authentication algorithm administrative state. + type: str + required: false + choices: + - disabled + - enabled + algorithm_name: + description: 'The SSH public key authentication algorithm name. (Key for list: public-key-authentication)' + type: str + required: true + key: algorithm-name + allowed_clients: + description: List of allowed client IP addresses. + type: list + elements: dict + suboptions: + ip_address: + description: 'IP address for allowed SSH clients. When the list is not empty, only the clients in the list can login to the + SSH server. (Key for list: allowed-clients)' + type: str + required: true + key: ip-address + authentication_retries: + description: Number of authentication retries allowed before the SSH connection is dropped. + type: int + required: false + listener_port: + description: Configured SSH listener port. Default is port 22. + type: int + required: false + web_server_state: + description: Indicate whether web server is enabled, HTTPS only. This leaf is deprecated, replaced by admin-state in https container. + type: str + required: false + choices: + - disabled + - enabled + shell: + description: Waveserver system CLI shell/session attributes. + type: dict + suboptions: + inactivity_timeout: + description: Leafref to global session inactivity timeout period, in minutes. This attribute is deprecated. Has been moved to server-config + container. + type: str + required: false + inactivity_timer: + description: Leafref to global session inactivity timer state. This attribute is deprecated. Has been moved to server-config container. + type: str + required: false + login_authentication_message: + description: Toggles the authentication message for CLI/shell session logins. + type: str + required: false + choices: + - disabled + - enabled + login_banner_file: + description: Local file name containing the banner text to be displayed prior to CLI/shell session logins. + type: str + required: false + more: + description: Global CLI/shell session pagination (more) behavior. + type: str + required: false + choices: + - disabled + - enabled + more_lines: + description: Global CLI/shell session pagination (more) number of lines per page. + type: int + required: false + welcome_banner_file: + description: Local file name containing the welcome banner text to be displayed upon successful CLI/shell session logins. + type: str + required: false + ssl: + description: Waveserver SSL security configuration and operational data. + type: dict + suboptions: + tls_cipher_suite_algorithms: + description: List of transport layer security(TLS) cipher suite algorithms. The algorithm names are system assigned. + type: list + elements: dict + suboptions: + admin_state: + description: TLS cipher suite algorithm administrative state. + type: str + required: false + choices: + - disabled + - enabled + algorithm_name: + description: 'The TLS cipher suite algorithm name. (Key for list: tls-cipher-suite-algorithms)' + type: str + required: true + key: algorithm-name + state_dump_config: + description: Configurable field about an active or recently completed state-dump collection operation. + type: dict + suboptions: + exclude_corefiles: + description: Indicates that exclude-corefiles is enabled or disabled. + type: str + required: false + choices: + - disabled + - enabled + time_config: + description: Waveserver system time configuration attributes. + type: dict + suboptions: + time_offset: + description: System time-offset from UTC in seconds. + type: int + required: false + time_stamp: + description: System time stamp format; local time or UTC time. + type: str + required: false + choices: + - utc + - local + xftp_config: + description: Waveserver system XFTP configuration attributes. + type: dict + suboptions: + ftp: + description: Waveserver system FTP configuration. + type: dict + suboptions: + host_name: + description: FTP host name. Format is an IP address (with optional port) or host name. + type: str + required: false + password: + description: FTP password string. + type: str + required: false + secret: + description: FTP secret string. + type: str + required: false + user_name: + description: FTP user name. + type: str + required: false + mode: + description: Identifies which file transfer protocol to user when default-server is specified in a command - FTP, SFTP, TFTP or SCP. + type: str + required: false + choices: + - none + - tftp + - ftp + - sftp + - scp + scp: + description: Waveserver system SCP configuration. + type: dict + suboptions: + host_name: + description: SCP host name. Format is an IP address (with optional port) or host name. + type: str + required: false + password: + description: SCP password string. + type: str + required: false + secret: + description: SCP secret string. + type: str + required: false + user_name: + description: SCP user name. + type: str + required: false + sftp: + description: Waveserver system SFTP configuration. + type: dict + suboptions: + host_name: + description: SFTP host name. Format is an IP address (with optional port) or host name. + type: str + required: false + password: + description: SFTP password string. + type: str + required: false + secret: + description: SFTP secret string. + type: str + required: false + user_name: + description: SFTP user name. + type: str + required: false + tftp: + description: Waveserver system TFTP configuration. + type: dict + suboptions: + config_host_name: + description: TFTP host name configured by user. Format is an IP address (with optional port) or host name. + type: str + required: false + state: + description: + - The state of the configuration + type: str + choices: + - merged + default: merged + +""" +EXAMPLES = """ +# Using merged + +- name: Configure system hostname + ciena.waveserver5.waveserver5_system: + config: + host_name: + config_host_name: foo + state: merged +""" + +RETURN = """ +before: + description: The configuration prior to the model invocation. + returned: always + type: dict + sample: > + The configuration returned will always be in the same format + of the parameters above. +after: + description: The resulting configuration model invocation. + returned: when changed + type: dict + sample: > + The configuration returned will always be in the same format + of the parameters above. +xml: + description: The set of xml commands pushed to the remote device. + returned: always + type: list + sample: ['foo'] +""" + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.ciena.waveserverai.plugins.module_utils.network.waveserverai.argspec.system.system import ( + SystemArgs, +) +from ansible_collections.ciena.waveserverai.plugins.module_utils.network.waveserverai.config.system.system import ( + System, +) + + +def main(): + """ + Main entry point for module execution + + :returns: the result form module invocation + """ + module = AnsibleModule(argument_spec=SystemArgs.argument_spec, supports_check_mode=True) + + result = System(module).execute_module() + module.exit_json(**result) + + +if __name__ == "__main__": + main() diff --git a/plugins/modules/waveserverai_xcvrs.py b/plugins/modules/waveserverai_xcvrs.py old mode 100644 new mode 100755 index bf3b709..cab8bb2 --- a/plugins/modules/waveserverai_xcvrs.py +++ b/plugins/modules/waveserverai_xcvrs.py @@ -1,6 +1,6 @@ #!/usr/bin/python # -*- coding: utf-8 -*- -# Copyright 2021 Ciena +# Copyright 2025 Ciena # GNU General Public License v3.0+ # (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) @@ -30,91 +30,383 @@ __metaclass__ = type + DOCUMENTATION = """ --- module: waveserverai_xcvrs -version_added: 2.9 -short_description: Manage XCVR on Ciena Waveserver Ai devices -description: This module provides declarative management of a transceiver +short_description: Waveserver transceivers (XCVR) configuration and operational data.Manage the xcvrs xcvrs configuration of a Ciena waveserverai + device +description: "Waveserver transceivers (XCVR) configuration and operational data.\n Waveserver transceiver (XCVR) list." author: Ciena options: config: - description: A dictionary of XVCR options + description: Waveserver transceiver (XCVR) list. type: list elements: dict suboptions: - xcvr-id: - description: - - Full name of xcvr, e.g. 1-1. - type: str - required: True properties: - description: - - A dictionary of properties to be configured on the xcvr. + description: All the Configurable and operational data of this XCVR instance. type: dict suboptions: mode: - description: - - Mode C(unit) should be of type string. + description: Mode of the XCVR. + type: str + required: true choices: - - 100GE - - OTL4.4 - - 56-100 - - 56-150 - - 56-200 - - 56-250 - - 56-300 - - 56-350 - - 56-400 - - 35-100 - - 35-150 - - 35-250 - - OCH - - OTM - - 4x10GE - - 35-200 - - OSC - - OTLC.4 - - OSC-ADD-DROP + - blank + - OCH + - OTM + - OSC + - OSC-Add-Drop + - 10GE + - 4x10GE + - 40GE + - 100GE + - 400GE + - 400GE-ZR + - 400GE-ZR+ + - 4x100GE + - 4x100GE-ZR + - 4x100GE-ZR+ + - OTL4.4 + - OTLC.4 + - FOIC1.4 + - FOIC4.8 + - 35-100 + - 35-150 + - 35-200 + - 35-250 + - 56-100 + - 56-150 + - 56-200 + - 56-250 + - 56-300 + - 56-350 + - 56-400 + - 70-300-O + - 70-400-O + - 70-400-E + - 65-300-E + - 65-400-E + - 63-200-O + - 63-400-O + - 60-400-E-ZR + - 60-400-E-ZR+ + - 60-200-E + - 58-200-O + - 35-200-O + - 31.5-100-O + - 31.5-200-O + - 95-200-O + - 95-250-O + - 95-300-O + - 95-350-O + - 95-400-O + - 95-450-O + - 95-500-O + - 95-550-O + - 95-600-O + - 95-650-O + - 95-700-O + - 95-750-O + - 95-800-O + - 95-200-E + - 95-250-E + - 95-300-E + - 95-350-E + - 95-400-E + - 95-450-E + - 95-500-E + - 95-550-E + - 95-600-E + - 95-650-E + - 95-700-E + - 95-750-E + - 95-800-E + - 91.6-200-O + - 91.6-250-O + - 91.6-300-O + - 91.6-350-O + - 91.6-400-O + - 91.6-450-O + - 91.6-500-O + - 91.6-550-O + - 91.6-600-O + - 91.6-650-O + - 91.6-700-O + - 91.6-750-O + - 91.6-800-O + - 91.6-200-E + - 91.6-250-E + - 91.6-300-E + - 91.6-350-E + - 91.6-400-E + - 91.6-450-E + - 91.6-500-E + - 91.6-550-E + - 91.6-600-E + - 91.6-650-E + - 91.6-700-E + - 91.6-750-E + - 91.6-800-E + - 89.3-200-O + - 89.3-250-O + - 89.3-300-O + - 89.3-350-O + - 89.3-400-O + - 89.3-450-O + - 89.3-500-O + - 89.3-550-O + - 89.3-600-O + - 89.3-650-O + - 89.3-700-O + - 89.3-750-O + - 89.3-800-O + - 89.3-200-E + - 89.3-250-E + - 89.3-300-E + - 89.3-350-E + - 89.3-400-E + - 89.3-450-E + - 89.3-500-E + - 89.3-550-E + - 89.3-600-E + - 89.3-650-E + - 89.3-700-E + - 89.3-750-E + - 89.3-800-E + - 71.3-200-O + - 71.3-250-O + - 71.3-300-O + - 71.3-350-O + - 71.3-400-O + - 71.3-450-O + - 71.3-500-O + - 71.3-550-O + - 71.3-600-O + - 71.3-200-E + - 71.3-250-E + - 71.3-300-E + - 71.3-350-E + - 71.3-400-E + - 71.3-450-E + - 71.3-500-E + - 71.3-550-E + - 71.3-600-E + - 69.5-200-O + - 69.5-250-O + - 69.5-300-O + - 69.5-350-O + - 69.5-400-O + - 69.5-450-O + - 69.5-500-O + - 69.5-550-O + - 69.5-600-O + - 69.5-200-E + - 69.5-250-E + - 69.5-300-E + - 69.5-350-E + - 69.5-400-E + - 69.5-450-E + - 69.5-500-E + - 69.5-550-E + - 69.5-600-E + - 93.3-200-O + - 93.3-250-O + - 93.3-300-O + - 93.3-350-O + - 93.3-400-O + - 93.3-450-O + - 93.3-500-O + - 93.3-550-O + - 93.3-600-O + - 93.3-650-O + - 93.3-700-O + - 93.3-750-O + - 93.3-800-O + - 93.3-200-E + - 93.3-250-E + - 93.3-300-E + - 93.3-350-E + - 93.3-400-E + - 93.3-450-E + - 93.3-500-E + - 93.3-550-E + - 93.3-600-E + - 93.3-650-E + - 93.3-700-E + - 93.3-750-E + - 93.3-800-E + - 90-200-O + - 90-250-O + - 90-300-O + - 90-350-O + - 90-400-O + - 90-450-O + - 90-500-O + - 90-550-O + - 90-600-O + - 90-650-O + - 90-700-O + - 90-750-O + - 90-800-O + - 90-200-E + - 90-250-E + - 90-300-E + - 90-350-E + - 90-400-E + - 90-450-E + - 90-500-E + - 90-550-E + - 90-600-E + - 90-650-E + - 90-700-E + - 90-750-E + - 90-800-E + - 85-200-O + - 85-250-O + - 85-300-O + - 85-350-O + - 85-400-O + - 85-450-O + - 85-500-O + - 85-550-O + - 85-600-O + - 85-650-O + - 85-700-O + - 85-750-O + - 85-800-O + - 85-200-E + - 85-250-E + - 85-300-E + - 85-350-E + - 85-400-E + - 85-450-E + - 85-500-E + - 85-550-E + - 85-600-E + - 85-650-E + - 85-700-E + - 85-750-E + - 85-800-E + - 82-200-O + - 82-250-O + - 82-300-O + - 82-350-O + - 82-400-O + - 82-450-O + - 82-500-O + - 82-550-O + - 82-600-O + - 82-650-O + - 82-700-O + - 82-750-O + - 82-800-O + - 82-200-E + - 82-250-E + - 82-300-E + - 82-350-E + - 82-400-E + - 82-450-E + - 82-500-E + - 82-550-E + - 82-600-E + - 82-650-E + - 82-700-E + - 82-750-E + - 82-800-E + - 107-200-O + - 107-200-E + - 107-250-O + - 107-250-E + - 107-300-O + - 107-300-E + - 107-350-O + - 107-350-E + - 107-400-O + - 107-400-E + - 107-450-O + - 107-450-E + - 107-500-O + - 107-500-E + - 107-550-O + - 107-550-E + - 107-600-O + - 107-600-E + - 107-650-O + - 107-650-E + - 107-700-O + - 107-700-E + - 107-750-O + - 107-750-E + - 107-800-O + - 107-800-E + state: + description: State information of this XCVR instance. + type: dict + suboptions: + admin_state: + description: Whether Admin State is enabled or disabled for this XCVR's PTP. type: str + required: false + choices: + - disabled + - enabled + xcvr_id: + description: 'Unique, access identifier string of the XCVR (e.g. ''1-1''). Key value for the XCVR List. (Key for list: xcvrs)' + type: str + required: true + key: xcvr-id state: + description: + - The state of the configuration + type: str choices: - merged - - overridden default: merged - description: - - The state the configuration should be left in - type: str + """ EXAMPLES = """ # Using merged -- name: Configure interfaces - ciena.waveserverai.waveserverai_xcvrs: +- name: Disable xcvr + ciena.waveserverai.xcvrs: config: - - name: 1-1 - properties: - mode: 56-400 - operation: merged - - + - xcvr_id: 5-1 + state: + admin_state: disabled + state: merged +- name: Enable xcvr + ciena.waveserverai.xcvrs: + config: + - xcvr_id: 5-1 + state: + admin_state: enabled + state: merged """ + RETURN = """ before: description: The configuration prior to the model invocation. returned: always + type: dict sample: > The configuration returned will always be in the same format of the parameters above. after: description: The resulting configuration model invocation. returned: when changed + type: dict sample: > The configuration returned will always be in the same format of the parameters above. +xml: + description: The set of xml commands pushed to the remote device. + returned: always + type: list + sample: ['foo'] """ - from ansible.module_utils.basic import AnsibleModule from ansible_collections.ciena.waveserverai.plugins.module_utils.network.waveserverai.argspec.xcvrs.xcvrs import ( XcvrsArgs, @@ -130,9 +422,7 @@ def main(): :returns: the result form module invocation """ - module = AnsibleModule( - argument_spec=XcvrsArgs.argument_spec, supports_check_mode=True - ) + module = AnsibleModule(argument_spec=XcvrsArgs.argument_spec, supports_check_mode=True) result = Xcvrs(module).execute_module() module.exit_json(**result) diff --git a/plugins/netconf/waveserverai.py b/plugins/netconf/waveserverai.py index 07587df..8ddb8f4 100644 --- a/plugins/netconf/waveserverai.py +++ b/plugins/netconf/waveserverai.py @@ -42,9 +42,7 @@ class Netconf(NetconfBase): def get_text(self, ele, tag): try: - return to_text( - ele.find(tag).text, errors="surrogate_then_replace" - ).strip() + return to_text(ele.find(tag).text, errors="surrogate_then_replace").strip() except AttributeError: pass @@ -64,9 +62,7 @@ def get_capabilities(self): result["server_capabilities"] = list(self.m.server_capabilities) result["client_capabilities"] = list(self.m.client_capabilities) result["session_id"] = self.m.session_id - result["device_operations"] = self.get_device_operations( - result["server_capabilities"] - ) + result["device_operations"] = self.get_device_operations(result["server_capabilities"]) return json.dumps(result) @ensure_ncclient diff --git a/tests/static/playbook.yml b/tests/static/playbook.yml index 51fabc0..b2c900b 100644 --- a/tests/static/playbook.yml +++ b/tests/static/playbook.yml @@ -6,26 +6,23 @@ gather_facts: false name: Gather facts for ciena device Waveserver Ai tasks: - # - name: get device facts for waveserverai device - # ciena.waveserverai.waveserverai_facts: - # gather_subset: - # - all - # gather_network_resources: - # - all - - name: Configure interfaces + - name: Get device facts for waveserverai device + ciena.waveserverai.waveserverai_facts: + gather_subset: + - min + gather_network_resources: + - all + + - name: Disable interfaces waveserverai_xcvrs: config: - - xcvr-id: 1-1 - properties: - mode: 56-400 + - xcvr_id: 1-1 + state: + admin_state: disabled - - name: Configure interfaces + - name: Enable interfaces waveserverai_xcvrs: config: - - xcvr-id: 2-2 - properties: - mode: 56-400 - - # register: mystdout - # - debug: - # var: mystdout.stdout_lines \ No newline at end of file + - xcvr_id: 1-1 + state: + admin_state: enabled