lib-tl1-huawei 0.1.8 → 0.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +30 -0
- data/.ruby-version +1 -1
- data/Gemfile +1 -2
- data/README.md +189 -22
- data/Rakefile +8 -3
- data/lib/lib/tl1/huawei/message/exception.rb +7 -6
- data/lib/lib/tl1/huawei/message/input.rb +6 -3
- data/lib/lib/tl1/huawei/message/login.rb +5 -3
- data/lib/lib/tl1/huawei/message/logout.rb +2 -1
- data/lib/lib/tl1/huawei/message/lst_bms_version.rb +1 -1
- data/lib/lib/tl1/huawei/message/lst_board.rb +4 -10
- data/lib/lib/tl1/huawei/message/lst_dev.rb +7 -12
- data/lib/lib/tl1/huawei/message/lst_emf_sys_info.rb +5 -2
- data/lib/lib/tl1/huawei/message/lst_frame.rb +4 -7
- data/lib/lib/tl1/huawei/message/lst_gem_connection.rb +7 -10
- data/lib/lib/tl1/huawei/message/lst_gem_port.rb +4 -8
- data/lib/lib/tl1/huawei/message/lst_gpon_auto_find.rb +6 -8
- data/lib/lib/tl1/huawei/message/lst_gpon_ddm_info.rb +4 -5
- data/lib/lib/tl1/huawei/message/lst_gpon_line_profile.rb +1 -0
- data/lib/lib/tl1/huawei/message/lst_gpon_nni_perf.rb +4 -5
- data/lib/lib/tl1/huawei/message/lst_gpon_nni_port.rb +1 -1
- data/lib/lib/tl1/huawei/message/lst_gpon_ont_eth_port_detail.rb +5 -9
- data/lib/lib/tl1/huawei/message/lst_gpon_ont_eth_port_perf.rb +5 -8
- data/lib/lib/tl1/huawei/message/lst_gpon_ont_port_mac.rb +6 -10
- data/lib/lib/tl1/huawei/message/lst_gpon_port.rb +4 -5
- data/lib/lib/tl1/huawei/message/lst_gpon_port_detail.rb +4 -6
- data/lib/lib/tl1/huawei/message/lst_gpon_port_perf.rb +4 -5
- data/lib/lib/tl1/huawei/message/lst_gpon_sfp.rb +4 -6
- data/lib/lib/tl1/huawei/message/lst_gpon_srv_profile.rb +1 -0
- data/lib/lib/tl1/huawei/message/lst_ont.rb +6 -15
- data/lib/lib/tl1/huawei/message/lst_ont_dba_prof.rb +5 -9
- data/lib/lib/tl1/huawei/message/lst_ont_ddm_detail.rb +4 -7
- data/lib/lib/tl1/huawei/message/lst_ont_detail.rb +6 -10
- data/lib/lib/tl1/huawei/message/lst_ont_eth_port_perf.rb +6 -12
- data/lib/lib/tl1/huawei/message/lst_ont_eth_vlan_switch_pair.rb +8 -10
- data/lib/lib/tl1/huawei/message/lst_ont_ip_config.rb +5 -8
- data/lib/lib/tl1/huawei/message/lst_ont_ip_info.rb +5 -10
- data/lib/lib/tl1/huawei/message/lst_ont_port.rb +6 -13
- data/lib/lib/tl1/huawei/message/lst_ont_port_detail.rb +6 -13
- data/lib/lib/tl1/huawei/message/lst_ont_pots_state.rb +5 -10
- data/lib/lib/tl1/huawei/message/lst_ont_queue_shaping.rb +6 -11
- data/lib/lib/tl1/huawei/message/lst_ont_run_info.rb +5 -10
- data/lib/lib/tl1/huawei/message/lst_ont_vag_voip.rb +5 -10
- data/lib/lib/tl1/huawei/message/lst_ont_voip_pstn_user.rb +7 -18
- data/lib/lib/tl1/huawei/message/lst_ont_wan.rb +5 -10
- data/lib/lib/tl1/huawei/message/lst_onu_nni_ddm_detail.rb +4 -5
- data/lib/lib/tl1/huawei/message/lst_port.rb +5 -15
- data/lib/lib/tl1/huawei/message/output.rb +43 -137
- data/lib/lib/tl1/huawei/message/response.rb +10 -4
- data/lib/lib/tl1/huawei/message/response_body.rb +107 -0
- data/lib/lib/tl1/huawei/message/shake_hand.rb +2 -1
- data/lib/lib/tl1/huawei/message.rb +1 -0
- data/lib/lib/tl1/huawei/version.rb +1 -1
- data/sig/lib/tl1/huawei/message/exception.rbs +10 -0
- data/sig/lib/tl1/huawei/message/input.rbs +41 -0
- data/sig/lib/tl1/huawei/message/login.rbs +13 -0
- data/sig/lib/tl1/huawei/message/logout.rbs +11 -0
- data/sig/lib/tl1/huawei/message/lst_bms_version.rbs +10 -0
- data/sig/lib/tl1/huawei/message/lst_board.rbs +26 -0
- data/sig/lib/tl1/huawei/message/lst_dev.rbs +29 -0
- data/sig/lib/tl1/huawei/message/lst_emf_sys_info.rbs +11 -0
- data/sig/lib/tl1/huawei/message/lst_frame.rbs +15 -0
- data/sig/lib/tl1/huawei/message/lst_gem_connection.rbs +33 -0
- data/sig/lib/tl1/huawei/message/lst_gem_port.rbs +31 -0
- data/sig/lib/tl1/huawei/message/lst_gpon_auto_find.rbs +27 -0
- data/sig/lib/tl1/huawei/message/lst_gpon_ddm_info.rbs +25 -0
- data/sig/lib/tl1/huawei/message/lst_gpon_line_profile.rbs +14 -0
- data/sig/lib/tl1/huawei/message/lst_gpon_nni_perf.rbs +25 -0
- data/sig/lib/tl1/huawei/message/lst_gpon_nni_port.rbs +14 -0
- data/sig/lib/tl1/huawei/message/lst_gpon_ont_eth_port_detail.rbs +31 -0
- data/sig/lib/tl1/huawei/message/lst_gpon_ont_eth_port_perf.rbs +29 -0
- data/sig/lib/tl1/huawei/message/lst_gpon_ont_port_mac.rbs +33 -0
- data/sig/lib/tl1/huawei/message/lst_gpon_port.rbs +25 -0
- data/sig/lib/tl1/huawei/message/lst_gpon_port_detail.rbs +27 -0
- data/sig/lib/tl1/huawei/message/lst_gpon_port_perf.rbs +25 -0
- data/sig/lib/tl1/huawei/message/lst_gpon_sfp.rbs +27 -0
- data/sig/lib/tl1/huawei/message/lst_gpon_srv_profile.rbs +14 -0
- data/sig/lib/tl1/huawei/message/lst_ont.rbs +38 -0
- data/sig/lib/tl1/huawei/message/lst_ont_dba_prof.rbs +31 -0
- data/sig/lib/tl1/huawei/message/lst_ont_ddm_detail.rbs +29 -0
- data/sig/lib/tl1/huawei/message/lst_ont_detail.rbs +30 -0
- data/sig/lib/tl1/huawei/message/lst_ont_eth_port_perf.rbs +35 -0
- data/sig/lib/tl1/huawei/message/lst_ont_eth_vlan_switch_pair.rbs +31 -0
- data/sig/lib/tl1/huawei/message/lst_ont_ip_config.rbs +29 -0
- data/sig/lib/tl1/huawei/message/lst_ont_ip_info.rbs +31 -0
- data/sig/lib/tl1/huawei/message/lst_ont_port.rbs +37 -0
- data/sig/lib/tl1/huawei/message/lst_ont_port_detail.rbs +37 -0
- data/sig/lib/tl1/huawei/message/lst_ont_pots_state.rbs +31 -0
- data/sig/lib/tl1/huawei/message/lst_ont_queue_shaping.rbs +33 -0
- data/sig/lib/tl1/huawei/message/lst_ont_run_info.rbs +32 -0
- data/sig/lib/tl1/huawei/message/lst_ont_vag_voip.rbs +33 -0
- data/sig/lib/tl1/huawei/message/lst_ont_voip_pstn_user.rbs +35 -0
- data/sig/lib/tl1/huawei/message/lst_ont_wan.rbs +33 -0
- data/sig/lib/tl1/huawei/message/lst_onu_nni_ddm_detail.rbs +25 -0
- data/sig/lib/tl1/huawei/message/lst_port.rbs +34 -0
- data/sig/lib/tl1/huawei/message/output.rbs +95 -0
- data/sig/lib/tl1/huawei/message/response.rbs +20 -0
- data/sig/lib/tl1/huawei/message/response_body.rbs +22 -0
- data/sig/lib/tl1/huawei/message/shake_hand.rbs +11 -0
- data/sig/lib/tl1/huawei/message.rbs +9 -0
- data/sig/lib/tl1/huawei/version.rbs +7 -0
- data/sig/lib/tl1/huawei.rbs +16 -2
- metadata +75 -11
- data/.idea/.gitignore +0 -8
- data/.idea/misc.xml +0 -4
- data/.idea/remote-mappings.xml +0 -16
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fa419db9b636262d5c1508225bfc2964dba1048640badd89617cfaf1d391cf83
|
|
4
|
+
data.tar.gz: 59b962716fe07cdbac297b0445270735dbe4e4a26d18fe2fb707338b97cc53da
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8db89037f1ef25ad794a573dfac262d6141869102d2ac419029ae1016328d059f502df49ea478bb0cce56e5683f80b69aa0b1878e259deea3da6f9b23e78c504
|
|
7
|
+
data.tar.gz: '09972d8cb1b8b53aaf874e25e32d69aef2c63ff30d211e0de715e16f04692eddf8b969038cb156fc18389ccdfefc4c24ffa89af51587f09343244ef4ed49fff6'
|
data/.rubocop.yml
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
AllCops:
|
|
2
|
+
TargetRubyVersion: 3.4
|
|
3
|
+
NewCops: enable
|
|
4
|
+
SuggestExtensions: false
|
|
5
|
+
Exclude:
|
|
6
|
+
- 'tmp/**/*'
|
|
7
|
+
- 'vendor/**/*'
|
|
8
|
+
|
|
9
|
+
# Named TL1 fields are part of the public command API; positional arguments keep
|
|
10
|
+
# the default limit.
|
|
11
|
+
Metrics/ParameterLists:
|
|
12
|
+
CountKeywordArgs: false
|
|
13
|
+
|
|
14
|
+
# Protocol field maps and expected response data are declarative collections.
|
|
15
|
+
Metrics/MethodLength:
|
|
16
|
+
CountAsOne: ['array', 'hash', 'heredoc']
|
|
17
|
+
|
|
18
|
+
# Example groups collect independent tests; individual examples remain checked.
|
|
19
|
+
Metrics/BlockLength:
|
|
20
|
+
AllowedMethods: ['describe']
|
|
21
|
+
|
|
22
|
+
# GB (general block) and CC (completion code) are public lib-tl1 keywords.
|
|
23
|
+
Naming/MethodParameterName:
|
|
24
|
+
AllowedNames: ['cc', 'gb']
|
|
25
|
+
|
|
26
|
+
# Response is a public OpenStruct subclass with dynamic, mutable TL1 columns.
|
|
27
|
+
# Replacing it with a fixed Struct or Hash would change the record API.
|
|
28
|
+
Style/OpenStructUse:
|
|
29
|
+
Exclude:
|
|
30
|
+
- 'lib/lib/tl1/huawei/message/response.rb'
|
data/.ruby-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
3.4
|
data/Gemfile
CHANGED
data/README.md
CHANGED
|
@@ -1,47 +1,214 @@
|
|
|
1
|
-
# Lib::
|
|
1
|
+
# Lib::TL1::Huawei
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A Ruby library for building commands and parsing TL1 NBI responses from Huawei iManager U2000.
|
|
4
|
+
It extends `lib-tl1`, using its fields and TL1 frame parser to read Huawei metadata
|
|
5
|
+
and tables. It provides a subset of queries for devices, GPON/ONT, GEM, profiles,
|
|
6
|
+
optical parameters, statistics, IP/WAN, VLAN and VoIP, as well as session commands.
|
|
4
7
|
|
|
5
|
-
|
|
8
|
+
The library does not establish TCP/TLS connections, send commands, maintain sessions
|
|
9
|
+
or assemble multipart responses. These are the responsibility of the application using the gem.
|
|
6
10
|
|
|
7
11
|
## Installation
|
|
8
12
|
|
|
9
|
-
|
|
13
|
+
Ruby `>= 3.4.0` is required. Older Ruby versions are no longer supported.
|
|
14
|
+
Add the following to your application's `Gemfile`:
|
|
10
15
|
|
|
11
|
-
```
|
|
16
|
+
```gemfile
|
|
12
17
|
gem 'lib-tl1-huawei'
|
|
13
18
|
```
|
|
14
19
|
|
|
15
|
-
|
|
20
|
+
Then run `bundle install`. The gem depends on `lib-tl1 ~> 0.1.2`
|
|
21
|
+
and `ostruct >= 0.1.0, < 1.0`; Bundler installs them automatically.
|
|
22
|
+
The entry point is `require 'lib/tl1/huawei'`, and the namespace is `Lib::TL1::Huawei`.
|
|
16
23
|
|
|
17
|
-
|
|
24
|
+
## Building a command
|
|
18
25
|
|
|
19
|
-
|
|
26
|
+
This example builds an `LST-ONTDETAIL` command to query details for ONT 3 on
|
|
27
|
+
port 2, slot 8, frame 0 of device 1. `CTAG` is a request identifier that lets the
|
|
28
|
+
application match a response to its command. Set it with `message.ctag` before
|
|
29
|
+
calling `to_s` to produce the TL1 command string.
|
|
20
30
|
|
|
21
|
-
|
|
31
|
+
```ruby
|
|
32
|
+
require 'lib/tl1/huawei'
|
|
33
|
+
|
|
34
|
+
message = Lib::TL1::Huawei::Message::LstOntDetail.new(
|
|
35
|
+
did: 1, frame_number: 0, slot_number: 8, port_number: 2, ont_id: 3
|
|
36
|
+
)
|
|
37
|
+
message.ctag = 101
|
|
38
|
+
puts message.to_s
|
|
39
|
+
# LST-ONTDETAIL::DID=1,FN=0,SN=8,PN=2,ONTID=3:101::;
|
|
40
|
+
```
|
|
22
41
|
|
|
23
|
-
|
|
42
|
+
`DID` is the device identifier in U2000. `DEV` means the device name by default,
|
|
43
|
+
but the `DevMean`/`DEVMEAN` setting can change its meaning to the IP address.
|
|
44
|
+
Choose `did:` or `dev:` according to the NBI configuration and the command's requirements.
|
|
45
|
+
The library does not read this configuration or validate the address against a device.
|
|
46
|
+
|
|
47
|
+
| Ruby argument | TL1 field | Meaning |
|
|
48
|
+
| --- | --- | --- |
|
|
49
|
+
| `frame_number:` | `FN` | OLT frame/shelf number |
|
|
50
|
+
| `slot_number:` | `SN` | Slot number |
|
|
51
|
+
| `port_number:` | `PN` | Port number |
|
|
52
|
+
| `ont_id:` | `ONTID` | ONT identifier on the port |
|
|
53
|
+
| `ont_name:` | `NAME` | ONT name, together with `DID` or `DEV` |
|
|
54
|
+
| `ont_alias:` | `ALIAS` | Alternative ONT addressing by alias |
|
|
55
|
+
|
|
56
|
+
For `LstOntDetail`, choose the ONT coordinates, a name with a device, or an alias alone;
|
|
57
|
+
do not combine all addressing variants. Available arguments depend on the constructor.
|
|
58
|
+
For example, `LstOnt` uses `onu_name:` for `NAME` and supports `ont_sn:` (`ONTSN`)
|
|
59
|
+
and `ont_pwd:` (`PWD`); `LstOntDbaProf` also maps `ont_pwd:` to `PWD`.
|
|
60
|
+
`LstGponAutoFind` sends `LST-GPONONTAUTOFIND` and accepts a serial number or an OLT location.
|
|
61
|
+
`LstGponNniPort` is a separate query for NNI ports with optional `SHOWOPTION`.
|
|
62
|
+
For example, `LstGponNniPort` supports `show_option: [:PSTAT]`;
|
|
63
|
+
the allowed `SHOWOPTION` fields differ between commands.
|
|
64
|
+
|
|
65
|
+
## Reading responses and errors
|
|
66
|
+
|
|
67
|
+
Run the following examples from the repository directory, for example with `bundle exec ruby`.
|
|
68
|
+
The files in `spec/fixtures/huawei` are synthetic: they contain no subscriber data and
|
|
69
|
+
are not device session recordings. Fixtures and tests are not packaged in the installed gem.
|
|
24
70
|
|
|
25
|
-
|
|
71
|
+
```ruby
|
|
72
|
+
require 'lib/tl1/huawei'
|
|
73
|
+
|
|
74
|
+
raw = File.binread('spec/fixtures/huawei/one_record.tl1')
|
|
75
|
+
output = Lib::TL1::Huawei::Message::Output.parse(raw, encoding: 'UTF-8')
|
|
76
|
+
puts output.ont_id # 1
|
|
77
|
+
puts output.first.name # Office west
|
|
78
|
+
puts output.first.rx_power # --
|
|
79
|
+
puts output.to_h[:blktotal] # 1
|
|
80
|
+
```
|
|
26
81
|
|
|
27
|
-
|
|
82
|
+
`Output.parse` accepts one complete response. `response` is an array of
|
|
83
|
+
`Response` records based on `OpenStruct`; `first`, `each`, `map`, `[]` and `size` provide
|
|
84
|
+
collection operations. Column names are converted to lowercase, and records also support
|
|
85
|
+
snake_case names: `ontid` and `ont_id` read the same field.
|
|
86
|
+
Record getters are delegated directly from `Output` only when
|
|
87
|
+
`blktotal == 1` and `response.size == 1`. Use the collection for empty results or results
|
|
88
|
+
with multiple records; `respond_to?` follows the same delegation rule.
|
|
28
89
|
|
|
29
|
-
|
|
90
|
+
`blktag` is the packet number, `blkcount` is the number of records in that packet, and
|
|
91
|
+
`blktotal` is the total number of records, not packets. `to_h` returns the header,
|
|
92
|
+
`en`, `endesc`, counters, title and an array of hashes in `:response`. Field values remain
|
|
93
|
+
strings without unit conversion; `--` remains `--`, and an empty table cell remains an empty string.
|
|
30
94
|
|
|
31
|
-
|
|
95
|
+
```ruby
|
|
96
|
+
require 'lib/tl1/huawei'
|
|
97
|
+
|
|
98
|
+
begin
|
|
99
|
+
raw = File.binread('spec/fixtures/huawei/error.tl1')
|
|
100
|
+
Lib::TL1::Huawei::Message::Output.parse(raw, encoding: 'UTF-8')
|
|
101
|
+
rescue Lib::TL1::Huawei::StandardError => error
|
|
102
|
+
puts "#{error.error_number}: #{error.message}"
|
|
103
|
+
# 123: Example device error.
|
|
104
|
+
end
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
A nonzero `EN` identifies a Huawei error; `ENDESC` supplies its description.
|
|
108
|
+
Do not compare the description with a literal success message. Frame syntax errors can also
|
|
109
|
+
come from the `lib-tl1` parser and may raise exceptions other than `Lib::TL1::Huawei::StandardError`.
|
|
32
110
|
|
|
33
|
-
##
|
|
111
|
+
## Encoding and API compatibility
|
|
34
112
|
|
|
35
|
-
|
|
113
|
+
The default `encoding: nil` preserves the bytes and encoding of the input `String`.
|
|
114
|
+
For `File.binread`, this means `ASCII-8BIT`, without guessing the server's encoding.
|
|
115
|
+
An explicit `encoding: 'UTF-8'`, `'GBK'` or `'ISO-8859-1'` interprets a copy of the input
|
|
116
|
+
bytes in the specified encoding and decodes it to UTF-8. Match it to the U2000 `CharSet`
|
|
117
|
+
configuration. Invalid data raises an exception; the parser does not replace characters.
|
|
118
|
+
Repeated reads and `to_h` do not change the source data or the encoding of record values.
|
|
119
|
+
`to_h` no longer forces conversion from ISO-8859-1.
|
|
36
120
|
|
|
37
|
-
|
|
121
|
+
`reverse` returns a reversed copy of the collection without changing its order.
|
|
122
|
+
The broken delegator with the misspelled name `revers` has been removed; replace calls to it
|
|
123
|
+
with `reverse`. `LstDev#dev_type` reflects the constructor argument, and `show_option`
|
|
124
|
+
and the retained alias `showoption` return the same list of options.
|
|
38
125
|
|
|
39
|
-
|
|
126
|
+
`LstOntEthVlanSwitchPair` sends `LST-ONTETHVLANSWTICHPAIR`, with the intentional
|
|
127
|
+
spelling `SWTICHPAIR`. It replaces the previously sent
|
|
128
|
+
`LST-ONTETHVLANSWITCHPAIR`. The `ont_port_type:` argument is serialized in uppercase
|
|
129
|
+
(the default `:eth` produces `ETH`); `nil` omits the field, and the getter preserves the supplied argument.
|
|
40
130
|
|
|
41
|
-
|
|
131
|
+
Tests use synthetic fixtures and do not establish compatibility with a live U2000 system.
|
|
132
|
+
The library implements a subset of U2000 commands and addressing variants; the class list is in
|
|
133
|
+
the [message loader](lib/lib/tl1/huawei/message.rb), and the maintained signatures are in
|
|
134
|
+
the [RBS signatures](sig/lib/tl1/), whose file layout mirrors `lib/lib/tl1/`.
|
|
42
135
|
|
|
43
|
-
|
|
136
|
+
## Development
|
|
137
|
+
|
|
138
|
+
Select a supported Ruby environment with RVM; `.ruby-version` specifies `3.4`,
|
|
139
|
+
and `.ruby-gemset` specifies `lib-tl1-huawei`. Use this gemset name when selecting another
|
|
140
|
+
supported Ruby version as well, for example `rvm use 4.0.2@lib-tl1-huawei --create`.
|
|
141
|
+
Install dependencies, including the `development` group, in the selected gemset and
|
|
142
|
+
run the local checks:
|
|
44
143
|
|
|
45
|
-
|
|
46
|
-
|
|
144
|
+
```sh
|
|
145
|
+
bundle check
|
|
146
|
+
bundle install
|
|
147
|
+
bundle exec rake
|
|
148
|
+
```
|
|
47
149
|
|
|
150
|
+
`bundle install` is only needed when `bundle check` reports missing dependencies.
|
|
151
|
+
The default Rake task runs RuboCop followed by RSpec. Use `bundle exec rake rubocop`
|
|
152
|
+
for lint only or `bundle exec rake spec` for tests only.
|
|
153
|
+
RuboCop settings live in `.rubocop.yml`, without an offense baseline.
|
|
154
|
+
The configuration preserves named TL1 parameters and the `gb`/`cc` protocol keywords,
|
|
155
|
+
counts multiline data literals as one expression for method length, and excludes
|
|
156
|
+
declarative RSpec `describe` groups from block length checks. Individual examples
|
|
157
|
+
and helpers retain the default limits. `Response` alone is exempt from
|
|
158
|
+
`Style/OpenStructUse` to preserve its public dynamic, mutable record API; all
|
|
159
|
+
other checks still apply to it. Fix new offenses in code instead of generating
|
|
160
|
+
exclusions; any rule adjustment needs an explicit design or compatibility reason.
|
|
161
|
+
The tests do not connect to U2000; they also execute the Ruby examples in this README.
|
|
162
|
+
CI runs RuboCop on Ruby 3.4 and tests on Ruby 3.4 and 4.0 for pull requests,
|
|
163
|
+
pushes to `master` and `v*` tags. Both checks must pass before release tag preparation.
|
|
164
|
+
|
|
165
|
+
## Publishing
|
|
166
|
+
|
|
167
|
+
When a push to `master` changes `Lib::TL1::Huawei::VERSION` in
|
|
168
|
+
`lib/lib/tl1/huawei/version.rb`, the workflow runs the tests and creates a matching
|
|
169
|
+
`v<VERSION>` tag (for example, `v0.1.9`). It compares the versions before and after
|
|
170
|
+
the entire push, including pushes containing multiple commits. Unchanged versions,
|
|
171
|
+
initial branch creation and existing tags do not trigger an automatic release.
|
|
172
|
+
Existing tags are never moved.
|
|
173
|
+
|
|
174
|
+
Only a newly created tag enables the build and publication using
|
|
175
|
+
[RubyGems Trusted Publishing](https://guides.rubygems.org/trusted-publishing/).
|
|
176
|
+
Tags created by the workflow use `GITHUB_TOKEN`, which
|
|
177
|
+
[does not trigger another push workflow](https://docs.github.com/en/actions/how-tos/write-workflows/choose-when-workflows-run/trigger-a-workflow#triggering-a-workflow-from-a-workflow).
|
|
178
|
+
The dependent publishing job therefore runs in the same workflow after tag creation,
|
|
179
|
+
without a personal access token. A new `v*` tag pushed manually also runs the tests
|
|
180
|
+
and publishes, provided its name matches the version at the tagged commit.
|
|
181
|
+
Deleting or updating an existing tag does not publish a gem.
|
|
182
|
+
|
|
183
|
+
The workflow exchanges a GitHub Actions OIDC token for short-lived RubyGems credentials
|
|
184
|
+
through the official
|
|
185
|
+
[`configure-rubygems-credentials` action](https://github.com/rubygems/configure-rubygems-credentials).
|
|
186
|
+
Only the publishing job has `id-token: write`; it uses the `release` environment.
|
|
187
|
+
The tag preparation job has `contents: write`; repository rules must allow
|
|
188
|
+
`GITHUB_TOKEN` to create `v*` tags.
|
|
189
|
+
|
|
190
|
+
Before the first publication through this workflow, create the GitHub environment `release`
|
|
191
|
+
and register a trusted publisher for `lib-tl1-huawei` on RubyGems.org with these values:
|
|
192
|
+
|
|
193
|
+
| Setting | Value |
|
|
194
|
+
| --- | --- |
|
|
195
|
+
| Repository owner | `pwojcieszonek` |
|
|
196
|
+
| Repository name | `lib-tl1-huawei` |
|
|
197
|
+
| Workflow filename | `main.yml` |
|
|
198
|
+
| Environment | `release` |
|
|
199
|
+
|
|
200
|
+
The workflow filename is the basename of `.github/workflows/main.yml`.
|
|
201
|
+
The RubyGems and GitHub environment names must match. No `RUBYGEMS_AUTH_TOKEN` secret
|
|
202
|
+
is required by this workflow.
|
|
203
|
+
If the `release` environment restricts deployment branches or tags, allow both
|
|
204
|
+
`master` (automatic tags) and `v*` tags (manual tag pushes). Required environment
|
|
205
|
+
reviewers, if configured, still need to approve publication.
|
|
206
|
+
|
|
207
|
+
Set a new, unpublished version in `lib/lib/tl1/huawei/version.rb` before pushing a release
|
|
208
|
+
to `master`; RubyGems rejects attempts to publish an existing version again.
|
|
209
|
+
If publication fails after automatic tag creation, use GitHub Actions' **Re-run failed jobs**
|
|
210
|
+
to retry publication with the existing tag output. Re-running all jobs finds the
|
|
211
|
+
existing tag and skips the automatic release.
|
|
212
|
+
Local tests and `gem build lib-tl1-huawei.gemspec` do not publish the gem.
|
|
213
|
+
|
|
214
|
+
This project is available under the [MIT license](LICENSE.txt).
|
data/Rakefile
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
3
|
+
require 'bundler/gem_tasks'
|
|
4
|
+
require 'rspec/core/rake_task'
|
|
5
5
|
|
|
6
6
|
RSpec::Core::RakeTask.new(:spec)
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
desc 'Run RuboCop'
|
|
9
|
+
task :rubocop do
|
|
10
|
+
ruby '-S', 'rubocop'
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
task default: %i[rubocop spec]
|
|
@@ -1,15 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Lib
|
|
2
4
|
module TL1
|
|
3
5
|
module Huawei
|
|
4
|
-
|
|
5
|
-
|
|
6
|
+
# Reports the Huawei EN error number alongside its ENDESC description.
|
|
7
|
+
class StandardError < ::StandardError
|
|
6
8
|
attr_reader :error_number
|
|
7
9
|
|
|
8
|
-
def initialize(
|
|
9
|
-
super(
|
|
10
|
-
@error_number =
|
|
10
|
+
def initialize(message = nil, error_number = nil)
|
|
11
|
+
super(message)
|
|
12
|
+
@error_number = error_number
|
|
11
13
|
end
|
|
12
|
-
|
|
13
14
|
end
|
|
14
15
|
end
|
|
15
16
|
end
|
|
@@ -6,8 +6,8 @@ module Lib
|
|
|
6
6
|
module TL1
|
|
7
7
|
module Huawei
|
|
8
8
|
module Message
|
|
9
|
+
# Serializes Huawei command parameters on top of the TL1 frame builder.
|
|
9
10
|
class Input < Lib::TL1::Message::Input
|
|
10
|
-
|
|
11
11
|
def initialize(command: nil, tid: nil, aid: nil, ctag: nil, gb: nil, payload: nil)
|
|
12
12
|
command = self.class.name.split('::').last.sub(/(.)([A-Z])/, '\1-\2').upcase if command.nil?
|
|
13
13
|
super
|
|
@@ -15,14 +15,17 @@ module Lib
|
|
|
15
15
|
|
|
16
16
|
private
|
|
17
17
|
|
|
18
|
+
def set_attributes(**attributes)
|
|
19
|
+
attributes.each { |name, value| instance_variable_set("@#{name}", value) }
|
|
20
|
+
end
|
|
21
|
+
|
|
18
22
|
def __show_option(*show_option)
|
|
19
23
|
show_option.empty? ? nil : show_option.map { |option| option.to_s.delete('_') }.join(' ')
|
|
20
24
|
end
|
|
21
25
|
|
|
22
26
|
def hash_to_string(**hash)
|
|
23
|
-
hash.
|
|
27
|
+
hash.compact.map { |key, value| "#{key.to_s.delete('_').upcase}=#{value}" }.join(',')
|
|
24
28
|
end
|
|
25
|
-
|
|
26
29
|
end
|
|
27
30
|
end
|
|
28
31
|
end
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'input'
|
|
2
4
|
|
|
3
5
|
module Lib
|
|
4
6
|
module TL1
|
|
5
7
|
module Huawei
|
|
6
8
|
module Message
|
|
9
|
+
# Builds a LOGIN command from the NBI username and password.
|
|
7
10
|
class Login < Lib::TL1::Huawei::Message::Input
|
|
8
11
|
attr_reader :password, :username
|
|
9
12
|
|
|
@@ -12,9 +15,8 @@ module Lib
|
|
|
12
15
|
@password = password
|
|
13
16
|
super(payload: "UN=#{username},PWD=#{password}")
|
|
14
17
|
end
|
|
15
|
-
|
|
16
18
|
end
|
|
17
19
|
end
|
|
18
20
|
end
|
|
19
21
|
end
|
|
20
|
-
end
|
|
22
|
+
end
|
|
@@ -6,8 +6,8 @@ module Lib
|
|
|
6
6
|
module TL1
|
|
7
7
|
module Huawei
|
|
8
8
|
module Message
|
|
9
|
+
# Queries boards by device, frame, slot, and board type.
|
|
9
10
|
class LstBoard < Lib::TL1::Huawei::Message::Input
|
|
10
|
-
|
|
11
11
|
attr_reader :dev, :did, :onu_locate_info, :frame_number, :slot_number, :board_type, :show_option
|
|
12
12
|
|
|
13
13
|
def initialize(
|
|
@@ -19,13 +19,9 @@ module Lib
|
|
|
19
19
|
board_type: nil,
|
|
20
20
|
show_option: nil
|
|
21
21
|
)
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
@onu_locate_info = onu_locate_info
|
|
26
|
-
@slot_number = slot_number
|
|
27
|
-
@board_type = board_type
|
|
28
|
-
@show_option = show_option
|
|
22
|
+
set_attributes(
|
|
23
|
+
dev:, did:, frame_number:, onu_locate_info:, slot_number:, board_type:, show_option:
|
|
24
|
+
)
|
|
29
25
|
|
|
30
26
|
super(
|
|
31
27
|
aid: hash_to_string(
|
|
@@ -39,10 +35,8 @@ module Lib
|
|
|
39
35
|
payload: __show_option(*show_option)
|
|
40
36
|
)
|
|
41
37
|
end
|
|
42
|
-
|
|
43
38
|
end
|
|
44
39
|
end
|
|
45
40
|
end
|
|
46
41
|
end
|
|
47
42
|
end
|
|
48
|
-
|
|
@@ -6,9 +6,11 @@ module Lib
|
|
|
6
6
|
module TL1
|
|
7
7
|
module Huawei
|
|
8
8
|
module Message
|
|
9
|
+
# Queries devices and optionally selects returned device attributes.
|
|
9
10
|
class LstDev < Lib::TL1::Huawei::Message::Input
|
|
11
|
+
attr_reader :did, :dev, :dev_ip, :dev_type, :dev_ver, :onu_locate_info, :show_option, :user_id
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
alias showoption show_option
|
|
12
14
|
|
|
13
15
|
def initialize(
|
|
14
16
|
did: nil,
|
|
@@ -20,15 +22,9 @@ module Lib
|
|
|
20
22
|
show_option: [],
|
|
21
23
|
user_id: nil
|
|
22
24
|
)
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
@dev_ip = dev_ip
|
|
27
|
-
@dt = dev_type
|
|
28
|
-
@dev_ver = dev_ver
|
|
29
|
-
@onu_locate_info = onu_locate_info
|
|
30
|
-
@show_option = show_option
|
|
31
|
-
@user_id = user_id
|
|
25
|
+
set_attributes(
|
|
26
|
+
did:, dev:, dev_ip:, dev_type:, dev_ver:, onu_locate_info:, show_option:, user_id:
|
|
27
|
+
)
|
|
32
28
|
|
|
33
29
|
super(
|
|
34
30
|
aid: hash_to_string(
|
|
@@ -44,10 +40,9 @@ module Lib
|
|
|
44
40
|
user_id: user_id
|
|
45
41
|
)
|
|
46
42
|
)
|
|
47
|
-
|
|
48
43
|
end
|
|
49
44
|
end
|
|
50
45
|
end
|
|
51
46
|
end
|
|
52
47
|
end
|
|
53
|
-
end
|
|
48
|
+
end
|
|
@@ -1,12 +1,15 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'input'
|
|
2
4
|
|
|
3
5
|
module Lib
|
|
4
6
|
module TL1
|
|
5
7
|
module Huawei
|
|
6
8
|
module Message
|
|
9
|
+
# Queries management system information.
|
|
7
10
|
class LstEmfSysInfo < Lib::TL1::Huawei::Message::Input
|
|
8
11
|
def initialize
|
|
9
|
-
super
|
|
12
|
+
super(command: 'LST-EMFSYSINFO')
|
|
10
13
|
end
|
|
11
14
|
end
|
|
12
15
|
end
|
|
@@ -6,24 +6,21 @@ module Lib
|
|
|
6
6
|
module TL1
|
|
7
7
|
module Huawei
|
|
8
8
|
module Message
|
|
9
|
+
# Queries frames belonging to a device.
|
|
9
10
|
class LstFrame < Lib::TL1::Huawei::Message::Input
|
|
10
|
-
|
|
11
11
|
attr_reader :dev, :did, :frame_number, :show_option
|
|
12
12
|
|
|
13
13
|
def initialize(dev: nil, did: nil, frame_number: nil, show_option: nil)
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
@show_option = show_option
|
|
14
|
+
set_attributes(
|
|
15
|
+
dev:, did:, frame_number:, show_option:
|
|
16
|
+
)
|
|
18
17
|
super(
|
|
19
18
|
aid: hash_to_string(dev: dev, did: did, fn: frame_number),
|
|
20
19
|
payload: __show_option(*show_option)
|
|
21
20
|
)
|
|
22
21
|
end
|
|
23
|
-
|
|
24
22
|
end
|
|
25
23
|
end
|
|
26
24
|
end
|
|
27
25
|
end
|
|
28
26
|
end
|
|
29
|
-
|
|
@@ -5,22 +5,19 @@ module Lib
|
|
|
5
5
|
module TL1
|
|
6
6
|
module Huawei
|
|
7
7
|
module Message
|
|
8
|
+
# Queries GEM connections by ONT, GEM port, and VLAN.
|
|
8
9
|
class LstGemConnection < Lib::TL1::Huawei::Message::Input
|
|
9
|
-
attr_reader :did, :dev, :frame_number, :slot_number, :port_number, :ont_id, :gem_port_id, :vlan_id,
|
|
10
|
+
attr_reader :did, :dev, :frame_number, :slot_number, :port_number, :ont_id, :gem_port_id, :vlan_id,
|
|
11
|
+
:show_option
|
|
10
12
|
|
|
11
13
|
def initialize(
|
|
12
14
|
did: nil, dev: nil, frame_number: nil, slot_number: nil, port_number: nil,
|
|
13
15
|
ont_id: nil, gem_port_id: nil, vlan_id: nil, show_option: []
|
|
14
16
|
)
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
@port_number = port_number
|
|
20
|
-
@ont_id = ont_id
|
|
21
|
-
@gem_port_id = gem_port_id
|
|
22
|
-
@vlan_id = vlan_id
|
|
23
|
-
@show_option = show_option
|
|
17
|
+
set_attributes(
|
|
18
|
+
did:, dev:, frame_number:, slot_number:, port_number:, ont_id:, gem_port_id:, vlan_id:,
|
|
19
|
+
show_option:
|
|
20
|
+
)
|
|
24
21
|
super(
|
|
25
22
|
aid: hash_to_string(
|
|
26
23
|
did: did, dev: dev, fn: frame_number, sn: slot_number, pn: port_number,
|
|
@@ -5,6 +5,7 @@ module Lib
|
|
|
5
5
|
module TL1
|
|
6
6
|
module Huawei
|
|
7
7
|
module Message
|
|
8
|
+
# Queries GEM ports belonging to an ONT.
|
|
8
9
|
class LstGemPort < Lib::TL1::Huawei::Message::Input
|
|
9
10
|
attr_reader :did, :dev, :frame_number, :slot_number, :port_number, :ont_id, :gem_port_id, :show_option
|
|
10
11
|
|
|
@@ -12,14 +13,9 @@ module Lib
|
|
|
12
13
|
did: nil, dev: nil, frame_number: nil, slot_number: nil, port_number: nil,
|
|
13
14
|
ont_id: nil, gem_port_id: nil, show_option: []
|
|
14
15
|
)
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
@slot_number = slot_number
|
|
19
|
-
@port_number = port_number
|
|
20
|
-
@ont_id = ont_id
|
|
21
|
-
@gem_port_id = gem_port_id
|
|
22
|
-
@show_option = show_option
|
|
16
|
+
set_attributes(
|
|
17
|
+
did:, dev:, frame_number:, slot_number:, port_number:, ont_id:, gem_port_id:, show_option:
|
|
18
|
+
)
|
|
23
19
|
super(
|
|
24
20
|
aid: hash_to_string(
|
|
25
21
|
did: did, dev: dev, fn: frame_number, sn: slot_number,
|
|
@@ -6,18 +6,16 @@ module Lib
|
|
|
6
6
|
module TL1
|
|
7
7
|
module Huawei
|
|
8
8
|
module Message
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
# Queries automatically discovered ONTs by serial number or GPON port.
|
|
10
|
+
class LstGponAutoFind < Lib::TL1::Huawei::Message::Input
|
|
11
11
|
attr_reader :did, :dev, :frame_number, :slot_number, :port_number, :ont_sn
|
|
12
12
|
|
|
13
13
|
def initialize(did: nil, dev: nil, frame_number: nil, slot_number: nil, port_number: nil, ont_sn: nil)
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
@slot_number = slot_number
|
|
18
|
-
@port_number = port_number
|
|
19
|
-
@ont_sn = ont_sn
|
|
14
|
+
set_attributes(
|
|
15
|
+
did:, dev:, frame_number:, slot_number:, port_number:, ont_sn:
|
|
16
|
+
)
|
|
20
17
|
super(
|
|
18
|
+
command: 'LST-GPONONTAUTOFIND',
|
|
21
19
|
aid: hash_to_string(
|
|
22
20
|
did: did, dev: dev, fn: frame_number, sn: slot_number, pn: port_number, ont_sn: ont_sn
|
|
23
21
|
)
|
|
@@ -6,15 +6,14 @@ module Lib
|
|
|
6
6
|
module TL1
|
|
7
7
|
module Huawei
|
|
8
8
|
module Message
|
|
9
|
+
# Queries digital diagnostic monitoring values for a GPON port.
|
|
9
10
|
class LstGponDdmInfo < Lib::TL1::Huawei::Message::Input
|
|
10
11
|
attr_reader :did, :dev, :frame_number, :slot_number, :port_number
|
|
11
12
|
|
|
12
13
|
def initialize(did: nil, dev: nil, frame_number: nil, slot_number: nil, port_number: nil)
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
@slot_number = slot_number
|
|
17
|
-
@port_number = port_number
|
|
14
|
+
set_attributes(
|
|
15
|
+
did:, dev:, frame_number:, slot_number:, port_number:
|
|
16
|
+
)
|
|
18
17
|
super(
|
|
19
18
|
aid: hash_to_string(
|
|
20
19
|
did: did, dev: dev, fn: frame_number, sn: slot_number, pn: port_number
|