Skip to content

Commit a56b0db

Browse files
feat: Implement DeviceProvider for IOS-XR
1 parent 081498a commit a56b0db

3 files changed

Lines changed: 96 additions & 1 deletion

File tree

internal/provider/cisco/iosxr/intf.go

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,18 @@ const (
4242
StateShutDown PhysIfStateType = "im-state-shutdown"
4343
)
4444

45+
type Ifaces struct {
46+
PhysIfList []*Iface `json:"interface-configuration"`
47+
}
48+
49+
func (i *Ifaces) XPath() string {
50+
return "Cisco-IOS-XR-ifmgr-cfg:interface-configurations"
51+
}
52+
4553
// Iface represents physical and bundle interfaces as part of the same struct as they share a lot of common configuration
4654
// and only differ in a few attributes like the interface name and the presence of bundle configuration or not.
4755
type Iface struct {
48-
Name string `json:"-"`
56+
Name string `json:"interface-name"`
4957
Description string `json:"description,omitzero"`
5058
Statistics Statistics `json:"Cisco-IOS-XR-infra-statsd-cfg:statistics,omitzero"`
5159
MTUs MTUs `json:"mtus,omitzero"`
@@ -193,6 +201,21 @@ func ExtractInterfaceSpeedFromName(ifaceName string) (IFaceSpeed, error) {
193201
}
194202
}
195203

204+
func MapInterfaceSpeedToNumeric(speed IFaceSpeed) (int32, error) {
205+
switch speed {
206+
case Speed10G:
207+
return 10000, nil
208+
case Speed25G:
209+
return 25000, nil
210+
case Speed40G:
211+
return 40000, nil
212+
case Speed100G:
213+
return 100000, nil
214+
default:
215+
return 0, fmt.Errorf("unsupported interface speed %s", speed)
216+
}
217+
}
218+
196219
func CheckInterfaceNameTypeAggregate(name string) error {
197220
if name == "" {
198221
return errors.New("interface name must not be empty")

internal/provider/cisco/iosxr/provider.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121

2222
var (
2323
_ provider.Provider = &Provider{}
24+
_ provider.DeviceProvider = &Provider{}
2425
_ provider.InterfaceProvider = &Provider{}
2526
)
2627

@@ -49,6 +50,58 @@ func (p *Provider) Disconnect(ctx context.Context, conn *deviceutil.Connection)
4950
return p.conn.Close()
5051
}
5152

53+
func (p *Provider) ListPorts(ctx context.Context) ([]provider.DevicePort, error) {
54+
iFaces := new(Ifaces)
55+
err := p.client.GetConfig(ctx, iFaces)
56+
if err != nil {
57+
return nil, fmt.Errorf("failed to list ports: %w", err)
58+
}
59+
60+
dp := make([]provider.DevicePort, 0, len(iFaces.PhysIfList))
61+
for _, intf := range iFaces.PhysIfList {
62+
var speeds = []int32{}
63+
s, _ := ExtractInterfaceSpeedFromName(intf.Name)
64+
65+
if n, err := MapInterfaceSpeedToNumeric(s); err == nil {
66+
speeds = append(speeds, n)
67+
}
68+
// (fixme): name already contains the speed information, convert them to standardized string value (e.g. 10G, 25G, 40G, 100G)
69+
dp = append(dp, provider.DevicePort{
70+
ID: intf.Name,
71+
Type: intf.Name,
72+
SupportedSpeedsGbps: speeds,
73+
})
74+
}
75+
return dp, nil
76+
}
77+
78+
func (p *Provider) GetDeviceInfo(ctx context.Context) (*provider.DeviceInfo, error) {
79+
i := new(BasicDeviceInfo)
80+
81+
if err := p.client.GetState(ctx, i); err != nil {
82+
return nil, err
83+
}
84+
85+
return &provider.DeviceInfo{
86+
Manufacturer: Manufacturer,
87+
Model: i.Model,
88+
SerialNumber: i.SerialNumber,
89+
FirmwareVersion: i.FirmwareVersion,
90+
}, nil
91+
}
92+
93+
func (p *Provider) Reboot(ctx context.Context, conn *deviceutil.Connection) error {
94+
return errors.New("IOS XR Provider does not support rebooting the device")
95+
}
96+
97+
func (p *Provider) FactoryReset(ctx context.Context, conn *deviceutil.Connection) error {
98+
return errors.New("IOS XR Provider does not support factory reset")
99+
}
100+
101+
func (p *Provider) Reprovision(cxt context.Context, conn *deviceutil.Connection) error {
102+
return errors.New("IOS XR Provider does not support reprovisioning")
103+
}
104+
52105
func (p *Provider) EnsureInterface(ctx context.Context, req *provider.EnsureInterfaceRequest) error {
53106
if p.client == nil {
54107
return errors.New("client is not connected")
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// SPDX-FileCopyrightText: 2025 SAP SE or an SAP affiliate company and IronCore contributors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package iosxr
5+
6+
const Manufacturer = "Cisco"
7+
8+
// Model is the chassis model of the device, e.g. "NCS-57C3-MOD-SYS".
9+
// SerialNumber is the serial number of the device, e.g. "9VT9OHZBC3H".
10+
// FirmwareVersion is the firmware version of the device, e.g. "25.2.2".
11+
type BasicDeviceInfo struct {
12+
Model string `json:"model-name"`
13+
SerialNumber string `json:"serial-number"`
14+
FirmwareVersion string `json:"firmware-version"`
15+
}
16+
17+
func (*BasicDeviceInfo) XPath() string {
18+
return "Cisco-IOS-XR-platform-inventory-oper:/platform-inventory/racks/rack[name=0]/attributes/basic-info"
19+
}

0 commit comments

Comments
 (0)