Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
4eb1bed
Add infra switch service and basic switch types for api v2
iljarotar Jun 18, 2025
9582cea
add tests for mac validation
iljarotar Jun 18, 2025
0b29c3a
make session uptime a duration
iljarotar Jun 18, 2025
c41adc6
rename partition id to partition
iljarotar Jun 18, 2025
95a90bc
Merge branch 'main' of https://github.com/metal-stack/api into mep17
majst01 Jul 10, 2025
6e770f6
Merge main
majst01 Jul 10, 2025
765b83f
Merge branch 'main' of https://github.com/metal-stack/api into mep17
majst01 Jul 16, 2025
1f6362c
Merge branch 'main' of https://github.com/metal-stack/api into mep17
majst01 Jul 17, 2025
eab1235
Merge branch 'main' of https://github.com/metal-stack/api into mep17
majst01 Aug 1, 2025
c6afc98
Merge main
majst01 Aug 1, 2025
67cf68e
Merge branch 'main' of github.com:metal-stack/api into mep17
iljarotar Aug 8, 2025
692c52a
merge main
iljarotar Aug 8, 2025
efe63fc
merge
iljarotar Aug 8, 2025
2737b8c
Merge branch 'main' of github.com:metal-stack/api into mep17
iljarotar Aug 14, 2025
d7dd3fb
merge main
iljarotar Dec 18, 2025
5434684
fix tests
iljarotar Dec 18, 2025
be33a1c
revert switch description change
iljarotar Dec 18, 2025
8d883f1
add bgp routes to heartbeat
iljarotar Jan 13, 2026
cbd4433
add lldp neighbors to heartbeat
iljarotar Jan 13, 2026
86ade9b
Merge branch 'main' of github.com:metal-stack/api into mep17
iljarotar Jan 13, 2026
7b28e1b
typo
iljarotar Jan 13, 2026
0726852
only one type of mgmt switch
iljarotar Jan 13, 2026
80c16ad
Merge main
majst01 Mar 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
198 changes: 198 additions & 0 deletions proto/metalstack/api/v2/switch.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
syntax = "proto3";

package metalstack.api.v2;

import "buf/validate/validate.proto";

// Switch represents a network switch
message Switch {
// ID of the switch
string id = 1 [(buf.validate.field).string = {
hostname: true
min_len: 2
max_len: 128
}];
// Description of the switch
string description = 2 [(buf.validate.field).string = {
min_len: 2
max_len: 128
}];
// Rack ID if the switch resides in a rack
optional string rack_id = 3 [(buf.validate.field).string = {
min_len: 2
max_len: 128
}];
// Partition ID of the partition the switch belongs to
string partition_id = 4 [(buf.validate.field).string = {
Comment thread
iljarotar marked this conversation as resolved.
Outdated
min_len: 2
max_len: 128
}];
// Type signifies what role a switch has, e.g. whether it is a leaf switch, or a spine, etc.
SwitchType type = 5 [(buf.validate.field).enum.defined_only = true];
// Replace mode is used to mark a switch ready for replacement
SwitchReplaceMode replace_mode = 6 [(buf.validate.field).enum.defined_only = true];
// Management IP is the switch's IP for management access
string management_ip = 7 [(buf.validate.field).string.ip = true];
// Management user is the user name to use for management access
string management_user = 8 [(buf.validate.field).string = {
min_len: 2
max_len: 128
}];
// Console command is the command for accessing the switch's console
string console_command = 9 [(buf.validate.field).string = {
min_len: 2
max_len: 128
}];
// Switch NICs are the front panel ports of the switch
repeated SwitchNic switch_nics = 10;
}

// SwitchOS holds information about the NOS and versions running on the switch
message SwitchOS {
// Switch OS vendor identifies what NOS distribution is running on the switch, e.g. SONiC
SwitchOSVendor vendor = 1 [(buf.validate.field).enum.defined_only = true];
// Version specifies what NOS version is currently installed on the switch
string version = 2 [(buf.validate.field).string = {
min_len: 2
max_len: 128
}];
// Metal core version is the currently running version of the metal-core
string metal_core_version = 3 [(buf.validate.field).string = {
min_len: 2
max_len: 128
}];
}

// SwitchNic represents a front panel port and its configuration
message SwitchNic {
// Name of the switch port
string name = 1 [(buf.validate.field).string = {
min_len: 2
max_len: 128
}];
// Identifier of the port
string identifier = 2 [(buf.validate.field).string = {
min_len: 2
max_len: 128
}];
// MAC address of the port
string mac_address = 3 [(validate.rules).string.pattern = "^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$"];
Comment thread
iljarotar marked this conversation as resolved.
Outdated
// VRF name if the port is bound in one
optional string vrf = 4 [(buf.validate.field).string = {
min_len: 2
max_len: 128
}];
// Actual port status
SwitchPortStatus actual = 5 [(buf.validate.field).enum.defined_only = true];
// BGP filter optionally configured on a port
optional BGPFilter bgp_filter = 6;
// BGP port state represents the current BGP status of the port
optional SwitchBGPPortState bgp_port_state = 7;
}

// BGP filter can be used to restrict BGP based on CIDRs and VNIs
message BGPFilter {
// CIDRs for which to allow BGP
repeated string cidrs = 1;
option (buf.validate.message).cel = {
id: "cidrs"
message: "given cidrs must be valid"
expression: "this.cidrs.all(m, m.isIpPrefix())"
};
// VNIs for which to allow BGP
repeated string vnis = 2 [(buf.validate.field).string = {
min_len: 2
max_len: 128
}];
}

// SwitchBGPPortState holds information about the BGP state of a port
message SwitchBGPPortState {
// Neighbor of this port
string neighbor = 1 [(buf.validate.field).string = {
min_len: 2
max_len: 128
}];
// Peer group of this port
string peer_group = 2 [(buf.validate.field).string = {
min_len: 2
max_len: 128
}];
// VRF name of the VRF this port is bound to
string vrf_name = 3 [(buf.validate.field).string = {
min_len: 2
max_len: 128
}];
// BGP state of the connection on this port
BGPState bgp_state = 4 [(buf.validate.field).enum.defined_only = true];
// BGP timer up established reports the uptime of this port's BGP connection
uint64 bgp_timer_up_established = 5;
Comment thread
iljarotar marked this conversation as resolved.
Outdated
// Sent prefix counter counts the prefixes sent by the switch on this port
uint64 sent_prefix_counter = 6;
// Accepted prefix counter counts the prefixes received on this port
uint64 accepted_prefix_counter = 7;
}

// BGPState represents the state of a BGP session
enum BGPState {
// BGP_STATE_UNSPECIFIED is not specified
BGP_STATE_UNSPECIFIED = 0;
// BGP_STATE_IDLE is the Idle state of a BGP session
BGP_STATE_IDLE = 1 [(enum_string_value) = "idle"];
// BGP_STATE_CONNECT is the Connect state of a BGP session
BGP_STATE_CONNECT = 2 [(enum_string_value) = "connect"];
// BGP_STATE_ACTIVE is the Active state of a BGP session
BGP_STATE_ACTIVE = 3 [(enum_string_value) = "active"];
// BGP_STATE_OPEN_SENT is the OpenSent state of a BGP session
BGP_STATE_OPEN_SENT = 4 [(enum_string_value) = "open-sent"];
// BGP_STATE_OPEN_CONFIRM is the OpenConfirm state of a BGP session
BGP_STATE_OPEN_CONFIRM = 5 [(enum_string_value) = "open-confirm"];
// BGP_STATE_ESTABLISHED is the Established state of a BGP session
BGP_STATE_ESTABLISHED = 6 [(enum_string_value) = "established"];
}

// SwitchReplaceMode is used to mark a switch ready for replacement
enum SwitchReplaceMode {
// SWITCH_REPLACE_MODE_UNSPECIFIED is not specified
SWITCH_REPLACE_MODE_UNSPECIFIED = 0;
// SWITCH_REPLACE_MODE_REPLACE means this switch is waiting to be replaced
SWITCH_REPLACE_MODE_REPLACE = 1 [(enum_string_value) = "replace"];
// SWITCH_REPLACE_MODE_OPERATIONAL means this switch is operational and cannot be replaced
SWITCH_REPLACE_MODE_OPERATIONAL = 2 [(enum_string_value) = "operational"];
}

// SwitchOSVendor represents a NOS distribution
enum SwitchOSVendor {
// SWITCH_OS_VENDOR_UNSPECIFIED is not specified
SWITCH_OS_VENDOR_UNSPECIFIED = 0;
// SWITCH_OS_VENDOR_CUMULUS means this switch is running on Cumulus Linux
SWITCH_OS_VENDOR_CUMULUS = 1 [(enum_string_value) = "cumulus"];
// SWITCH_OS_VENDOR_SONIC means this switch is running on SONiC NOS
SWITCH_OS_VENDOR_SONIC = 2 [(enum_string_value) = "sonic"];
}

// SwitchPortStatus specifies the state of a switch port
enum SwitchPortStatus {
// SWITCH_PORT_STATUS_UNSPECIFIED is not specified
SWITCH_PORT_STATUS_UNSPECIFED = 0;
// SWITCH_PORT_STATUS_UP means this port is up
SWITCH_PORT_STATUS_UP = 1 [(enum_string_value) = "up"];
// SWITCH_PORT_STATUS_DOWN means this port is down
SWITCH_PORT_STATUS_DOWN = 2 [(enum_string_value) = "down"];
}

// SwitchType represents the role of a switch
enum SwitchType {
// SWITCH_TYPE_UNSPECIFIED is not specified
SWITCH_TYPE_UNSPECIFIED = 0;
// SWITCH_TYPE_LEAF is a leaf switch
SWITCH_TYPE_LEAF = 1 [(enum_string_value) = "leaf"];
// SWITCH_TYPE_EXIT is an exit switch
SWITCH_TYPE_EXIT = 2 [(enum_string_value) = "exit"];
// SWITCH_TYPE_SPINE is a spine switch
SWITCH_TYPE_SPINE = 3 [(enum_string_value) = "spine"];
// SWITCH_TYPE_MGMTLEAF is a special type of leaf used only for management tasks
SWITCH_TYPE_MGMTLEAF = 4 [(enum_string_value) = "mgmtleaf"];
// SWITCH_TYPE_MGMTSPINE is a special type of spine used only for management tasks
SWITCH_TYPE_MGMTSPINE = 5 [(enum_string_value) = "mgmtspine"];
}
59 changes: 59 additions & 0 deletions proto/metalstack/infra/v2/switch.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
syntax = "proto3";

package metalstack.infra.v2;

import "metalstack/api/v2/common.proto";

// SwitchService serves switch related functions
service SwitchService {
// Register a switch
rpc Register(SwitchServiceRegisterRequest) returns (SwitchServiceRegisterResponse) {
option (metalstack.api.v2.infra_roles) = INFRA_ROLE_EDITOR;
option (metalstack.api.v2.infra_roles) = INFRA_ROLE_VIEWER;
option (metalstack.api.v2.auditing) = AUDITING_EXCLUDED;
}
// Report BGP routes of a switch
rpc ReportBGPRoutes(SwitchServiceReportBGPRoutesRequest) returns (SwitchServiceReportBGPRoutesResponse) {
option (metalstack.api.v2.infra_roles) = INFRA_ROLE_EDITOR;
option (metalstack.api.v2.infra_roles) = INFRA_ROLE_VIEWER;
option (metalstack.api.v2.auditing) = AUDITING_EXCLUDED;
}
}

// SwitchServiceRegisterRequest
message SwitchServiceRegisterRequest {
// Switch to register
metalstack.api.v2.Switch switch = 1;
}

// SwitchServiceRegisterResponse
message SwitchServiceRegisterResponse {
// Switch that was registered
metalstack.api.v2.Switch switch = 1;
}

// SwitchServiceReportBGPRoutesRequest
message SwitchServiceReportBGPRoutesRequest {
// Switch ID of the switch that reports its routes
string switch_id = 1 [(buf.validate.field).string = {
hostname: true
min_len: 2
max_len: 128
}];
// BGP routes collected on the switch
repeated BGPRoute bgpRoutes = 2;
}

// SwitchServiceReportBGPRoutesResponse
message SwitchServiceReportBGPRoutesResponse {}

// BGPRoute represents the route to a prefix
message BGPRoute {
// CIDR of the network that is routed to
string cidr = 1;
option (buf.validate.message).cel = {
id: "cidr"
message: "cidr must be a valid ip prefix"
expression: "this.cidr.isIpPrefix()"
};
}