diff --git a/doc/index.html b/doc/index.html
index d5b61b91..aa5d8a4b 100644
--- a/doc/index.html
+++ b/doc/index.html
@@ -1413,6 +1413,10 @@
Table of Contents
ESwitchReplaceMode
+
+ ESwitchType
+
+
@@ -1984,6 +1988,10 @@ Table of Contents
metalstack/infra/v2/switch.proto
+ -
+ MBGPRoute
+
+
-
MSwitchServiceGetRequest
@@ -2016,6 +2024,14 @@ Table of Contents
MSwitchServiceRegisterResponse
+ -
+ MSwitchServiceReportBGPRoutesRequest
+
+
+ -
+ MSwitchServiceReportBGPRoutesResponse
+
+
-
MSwitchSync
@@ -11562,6 +11578,13 @@
MachineConnections map machines to the nics they are connected to. |
+
+ | type |
+ SwitchType |
+ |
+ Type is the role of the switch. |
+
+
@@ -11963,6 +11986,53 @@
+
+ SwitchType represents the role of a switch
+
+
+ | Name | Number | Description |
+
+
+
+
+ | SWITCH_TYPE_UNSPECIFIED |
+ 0 |
+ SWITCH_TYPE_UNSPECIFIED is not specified |
+
+
+
+ | SWITCH_TYPE_LEAF |
+ 1 |
+ SWITCH_TYPE_LEAF is a leaf switch |
+
+
+
+ | SWITCH_TYPE_EXIT |
+ 2 |
+ SWITCH_TYPE_EXIT is an exit switch |
+
+
+
+ | SWITCH_TYPE_SPINE |
+ 3 |
+ SWITCH_TYPE_SPINE is a spine switch |
+
+
+
+ | SWITCH_TYPE_MGMTLEAF |
+ 4 |
+ SWITCH_TYPE_MGMTLEAF is a special type of leaf used only for management tasks |
+
+
+
+ | SWITCH_TYPE_MGMTSPINE |
+ 5 |
+ SWITCH_TYPE_MGMTSPINE is a special type of spine used only for management tasks |
+
+
+
+
+
@@ -15605,6 +15675,30 @@ <
+
+ BGPRoute represents the route to a prefix.
+
+
+
+
+ | Field | Type | Label | Description |
+
+
+
+
+ | cidr |
+ string |
+ |
+ CIDR of the network that is routed to. |
+
+
+
+
+
+
+
+
+
SwitchServiceGetRequest.
@@ -15853,6 +15947,44 @@ SwitchServiceReportBGPRoutesRequest.
+
+
+
+
+ | Field | Type | Label | Description |
+
+
+
+
+ | switch_id |
+ string |
+ |
+ Switch ID of the switch that reports its routes. |
+
+
+
+ | bgp_routes |
+ BGPRoute |
+ repeated |
+ BGP routes collected on the switch. |
+
+
+
+
+
+
+
+
+
+ SwitchServiceReportBGPRoutesResponse
+ SwitchServiceReportBGPRoutesResponse.
+
+
+
+
+
SwitchSync
SwitchSync summarizes information about a switch sync.
@@ -15926,6 +16058,13 @@ SwitchService
Heartbeat a switch. |
+
+ | ReportBGPRoutes |
+ SwitchServiceReportBGPRoutesRequest |
+ SwitchServiceReportBGPRoutesResponse |
+ ReportBGPRoutes of a switch |
+
+
diff --git a/go/metalstack/api/v2/switch.pb.go b/go/metalstack/api/v2/switch.pb.go
index fab16a35..1a5cd8e4 100644
--- a/go/metalstack/api/v2/switch.pb.go
+++ b/go/metalstack/api/v2/switch.pb.go
@@ -255,6 +255,71 @@ func (SwitchPortStatus) EnumDescriptor() ([]byte, []int) {
return file_metalstack_api_v2_switch_proto_rawDescGZIP(), []int{3}
}
+// SwitchType represents the role of a switch
+type SwitchType int32
+
+const (
+ // SWITCH_TYPE_UNSPECIFIED is not specified
+ SwitchType_SWITCH_TYPE_UNSPECIFIED SwitchType = 0
+ // SWITCH_TYPE_LEAF is a leaf switch
+ SwitchType_SWITCH_TYPE_LEAF SwitchType = 1
+ // SWITCH_TYPE_EXIT is an exit switch
+ SwitchType_SWITCH_TYPE_EXIT SwitchType = 2
+ // SWITCH_TYPE_SPINE is a spine switch
+ SwitchType_SWITCH_TYPE_SPINE SwitchType = 3
+ // SWITCH_TYPE_MGMTLEAF is a special type of leaf used only for management tasks
+ SwitchType_SWITCH_TYPE_MGMTLEAF SwitchType = 4
+ // SWITCH_TYPE_MGMTSPINE is a special type of spine used only for management tasks
+ SwitchType_SWITCH_TYPE_MGMTSPINE SwitchType = 5
+)
+
+// Enum value maps for SwitchType.
+var (
+ SwitchType_name = map[int32]string{
+ 0: "SWITCH_TYPE_UNSPECIFIED",
+ 1: "SWITCH_TYPE_LEAF",
+ 2: "SWITCH_TYPE_EXIT",
+ 3: "SWITCH_TYPE_SPINE",
+ 4: "SWITCH_TYPE_MGMTLEAF",
+ 5: "SWITCH_TYPE_MGMTSPINE",
+ }
+ SwitchType_value = map[string]int32{
+ "SWITCH_TYPE_UNSPECIFIED": 0,
+ "SWITCH_TYPE_LEAF": 1,
+ "SWITCH_TYPE_EXIT": 2,
+ "SWITCH_TYPE_SPINE": 3,
+ "SWITCH_TYPE_MGMTLEAF": 4,
+ "SWITCH_TYPE_MGMTSPINE": 5,
+ }
+)
+
+func (x SwitchType) Enum() *SwitchType {
+ p := new(SwitchType)
+ *p = x
+ return p
+}
+
+func (x SwitchType) String() string {
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (SwitchType) Descriptor() protoreflect.EnumDescriptor {
+ return file_metalstack_api_v2_switch_proto_enumTypes[4].Descriptor()
+}
+
+func (SwitchType) Type() protoreflect.EnumType {
+ return &file_metalstack_api_v2_switch_proto_enumTypes[4]
+}
+
+func (x SwitchType) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use SwitchType.Descriptor instead.
+func (SwitchType) EnumDescriptor() ([]byte, []int) {
+ return file_metalstack_api_v2_switch_proto_rawDescGZIP(), []int{4}
+}
+
// Switch represents a network switch.
type Switch struct {
state protoimpl.MessageState `protogen:"open.v1"`
@@ -282,8 +347,10 @@ type Switch struct {
Os *SwitchOS `protobuf:"bytes,11,opt,name=os,proto3" json:"os,omitempty"`
// MachineConnections map machines to the nics they are connected to.
MachineConnections []*MachineConnection `protobuf:"bytes,12,rep,name=machine_connections,json=machineConnections,proto3" json:"machine_connections,omitempty"`
- unknownFields protoimpl.UnknownFields
- sizeCache protoimpl.SizeCache
+ // Type is the role of the switch.
+ Type SwitchType `protobuf:"varint,13,opt,name=type,proto3,enum=metalstack.api.v2.SwitchType" json:"type,omitempty"`
+ unknownFields protoimpl.UnknownFields
+ sizeCache protoimpl.SizeCache
}
func (x *Switch) Reset() {
@@ -400,6 +467,13 @@ func (x *Switch) GetMachineConnections() []*MachineConnection {
return nil
}
+func (x *Switch) GetType() SwitchType {
+ if x != nil {
+ return x.Type
+ }
+ return SwitchType_SWITCH_TYPE_UNSPECIFIED
+}
+
// SwitchOS holds information about the NOS and versions running on the switch.
type SwitchOS struct {
state protoimpl.MessageState `protogen:"open.v1"`
@@ -961,7 +1035,7 @@ var File_metalstack_api_v2_switch_proto protoreflect.FileDescriptor
const file_metalstack_api_v2_switch_proto_rawDesc = "" +
"\n" +
- "\x1emetalstack/api/v2/switch.proto\x12\x11metalstack.api.v2\x1a\x1bbuf/validate/validate.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1emetalstack/api/v2/common.proto\x1a(metalstack/api/v2/predefined_rules.proto\"\xb0\x05\n" +
+ "\x1emetalstack/api/v2/switch.proto\x12\x11metalstack.api.v2\x1a\x1bbuf/validate/validate.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1emetalstack/api/v2/common.proto\x1a(metalstack/api/v2/predefined_rules.proto\"\xed\x05\n" +
"\x06Switch\x12\x1d\n" +
"\x02id\x18\x01 \x01(\tB\r\xbaH\n" +
"r\b\xc0\xb3\xae\xb1\x02\x01h\x01R\x02id\x12+\n" +
@@ -978,7 +1052,8 @@ const file_metalstack_api_v2_switch_proto_rawDesc = "" +
"\x04nics\x18\n" +
" \x03(\v2\x1c.metalstack.api.v2.SwitchNicR\x04nics\x12+\n" +
"\x02os\x18\v \x01(\v2\x1b.metalstack.api.v2.SwitchOSR\x02os\x12U\n" +
- "\x13machine_connections\x18\f \x03(\v2$.metalstack.api.v2.MachineConnectionR\x12machineConnectionsB\a\n" +
+ "\x13machine_connections\x18\f \x03(\v2$.metalstack.api.v2.MachineConnectionR\x12machineConnections\x12;\n" +
+ "\x04type\x18\r \x01(\x0e2\x1d.metalstack.api.v2.SwitchTypeB\b\xbaH\x05\x82\x01\x02\x10\x01R\x04typeB\a\n" +
"\x05_rackB\x12\n" +
"\x10_management_userB\x12\n" +
"\x10_console_command\"\xb1\x01\n" +
@@ -1060,7 +1135,15 @@ const file_metalstack_api_v2_switch_proto_rawDesc = "" +
"\x1eSWITCH_PORT_STATUS_UNSPECIFIED\x10\x00\x12!\n" +
"\x15SWITCH_PORT_STATUS_UP\x10\x01\x1a\x06\x82\xb2\x19\x02up\x12%\n" +
"\x17SWITCH_PORT_STATUS_DOWN\x10\x02\x1a\b\x82\xb2\x19\x04down\x12+\n" +
- "\x1aSWITCH_PORT_STATUS_UNKNOWN\x10\x03\x1a\v\x82\xb2\x19\aunknownB\xc1\x01\n" +
+ "\x1aSWITCH_PORT_STATUS_UNKNOWN\x10\x03\x1a\v\x82\xb2\x19\aunknown*\xdd\x01\n" +
+ "\n" +
+ "SwitchType\x12\x1b\n" +
+ "\x17SWITCH_TYPE_UNSPECIFIED\x10\x00\x12\x1e\n" +
+ "\x10SWITCH_TYPE_LEAF\x10\x01\x1a\b\x82\xb2\x19\x04leaf\x12\x1e\n" +
+ "\x10SWITCH_TYPE_EXIT\x10\x02\x1a\b\x82\xb2\x19\x04exit\x12 \n" +
+ "\x11SWITCH_TYPE_SPINE\x10\x03\x1a\t\x82\xb2\x19\x05spine\x12&\n" +
+ "\x14SWITCH_TYPE_MGMTLEAF\x10\x04\x1a\f\x82\xb2\x19\bmgmtleaf\x12(\n" +
+ "\x15SWITCH_TYPE_MGMTSPINE\x10\x05\x1a\r\x82\xb2\x19\tmgmtspineB\xc1\x01\n" +
"\x15com.metalstack.api.v2B\vSwitchProtoP\x01Z5github.com/metal-stack/api/go/metalstack/api/v2;apiv2\xa2\x02\x03MAX\xaa\x02\x11Metalstack.Api.V2\xca\x02\x11Metalstack\\Api\\V2\xe2\x02\x1dMetalstack\\Api\\V2\\GPBMetadata\xea\x02\x13Metalstack::Api::V2b\x06proto3"
var (
@@ -1075,47 +1158,49 @@ func file_metalstack_api_v2_switch_proto_rawDescGZIP() []byte {
return file_metalstack_api_v2_switch_proto_rawDescData
}
-var file_metalstack_api_v2_switch_proto_enumTypes = make([]protoimpl.EnumInfo, 4)
+var file_metalstack_api_v2_switch_proto_enumTypes = make([]protoimpl.EnumInfo, 5)
var file_metalstack_api_v2_switch_proto_msgTypes = make([]protoimpl.MessageInfo, 9)
var file_metalstack_api_v2_switch_proto_goTypes = []any{
(BGPState)(0), // 0: metalstack.api.v2.BGPState
(SwitchReplaceMode)(0), // 1: metalstack.api.v2.SwitchReplaceMode
(SwitchOSVendor)(0), // 2: metalstack.api.v2.SwitchOSVendor
(SwitchPortStatus)(0), // 3: metalstack.api.v2.SwitchPortStatus
- (*Switch)(nil), // 4: metalstack.api.v2.Switch
- (*SwitchOS)(nil), // 5: metalstack.api.v2.SwitchOS
- (*SwitchNic)(nil), // 6: metalstack.api.v2.SwitchNic
- (*BGPFilter)(nil), // 7: metalstack.api.v2.BGPFilter
- (*SwitchBGPPortState)(nil), // 8: metalstack.api.v2.SwitchBGPPortState
- (*NicState)(nil), // 9: metalstack.api.v2.NicState
- (*MachineConnection)(nil), // 10: metalstack.api.v2.MachineConnection
- (*SwitchQuery)(nil), // 11: metalstack.api.v2.SwitchQuery
- (*SwitchOSQuery)(nil), // 12: metalstack.api.v2.SwitchOSQuery
- (*Meta)(nil), // 13: metalstack.api.v2.Meta
- (*timestamppb.Timestamp)(nil), // 14: google.protobuf.Timestamp
+ (SwitchType)(0), // 4: metalstack.api.v2.SwitchType
+ (*Switch)(nil), // 5: metalstack.api.v2.Switch
+ (*SwitchOS)(nil), // 6: metalstack.api.v2.SwitchOS
+ (*SwitchNic)(nil), // 7: metalstack.api.v2.SwitchNic
+ (*BGPFilter)(nil), // 8: metalstack.api.v2.BGPFilter
+ (*SwitchBGPPortState)(nil), // 9: metalstack.api.v2.SwitchBGPPortState
+ (*NicState)(nil), // 10: metalstack.api.v2.NicState
+ (*MachineConnection)(nil), // 11: metalstack.api.v2.MachineConnection
+ (*SwitchQuery)(nil), // 12: metalstack.api.v2.SwitchQuery
+ (*SwitchOSQuery)(nil), // 13: metalstack.api.v2.SwitchOSQuery
+ (*Meta)(nil), // 14: metalstack.api.v2.Meta
+ (*timestamppb.Timestamp)(nil), // 15: google.protobuf.Timestamp
}
var file_metalstack_api_v2_switch_proto_depIdxs = []int32{
- 13, // 0: metalstack.api.v2.Switch.meta:type_name -> metalstack.api.v2.Meta
+ 14, // 0: metalstack.api.v2.Switch.meta:type_name -> metalstack.api.v2.Meta
1, // 1: metalstack.api.v2.Switch.replace_mode:type_name -> metalstack.api.v2.SwitchReplaceMode
- 6, // 2: metalstack.api.v2.Switch.nics:type_name -> metalstack.api.v2.SwitchNic
- 5, // 3: metalstack.api.v2.Switch.os:type_name -> metalstack.api.v2.SwitchOS
- 10, // 4: metalstack.api.v2.Switch.machine_connections:type_name -> metalstack.api.v2.MachineConnection
- 2, // 5: metalstack.api.v2.SwitchOS.vendor:type_name -> metalstack.api.v2.SwitchOSVendor
- 9, // 6: metalstack.api.v2.SwitchNic.state:type_name -> metalstack.api.v2.NicState
- 7, // 7: metalstack.api.v2.SwitchNic.bgp_filter:type_name -> metalstack.api.v2.BGPFilter
- 8, // 8: metalstack.api.v2.SwitchNic.bgp_port_state:type_name -> metalstack.api.v2.SwitchBGPPortState
- 0, // 9: metalstack.api.v2.SwitchBGPPortState.bgp_state:type_name -> metalstack.api.v2.BGPState
- 14, // 10: metalstack.api.v2.SwitchBGPPortState.bgp_timer_up_established:type_name -> google.protobuf.Timestamp
- 3, // 11: metalstack.api.v2.NicState.desired:type_name -> metalstack.api.v2.SwitchPortStatus
- 3, // 12: metalstack.api.v2.NicState.actual:type_name -> metalstack.api.v2.SwitchPortStatus
- 6, // 13: metalstack.api.v2.MachineConnection.nic:type_name -> metalstack.api.v2.SwitchNic
- 12, // 14: metalstack.api.v2.SwitchQuery.os:type_name -> metalstack.api.v2.SwitchOSQuery
- 2, // 15: metalstack.api.v2.SwitchOSQuery.vendor:type_name -> metalstack.api.v2.SwitchOSVendor
- 16, // [16:16] is the sub-list for method output_type
- 16, // [16:16] is the sub-list for method input_type
- 16, // [16:16] is the sub-list for extension type_name
- 16, // [16:16] is the sub-list for extension extendee
- 0, // [0:16] is the sub-list for field type_name
+ 7, // 2: metalstack.api.v2.Switch.nics:type_name -> metalstack.api.v2.SwitchNic
+ 6, // 3: metalstack.api.v2.Switch.os:type_name -> metalstack.api.v2.SwitchOS
+ 11, // 4: metalstack.api.v2.Switch.machine_connections:type_name -> metalstack.api.v2.MachineConnection
+ 4, // 5: metalstack.api.v2.Switch.type:type_name -> metalstack.api.v2.SwitchType
+ 2, // 6: metalstack.api.v2.SwitchOS.vendor:type_name -> metalstack.api.v2.SwitchOSVendor
+ 10, // 7: metalstack.api.v2.SwitchNic.state:type_name -> metalstack.api.v2.NicState
+ 8, // 8: metalstack.api.v2.SwitchNic.bgp_filter:type_name -> metalstack.api.v2.BGPFilter
+ 9, // 9: metalstack.api.v2.SwitchNic.bgp_port_state:type_name -> metalstack.api.v2.SwitchBGPPortState
+ 0, // 10: metalstack.api.v2.SwitchBGPPortState.bgp_state:type_name -> metalstack.api.v2.BGPState
+ 15, // 11: metalstack.api.v2.SwitchBGPPortState.bgp_timer_up_established:type_name -> google.protobuf.Timestamp
+ 3, // 12: metalstack.api.v2.NicState.desired:type_name -> metalstack.api.v2.SwitchPortStatus
+ 3, // 13: metalstack.api.v2.NicState.actual:type_name -> metalstack.api.v2.SwitchPortStatus
+ 7, // 14: metalstack.api.v2.MachineConnection.nic:type_name -> metalstack.api.v2.SwitchNic
+ 13, // 15: metalstack.api.v2.SwitchQuery.os:type_name -> metalstack.api.v2.SwitchOSQuery
+ 2, // 16: metalstack.api.v2.SwitchOSQuery.vendor:type_name -> metalstack.api.v2.SwitchOSVendor
+ 17, // [17:17] is the sub-list for method output_type
+ 17, // [17:17] is the sub-list for method input_type
+ 17, // [17:17] is the sub-list for extension type_name
+ 17, // [17:17] is the sub-list for extension extendee
+ 0, // [0:17] is the sub-list for field type_name
}
func init() { file_metalstack_api_v2_switch_proto_init() }
@@ -1135,7 +1220,7 @@ func file_metalstack_api_v2_switch_proto_init() {
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_metalstack_api_v2_switch_proto_rawDesc), len(file_metalstack_api_v2_switch_proto_rawDesc)),
- NumEnums: 4,
+ NumEnums: 5,
NumMessages: 9,
NumExtensions: 0,
NumServices: 0,
diff --git a/go/metalstack/infra/v2/infrav2connect/switch.connect.go b/go/metalstack/infra/v2/infrav2connect/switch.connect.go
index ae248c4b..a3ebe605 100644
--- a/go/metalstack/infra/v2/infrav2connect/switch.connect.go
+++ b/go/metalstack/infra/v2/infrav2connect/switch.connect.go
@@ -39,6 +39,9 @@ const (
SwitchServiceRegisterProcedure = "/metalstack.infra.v2.SwitchService/Register"
// SwitchServiceHeartbeatProcedure is the fully-qualified name of the SwitchService's Heartbeat RPC.
SwitchServiceHeartbeatProcedure = "/metalstack.infra.v2.SwitchService/Heartbeat"
+ // SwitchServiceReportBGPRoutesProcedure is the fully-qualified name of the SwitchService's
+ // ReportBGPRoutes RPC.
+ SwitchServiceReportBGPRoutesProcedure = "/metalstack.infra.v2.SwitchService/ReportBGPRoutes"
)
// SwitchServiceClient is a client for the metalstack.infra.v2.SwitchService service.
@@ -49,6 +52,8 @@ type SwitchServiceClient interface {
Register(context.Context, *v2.SwitchServiceRegisterRequest) (*v2.SwitchServiceRegisterResponse, error)
// Heartbeat a switch.
Heartbeat(context.Context, *v2.SwitchServiceHeartbeatRequest) (*v2.SwitchServiceHeartbeatResponse, error)
+ // ReportBGPRoutes of a switch
+ ReportBGPRoutes(context.Context, *v2.SwitchServiceReportBGPRoutesRequest) (*v2.SwitchServiceReportBGPRoutesResponse, error)
}
// NewSwitchServiceClient constructs a client for the metalstack.infra.v2.SwitchService service. By
@@ -80,14 +85,21 @@ func NewSwitchServiceClient(httpClient connect.HTTPClient, baseURL string, opts
connect.WithSchema(switchServiceMethods.ByName("Heartbeat")),
connect.WithClientOptions(opts...),
),
+ reportBGPRoutes: connect.NewClient[v2.SwitchServiceReportBGPRoutesRequest, v2.SwitchServiceReportBGPRoutesResponse](
+ httpClient,
+ baseURL+SwitchServiceReportBGPRoutesProcedure,
+ connect.WithSchema(switchServiceMethods.ByName("ReportBGPRoutes")),
+ connect.WithClientOptions(opts...),
+ ),
}
}
// switchServiceClient implements SwitchServiceClient.
type switchServiceClient struct {
- get *connect.Client[v2.SwitchServiceGetRequest, v2.SwitchServiceGetResponse]
- register *connect.Client[v2.SwitchServiceRegisterRequest, v2.SwitchServiceRegisterResponse]
- heartbeat *connect.Client[v2.SwitchServiceHeartbeatRequest, v2.SwitchServiceHeartbeatResponse]
+ get *connect.Client[v2.SwitchServiceGetRequest, v2.SwitchServiceGetResponse]
+ register *connect.Client[v2.SwitchServiceRegisterRequest, v2.SwitchServiceRegisterResponse]
+ heartbeat *connect.Client[v2.SwitchServiceHeartbeatRequest, v2.SwitchServiceHeartbeatResponse]
+ reportBGPRoutes *connect.Client[v2.SwitchServiceReportBGPRoutesRequest, v2.SwitchServiceReportBGPRoutesResponse]
}
// Get calls metalstack.infra.v2.SwitchService.Get.
@@ -117,6 +129,15 @@ func (c *switchServiceClient) Heartbeat(ctx context.Context, req *v2.SwitchServi
return nil, err
}
+// ReportBGPRoutes calls metalstack.infra.v2.SwitchService.ReportBGPRoutes.
+func (c *switchServiceClient) ReportBGPRoutes(ctx context.Context, req *v2.SwitchServiceReportBGPRoutesRequest) (*v2.SwitchServiceReportBGPRoutesResponse, error) {
+ response, err := c.reportBGPRoutes.CallUnary(ctx, connect.NewRequest(req))
+ if response != nil {
+ return response.Msg, err
+ }
+ return nil, err
+}
+
// SwitchServiceHandler is an implementation of the metalstack.infra.v2.SwitchService service.
type SwitchServiceHandler interface {
// Get a switch by ID.
@@ -125,6 +146,8 @@ type SwitchServiceHandler interface {
Register(context.Context, *v2.SwitchServiceRegisterRequest) (*v2.SwitchServiceRegisterResponse, error)
// Heartbeat a switch.
Heartbeat(context.Context, *v2.SwitchServiceHeartbeatRequest) (*v2.SwitchServiceHeartbeatResponse, error)
+ // ReportBGPRoutes of a switch
+ ReportBGPRoutes(context.Context, *v2.SwitchServiceReportBGPRoutesRequest) (*v2.SwitchServiceReportBGPRoutesResponse, error)
}
// NewSwitchServiceHandler builds an HTTP handler from the service implementation. It returns the
@@ -152,6 +175,12 @@ func NewSwitchServiceHandler(svc SwitchServiceHandler, opts ...connect.HandlerOp
connect.WithSchema(switchServiceMethods.ByName("Heartbeat")),
connect.WithHandlerOptions(opts...),
)
+ switchServiceReportBGPRoutesHandler := connect.NewUnaryHandlerSimple(
+ SwitchServiceReportBGPRoutesProcedure,
+ svc.ReportBGPRoutes,
+ connect.WithSchema(switchServiceMethods.ByName("ReportBGPRoutes")),
+ connect.WithHandlerOptions(opts...),
+ )
return "/metalstack.infra.v2.SwitchService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch r.URL.Path {
case SwitchServiceGetProcedure:
@@ -160,6 +189,8 @@ func NewSwitchServiceHandler(svc SwitchServiceHandler, opts ...connect.HandlerOp
switchServiceRegisterHandler.ServeHTTP(w, r)
case SwitchServiceHeartbeatProcedure:
switchServiceHeartbeatHandler.ServeHTTP(w, r)
+ case SwitchServiceReportBGPRoutesProcedure:
+ switchServiceReportBGPRoutesHandler.ServeHTTP(w, r)
default:
http.NotFound(w, r)
}
@@ -180,3 +211,7 @@ func (UnimplementedSwitchServiceHandler) Register(context.Context, *v2.SwitchSer
func (UnimplementedSwitchServiceHandler) Heartbeat(context.Context, *v2.SwitchServiceHeartbeatRequest) (*v2.SwitchServiceHeartbeatResponse, error) {
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("metalstack.infra.v2.SwitchService.Heartbeat is not implemented"))
}
+
+func (UnimplementedSwitchServiceHandler) ReportBGPRoutes(context.Context, *v2.SwitchServiceReportBGPRoutesRequest) (*v2.SwitchServiceReportBGPRoutesResponse, error) {
+ return nil, connect.NewError(connect.CodeUnimplemented, errors.New("metalstack.infra.v2.SwitchService.ReportBGPRoutes is not implemented"))
+}
diff --git a/go/metalstack/infra/v2/switch.pb.go b/go/metalstack/infra/v2/switch.pb.go
index 1fd9342a..2031b95a 100644
--- a/go/metalstack/infra/v2/switch.pb.go
+++ b/go/metalstack/infra/v2/switch.pb.go
@@ -209,6 +209,144 @@ func (x *SwitchServiceRegisterResponse) GetSwitch() *v2.Switch {
return nil
}
+// SwitchServiceReportBGPRoutesRequest.
+type SwitchServiceReportBGPRoutesRequest struct {
+ state protoimpl.MessageState `protogen:"open.v1"`
+ // Switch ID of the switch that reports its routes.
+ SwitchId string `protobuf:"bytes,1,opt,name=switch_id,json=switchId,proto3" json:"switch_id,omitempty"`
+ // BGP routes collected on the switch.
+ BgpRoutes []*BGPRoute `protobuf:"bytes,2,rep,name=bgp_routes,json=bgpRoutes,proto3" json:"bgp_routes,omitempty"`
+ unknownFields protoimpl.UnknownFields
+ sizeCache protoimpl.SizeCache
+}
+
+func (x *SwitchServiceReportBGPRoutesRequest) Reset() {
+ *x = SwitchServiceReportBGPRoutesRequest{}
+ mi := &file_metalstack_infra_v2_switch_proto_msgTypes[4]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+}
+
+func (x *SwitchServiceReportBGPRoutesRequest) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SwitchServiceReportBGPRoutesRequest) ProtoMessage() {}
+
+func (x *SwitchServiceReportBGPRoutesRequest) ProtoReflect() protoreflect.Message {
+ mi := &file_metalstack_infra_v2_switch_proto_msgTypes[4]
+ if x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use SwitchServiceReportBGPRoutesRequest.ProtoReflect.Descriptor instead.
+func (*SwitchServiceReportBGPRoutesRequest) Descriptor() ([]byte, []int) {
+ return file_metalstack_infra_v2_switch_proto_rawDescGZIP(), []int{4}
+}
+
+func (x *SwitchServiceReportBGPRoutesRequest) GetSwitchId() string {
+ if x != nil {
+ return x.SwitchId
+ }
+ return ""
+}
+
+func (x *SwitchServiceReportBGPRoutesRequest) GetBgpRoutes() []*BGPRoute {
+ if x != nil {
+ return x.BgpRoutes
+ }
+ return nil
+}
+
+// SwitchServiceReportBGPRoutesResponse.
+type SwitchServiceReportBGPRoutesResponse struct {
+ state protoimpl.MessageState `protogen:"open.v1"`
+ unknownFields protoimpl.UnknownFields
+ sizeCache protoimpl.SizeCache
+}
+
+func (x *SwitchServiceReportBGPRoutesResponse) Reset() {
+ *x = SwitchServiceReportBGPRoutesResponse{}
+ mi := &file_metalstack_infra_v2_switch_proto_msgTypes[5]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+}
+
+func (x *SwitchServiceReportBGPRoutesResponse) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SwitchServiceReportBGPRoutesResponse) ProtoMessage() {}
+
+func (x *SwitchServiceReportBGPRoutesResponse) ProtoReflect() protoreflect.Message {
+ mi := &file_metalstack_infra_v2_switch_proto_msgTypes[5]
+ if x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use SwitchServiceReportBGPRoutesResponse.ProtoReflect.Descriptor instead.
+func (*SwitchServiceReportBGPRoutesResponse) Descriptor() ([]byte, []int) {
+ return file_metalstack_infra_v2_switch_proto_rawDescGZIP(), []int{5}
+}
+
+// BGPRoute represents the route to a prefix.
+type BGPRoute struct {
+ state protoimpl.MessageState `protogen:"open.v1"`
+ // CIDR of the network that is routed to.
+ Cidr string `protobuf:"bytes,1,opt,name=cidr,proto3" json:"cidr,omitempty"`
+ unknownFields protoimpl.UnknownFields
+ sizeCache protoimpl.SizeCache
+}
+
+func (x *BGPRoute) Reset() {
+ *x = BGPRoute{}
+ mi := &file_metalstack_infra_v2_switch_proto_msgTypes[6]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+}
+
+func (x *BGPRoute) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*BGPRoute) ProtoMessage() {}
+
+func (x *BGPRoute) ProtoReflect() protoreflect.Message {
+ mi := &file_metalstack_infra_v2_switch_proto_msgTypes[6]
+ if x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use BGPRoute.ProtoReflect.Descriptor instead.
+func (*BGPRoute) Descriptor() ([]byte, []int) {
+ return file_metalstack_infra_v2_switch_proto_rawDescGZIP(), []int{6}
+}
+
+func (x *BGPRoute) GetCidr() string {
+ if x != nil {
+ return x.Cidr
+ }
+ return ""
+}
+
// SwitchServiceHeartbeatRequest.
type SwitchServiceHeartbeatRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
@@ -228,7 +366,7 @@ type SwitchServiceHeartbeatRequest struct {
func (x *SwitchServiceHeartbeatRequest) Reset() {
*x = SwitchServiceHeartbeatRequest{}
- mi := &file_metalstack_infra_v2_switch_proto_msgTypes[4]
+ mi := &file_metalstack_infra_v2_switch_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -240,7 +378,7 @@ func (x *SwitchServiceHeartbeatRequest) String() string {
func (*SwitchServiceHeartbeatRequest) ProtoMessage() {}
func (x *SwitchServiceHeartbeatRequest) ProtoReflect() protoreflect.Message {
- mi := &file_metalstack_infra_v2_switch_proto_msgTypes[4]
+ mi := &file_metalstack_infra_v2_switch_proto_msgTypes[7]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -253,7 +391,7 @@ func (x *SwitchServiceHeartbeatRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use SwitchServiceHeartbeatRequest.ProtoReflect.Descriptor instead.
func (*SwitchServiceHeartbeatRequest) Descriptor() ([]byte, []int) {
- return file_metalstack_infra_v2_switch_proto_rawDescGZIP(), []int{4}
+ return file_metalstack_infra_v2_switch_proto_rawDescGZIP(), []int{7}
}
func (x *SwitchServiceHeartbeatRequest) GetId() string {
@@ -306,7 +444,7 @@ type SwitchServiceHeartbeatResponse struct {
func (x *SwitchServiceHeartbeatResponse) Reset() {
*x = SwitchServiceHeartbeatResponse{}
- mi := &file_metalstack_infra_v2_switch_proto_msgTypes[5]
+ mi := &file_metalstack_infra_v2_switch_proto_msgTypes[8]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -318,7 +456,7 @@ func (x *SwitchServiceHeartbeatResponse) String() string {
func (*SwitchServiceHeartbeatResponse) ProtoMessage() {}
func (x *SwitchServiceHeartbeatResponse) ProtoReflect() protoreflect.Message {
- mi := &file_metalstack_infra_v2_switch_proto_msgTypes[5]
+ mi := &file_metalstack_infra_v2_switch_proto_msgTypes[8]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -331,7 +469,7 @@ func (x *SwitchServiceHeartbeatResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use SwitchServiceHeartbeatResponse.ProtoReflect.Descriptor instead.
func (*SwitchServiceHeartbeatResponse) Descriptor() ([]byte, []int) {
- return file_metalstack_infra_v2_switch_proto_rawDescGZIP(), []int{5}
+ return file_metalstack_infra_v2_switch_proto_rawDescGZIP(), []int{8}
}
func (x *SwitchServiceHeartbeatResponse) GetId() string {
@@ -370,7 +508,7 @@ type SwitchSync struct {
func (x *SwitchSync) Reset() {
*x = SwitchSync{}
- mi := &file_metalstack_infra_v2_switch_proto_msgTypes[6]
+ mi := &file_metalstack_infra_v2_switch_proto_msgTypes[9]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -382,7 +520,7 @@ func (x *SwitchSync) String() string {
func (*SwitchSync) ProtoMessage() {}
func (x *SwitchSync) ProtoReflect() protoreflect.Message {
- mi := &file_metalstack_infra_v2_switch_proto_msgTypes[6]
+ mi := &file_metalstack_infra_v2_switch_proto_msgTypes[9]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -395,7 +533,7 @@ func (x *SwitchSync) ProtoReflect() protoreflect.Message {
// Deprecated: Use SwitchSync.ProtoReflect.Descriptor instead.
func (*SwitchSync) Descriptor() ([]byte, []int) {
- return file_metalstack_infra_v2_switch_proto_rawDescGZIP(), []int{6}
+ return file_metalstack_infra_v2_switch_proto_rawDescGZIP(), []int{9}
}
func (x *SwitchSync) GetTime() *timestamppb.Timestamp {
@@ -432,7 +570,15 @@ const file_metalstack_infra_v2_switch_proto_rawDesc = "" +
"\x1cSwitchServiceRegisterRequest\x121\n" +
"\x06switch\x18\x01 \x01(\v2\x19.metalstack.api.v2.SwitchR\x06switch\"R\n" +
"\x1dSwitchServiceRegisterResponse\x121\n" +
- "\x06switch\x18\x01 \x01(\v2\x19.metalstack.api.v2.SwitchR\x06switch\"\xbb\x04\n" +
+ "\x06switch\x18\x01 \x01(\v2\x19.metalstack.api.v2.SwitchR\x06switch\"\x8e\x01\n" +
+ "#SwitchServiceReportBGPRoutesRequest\x12)\n" +
+ "\tswitch_id\x18\x01 \x01(\tB\f\xbaH\tr\a\x10\x02\x18\x80\x01h\x01R\bswitchId\x12<\n" +
+ "\n" +
+ "bgp_routes\x18\x02 \x03(\v2\x1d.metalstack.infra.v2.BGPRouteR\tbgpRoutes\"&\n" +
+ "$SwitchServiceReportBGPRoutesResponse\"c\n" +
+ "\bBGPRoute\x12\x12\n" +
+ "\x04cidr\x18\x01 \x01(\tR\x04cidr:C\xbaH@\x1a>\n" +
+ "\x04cidr\x12\x1ecidr must be a valid ip prefix\x1a\x16this.cidr.isIpPrefix()\"\xbb\x04\n" +
"\x1dSwitchServiceHeartbeatRequest\x12\x1d\n" +
"\x02id\x18\x01 \x01(\tB\r\xbaH\n" +
"r\b\xc0\xb3\xae\xb1\x02\x01h\x01R\x02id\x125\n" +
@@ -457,12 +603,13 @@ const file_metalstack_infra_v2_switch_proto_rawDesc = "" +
"\x04time\x18\x01 \x01(\v2\x1a.google.protobuf.TimestampR\x04time\x125\n" +
"\bduration\x18\x02 \x01(\v2\x19.google.protobuf.DurationR\bduration\x12\x19\n" +
"\x05error\x18\x03 \x01(\tH\x00R\x05error\x88\x01\x01B\b\n" +
- "\x06_error2\xfe\x02\n" +
+ "\x06_error2\x8f\x04\n" +
"\rSwitchService\x12n\n" +
"\x03Get\x12,.metalstack.infra.v2.SwitchServiceGetRequest\x1a-.metalstack.infra.v2.SwitchServiceGetResponse\"\n" +
"\xe0\xf3\x18\x02\xea\xf3\x18\x02\x01\x02\x12|\n" +
"\bRegister\x121.metalstack.infra.v2.SwitchServiceRegisterRequest\x1a2.metalstack.infra.v2.SwitchServiceRegisterResponse\"\t\xe0\xf3\x18\x02\xea\xf3\x18\x01\x01\x12\x7f\n" +
- "\tHeartbeat\x122.metalstack.infra.v2.SwitchServiceHeartbeatRequest\x1a3.metalstack.infra.v2.SwitchServiceHeartbeatResponse\"\t\xe0\xf3\x18\x02\xea\xf3\x18\x01\x01B\xcf\x01\n" +
+ "\tHeartbeat\x122.metalstack.infra.v2.SwitchServiceHeartbeatRequest\x1a3.metalstack.infra.v2.SwitchServiceHeartbeatResponse\"\t\xe0\xf3\x18\x02\xea\xf3\x18\x01\x01\x12\x8e\x01\n" +
+ "\x0fReportBGPRoutes\x128.metalstack.infra.v2.SwitchServiceReportBGPRoutesRequest\x1a9.metalstack.infra.v2.SwitchServiceReportBGPRoutesResponse\"\x06\xea\xf3\x18\x02\x01\x02B\xcf\x01\n" +
"\x17com.metalstack.infra.v2B\vSwitchProtoP\x01Z9github.com/metal-stack/api/go/metalstack/infra/v2;infrav2\xa2\x02\x03MIX\xaa\x02\x13Metalstack.Infra.V2\xca\x02\x13Metalstack\\Infra\\V2\xe2\x02\x1fMetalstack\\Infra\\V2\\GPBMetadata\xea\x02\x15Metalstack::Infra::V2b\x06proto3"
var (
@@ -477,47 +624,53 @@ func file_metalstack_infra_v2_switch_proto_rawDescGZIP() []byte {
return file_metalstack_infra_v2_switch_proto_rawDescData
}
-var file_metalstack_infra_v2_switch_proto_msgTypes = make([]protoimpl.MessageInfo, 9)
+var file_metalstack_infra_v2_switch_proto_msgTypes = make([]protoimpl.MessageInfo, 12)
var file_metalstack_infra_v2_switch_proto_goTypes = []any{
- (*SwitchServiceGetRequest)(nil), // 0: metalstack.infra.v2.SwitchServiceGetRequest
- (*SwitchServiceGetResponse)(nil), // 1: metalstack.infra.v2.SwitchServiceGetResponse
- (*SwitchServiceRegisterRequest)(nil), // 2: metalstack.infra.v2.SwitchServiceRegisterRequest
- (*SwitchServiceRegisterResponse)(nil), // 3: metalstack.infra.v2.SwitchServiceRegisterResponse
- (*SwitchServiceHeartbeatRequest)(nil), // 4: metalstack.infra.v2.SwitchServiceHeartbeatRequest
- (*SwitchServiceHeartbeatResponse)(nil), // 5: metalstack.infra.v2.SwitchServiceHeartbeatResponse
- (*SwitchSync)(nil), // 6: metalstack.infra.v2.SwitchSync
- nil, // 7: metalstack.infra.v2.SwitchServiceHeartbeatRequest.PortStatesEntry
- nil, // 8: metalstack.infra.v2.SwitchServiceHeartbeatRequest.BgpPortStatesEntry
- (*v2.Switch)(nil), // 9: metalstack.api.v2.Switch
- (*durationpb.Duration)(nil), // 10: google.protobuf.Duration
- (*timestamppb.Timestamp)(nil), // 11: google.protobuf.Timestamp
- (v2.SwitchPortStatus)(0), // 12: metalstack.api.v2.SwitchPortStatus
- (*v2.SwitchBGPPortState)(nil), // 13: metalstack.api.v2.SwitchBGPPortState
+ (*SwitchServiceGetRequest)(nil), // 0: metalstack.infra.v2.SwitchServiceGetRequest
+ (*SwitchServiceGetResponse)(nil), // 1: metalstack.infra.v2.SwitchServiceGetResponse
+ (*SwitchServiceRegisterRequest)(nil), // 2: metalstack.infra.v2.SwitchServiceRegisterRequest
+ (*SwitchServiceRegisterResponse)(nil), // 3: metalstack.infra.v2.SwitchServiceRegisterResponse
+ (*SwitchServiceReportBGPRoutesRequest)(nil), // 4: metalstack.infra.v2.SwitchServiceReportBGPRoutesRequest
+ (*SwitchServiceReportBGPRoutesResponse)(nil), // 5: metalstack.infra.v2.SwitchServiceReportBGPRoutesResponse
+ (*BGPRoute)(nil), // 6: metalstack.infra.v2.BGPRoute
+ (*SwitchServiceHeartbeatRequest)(nil), // 7: metalstack.infra.v2.SwitchServiceHeartbeatRequest
+ (*SwitchServiceHeartbeatResponse)(nil), // 8: metalstack.infra.v2.SwitchServiceHeartbeatResponse
+ (*SwitchSync)(nil), // 9: metalstack.infra.v2.SwitchSync
+ nil, // 10: metalstack.infra.v2.SwitchServiceHeartbeatRequest.PortStatesEntry
+ nil, // 11: metalstack.infra.v2.SwitchServiceHeartbeatRequest.BgpPortStatesEntry
+ (*v2.Switch)(nil), // 12: metalstack.api.v2.Switch
+ (*durationpb.Duration)(nil), // 13: google.protobuf.Duration
+ (*timestamppb.Timestamp)(nil), // 14: google.protobuf.Timestamp
+ (v2.SwitchPortStatus)(0), // 15: metalstack.api.v2.SwitchPortStatus
+ (*v2.SwitchBGPPortState)(nil), // 16: metalstack.api.v2.SwitchBGPPortState
}
var file_metalstack_infra_v2_switch_proto_depIdxs = []int32{
- 9, // 0: metalstack.infra.v2.SwitchServiceGetResponse.switch:type_name -> metalstack.api.v2.Switch
- 9, // 1: metalstack.infra.v2.SwitchServiceRegisterRequest.switch:type_name -> metalstack.api.v2.Switch
- 9, // 2: metalstack.infra.v2.SwitchServiceRegisterResponse.switch:type_name -> metalstack.api.v2.Switch
- 10, // 3: metalstack.infra.v2.SwitchServiceHeartbeatRequest.duration:type_name -> google.protobuf.Duration
- 7, // 4: metalstack.infra.v2.SwitchServiceHeartbeatRequest.port_states:type_name -> metalstack.infra.v2.SwitchServiceHeartbeatRequest.PortStatesEntry
- 8, // 5: metalstack.infra.v2.SwitchServiceHeartbeatRequest.bgp_port_states:type_name -> metalstack.infra.v2.SwitchServiceHeartbeatRequest.BgpPortStatesEntry
- 6, // 6: metalstack.infra.v2.SwitchServiceHeartbeatResponse.last_sync:type_name -> metalstack.infra.v2.SwitchSync
- 6, // 7: metalstack.infra.v2.SwitchServiceHeartbeatResponse.last_sync_error:type_name -> metalstack.infra.v2.SwitchSync
- 11, // 8: metalstack.infra.v2.SwitchSync.time:type_name -> google.protobuf.Timestamp
- 10, // 9: metalstack.infra.v2.SwitchSync.duration:type_name -> google.protobuf.Duration
- 12, // 10: metalstack.infra.v2.SwitchServiceHeartbeatRequest.PortStatesEntry.value:type_name -> metalstack.api.v2.SwitchPortStatus
- 13, // 11: metalstack.infra.v2.SwitchServiceHeartbeatRequest.BgpPortStatesEntry.value:type_name -> metalstack.api.v2.SwitchBGPPortState
- 0, // 12: metalstack.infra.v2.SwitchService.Get:input_type -> metalstack.infra.v2.SwitchServiceGetRequest
- 2, // 13: metalstack.infra.v2.SwitchService.Register:input_type -> metalstack.infra.v2.SwitchServiceRegisterRequest
- 4, // 14: metalstack.infra.v2.SwitchService.Heartbeat:input_type -> metalstack.infra.v2.SwitchServiceHeartbeatRequest
- 1, // 15: metalstack.infra.v2.SwitchService.Get:output_type -> metalstack.infra.v2.SwitchServiceGetResponse
- 3, // 16: metalstack.infra.v2.SwitchService.Register:output_type -> metalstack.infra.v2.SwitchServiceRegisterResponse
- 5, // 17: metalstack.infra.v2.SwitchService.Heartbeat:output_type -> metalstack.infra.v2.SwitchServiceHeartbeatResponse
- 15, // [15:18] is the sub-list for method output_type
- 12, // [12:15] is the sub-list for method input_type
- 12, // [12:12] is the sub-list for extension type_name
- 12, // [12:12] is the sub-list for extension extendee
- 0, // [0:12] is the sub-list for field type_name
+ 12, // 0: metalstack.infra.v2.SwitchServiceGetResponse.switch:type_name -> metalstack.api.v2.Switch
+ 12, // 1: metalstack.infra.v2.SwitchServiceRegisterRequest.switch:type_name -> metalstack.api.v2.Switch
+ 12, // 2: metalstack.infra.v2.SwitchServiceRegisterResponse.switch:type_name -> metalstack.api.v2.Switch
+ 6, // 3: metalstack.infra.v2.SwitchServiceReportBGPRoutesRequest.bgp_routes:type_name -> metalstack.infra.v2.BGPRoute
+ 13, // 4: metalstack.infra.v2.SwitchServiceHeartbeatRequest.duration:type_name -> google.protobuf.Duration
+ 10, // 5: metalstack.infra.v2.SwitchServiceHeartbeatRequest.port_states:type_name -> metalstack.infra.v2.SwitchServiceHeartbeatRequest.PortStatesEntry
+ 11, // 6: metalstack.infra.v2.SwitchServiceHeartbeatRequest.bgp_port_states:type_name -> metalstack.infra.v2.SwitchServiceHeartbeatRequest.BgpPortStatesEntry
+ 9, // 7: metalstack.infra.v2.SwitchServiceHeartbeatResponse.last_sync:type_name -> metalstack.infra.v2.SwitchSync
+ 9, // 8: metalstack.infra.v2.SwitchServiceHeartbeatResponse.last_sync_error:type_name -> metalstack.infra.v2.SwitchSync
+ 14, // 9: metalstack.infra.v2.SwitchSync.time:type_name -> google.protobuf.Timestamp
+ 13, // 10: metalstack.infra.v2.SwitchSync.duration:type_name -> google.protobuf.Duration
+ 15, // 11: metalstack.infra.v2.SwitchServiceHeartbeatRequest.PortStatesEntry.value:type_name -> metalstack.api.v2.SwitchPortStatus
+ 16, // 12: metalstack.infra.v2.SwitchServiceHeartbeatRequest.BgpPortStatesEntry.value:type_name -> metalstack.api.v2.SwitchBGPPortState
+ 0, // 13: metalstack.infra.v2.SwitchService.Get:input_type -> metalstack.infra.v2.SwitchServiceGetRequest
+ 2, // 14: metalstack.infra.v2.SwitchService.Register:input_type -> metalstack.infra.v2.SwitchServiceRegisterRequest
+ 7, // 15: metalstack.infra.v2.SwitchService.Heartbeat:input_type -> metalstack.infra.v2.SwitchServiceHeartbeatRequest
+ 4, // 16: metalstack.infra.v2.SwitchService.ReportBGPRoutes:input_type -> metalstack.infra.v2.SwitchServiceReportBGPRoutesRequest
+ 1, // 17: metalstack.infra.v2.SwitchService.Get:output_type -> metalstack.infra.v2.SwitchServiceGetResponse
+ 3, // 18: metalstack.infra.v2.SwitchService.Register:output_type -> metalstack.infra.v2.SwitchServiceRegisterResponse
+ 8, // 19: metalstack.infra.v2.SwitchService.Heartbeat:output_type -> metalstack.infra.v2.SwitchServiceHeartbeatResponse
+ 5, // 20: metalstack.infra.v2.SwitchService.ReportBGPRoutes:output_type -> metalstack.infra.v2.SwitchServiceReportBGPRoutesResponse
+ 17, // [17:21] is the sub-list for method output_type
+ 13, // [13:17] is the sub-list for method input_type
+ 13, // [13:13] is the sub-list for extension type_name
+ 13, // [13:13] is the sub-list for extension extendee
+ 0, // [0:13] is the sub-list for field type_name
}
func init() { file_metalstack_infra_v2_switch_proto_init() }
@@ -525,15 +678,15 @@ func file_metalstack_infra_v2_switch_proto_init() {
if File_metalstack_infra_v2_switch_proto != nil {
return
}
- file_metalstack_infra_v2_switch_proto_msgTypes[4].OneofWrappers = []any{}
- file_metalstack_infra_v2_switch_proto_msgTypes[6].OneofWrappers = []any{}
+ file_metalstack_infra_v2_switch_proto_msgTypes[7].OneofWrappers = []any{}
+ file_metalstack_infra_v2_switch_proto_msgTypes[9].OneofWrappers = []any{}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_metalstack_infra_v2_switch_proto_rawDesc), len(file_metalstack_infra_v2_switch_proto_rawDesc)),
NumEnums: 0,
- NumMessages: 9,
+ NumMessages: 12,
NumExtensions: 0,
NumServices: 1,
},
diff --git a/go/permissions/servicepermissions.go b/go/permissions/servicepermissions.go
index df3708e1..be1562e5 100755
--- a/go/permissions/servicepermissions.go
+++ b/go/permissions/servicepermissions.go
@@ -100,9 +100,11 @@ func GetServicePermissions() *ServicePermissions {
"/metalstack.infra.v2.SwitchService/Get",
"/metalstack.infra.v2.SwitchService/Register",
"/metalstack.infra.v2.SwitchService/Heartbeat",
+ "/metalstack.infra.v2.SwitchService/ReportBGPRoutes",
},
"INFRA_ROLE_VIEWER": []string{
"/metalstack.infra.v2.SwitchService/Get",
+ "/metalstack.infra.v2.SwitchService/ReportBGPRoutes",
},
},
Tenant: Tenant{
@@ -296,6 +298,7 @@ func GetServicePermissions() *ServicePermissions {
"/metalstack.infra.v2.SwitchService/Get": true,
"/metalstack.infra.v2.SwitchService/Heartbeat": true,
"/metalstack.infra.v2.SwitchService/Register": true,
+ "/metalstack.infra.v2.SwitchService/ReportBGPRoutes": true,
},
Visibility: Visibility{
Public: map[string]bool{
@@ -369,11 +372,12 @@ func GetServicePermissions() *ServicePermissions {
"/metalstack.admin.v2.TokenService/Revoke": true,
},
Infra: map[string]bool{
- "/metalstack.infra.v2.BMCService/UpdateBMCInfo": true,
- "/metalstack.infra.v2.EventService/Send": true,
- "/metalstack.infra.v2.SwitchService/Get": true,
- "/metalstack.infra.v2.SwitchService/Heartbeat": true,
- "/metalstack.infra.v2.SwitchService/Register": true,
+ "/metalstack.infra.v2.BMCService/UpdateBMCInfo": true,
+ "/metalstack.infra.v2.EventService/Send": true,
+ "/metalstack.infra.v2.SwitchService/Get": true,
+ "/metalstack.infra.v2.SwitchService/Heartbeat": true,
+ "/metalstack.infra.v2.SwitchService/Register": true,
+ "/metalstack.infra.v2.SwitchService/ReportBGPRoutes": true,
},
Tenant: map[string]bool{
"/metalstack.api.v2.ProjectService/Create": true,
@@ -518,6 +522,7 @@ func GetServicePermissions() *ServicePermissions {
"/metalstack.infra.v2.SwitchService/Get": false,
"/metalstack.infra.v2.SwitchService/Heartbeat": false,
"/metalstack.infra.v2.SwitchService/Register": false,
+ "/metalstack.infra.v2.SwitchService/ReportBGPRoutes": true,
},
}
}
diff --git a/go/tests/mocks/metalstack/infra/v2/infrav2connect/SwitchServiceClient.go b/go/tests/mocks/metalstack/infra/v2/infrav2connect/SwitchServiceClient.go
index 86bc30ba..0f678ace 100644
--- a/go/tests/mocks/metalstack/infra/v2/infrav2connect/SwitchServiceClient.go
+++ b/go/tests/mocks/metalstack/infra/v2/infrav2connect/SwitchServiceClient.go
@@ -241,3 +241,71 @@ func (_c *SwitchServiceClient_Register_Call) RunAndReturn(run func(context1 cont
_c.Call.Return(run)
return _c
}
+
+// ReportBGPRoutes provides a mock function for the type SwitchServiceClient
+func (_mock *SwitchServiceClient) ReportBGPRoutes(context1 context.Context, switchServiceReportBGPRoutesRequest *infrav2.SwitchServiceReportBGPRoutesRequest) (*infrav2.SwitchServiceReportBGPRoutesResponse, error) {
+ ret := _mock.Called(context1, switchServiceReportBGPRoutesRequest)
+
+ if len(ret) == 0 {
+ panic("no return value specified for ReportBGPRoutes")
+ }
+
+ var r0 *infrav2.SwitchServiceReportBGPRoutesResponse
+ var r1 error
+ if returnFunc, ok := ret.Get(0).(func(context.Context, *infrav2.SwitchServiceReportBGPRoutesRequest) (*infrav2.SwitchServiceReportBGPRoutesResponse, error)); ok {
+ return returnFunc(context1, switchServiceReportBGPRoutesRequest)
+ }
+ if returnFunc, ok := ret.Get(0).(func(context.Context, *infrav2.SwitchServiceReportBGPRoutesRequest) *infrav2.SwitchServiceReportBGPRoutesResponse); ok {
+ r0 = returnFunc(context1, switchServiceReportBGPRoutesRequest)
+ } else {
+ if ret.Get(0) != nil {
+ r0 = ret.Get(0).(*infrav2.SwitchServiceReportBGPRoutesResponse)
+ }
+ }
+ if returnFunc, ok := ret.Get(1).(func(context.Context, *infrav2.SwitchServiceReportBGPRoutesRequest) error); ok {
+ r1 = returnFunc(context1, switchServiceReportBGPRoutesRequest)
+ } else {
+ r1 = ret.Error(1)
+ }
+ return r0, r1
+}
+
+// SwitchServiceClient_ReportBGPRoutes_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ReportBGPRoutes'
+type SwitchServiceClient_ReportBGPRoutes_Call struct {
+ *mock.Call
+}
+
+// ReportBGPRoutes is a helper method to define mock.On call
+// - context1 context.Context
+// - switchServiceReportBGPRoutesRequest *infrav2.SwitchServiceReportBGPRoutesRequest
+func (_e *SwitchServiceClient_Expecter) ReportBGPRoutes(context1 interface{}, switchServiceReportBGPRoutesRequest interface{}) *SwitchServiceClient_ReportBGPRoutes_Call {
+ return &SwitchServiceClient_ReportBGPRoutes_Call{Call: _e.mock.On("ReportBGPRoutes", context1, switchServiceReportBGPRoutesRequest)}
+}
+
+func (_c *SwitchServiceClient_ReportBGPRoutes_Call) Run(run func(context1 context.Context, switchServiceReportBGPRoutesRequest *infrav2.SwitchServiceReportBGPRoutesRequest)) *SwitchServiceClient_ReportBGPRoutes_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ var arg0 context.Context
+ if args[0] != nil {
+ arg0 = args[0].(context.Context)
+ }
+ var arg1 *infrav2.SwitchServiceReportBGPRoutesRequest
+ if args[1] != nil {
+ arg1 = args[1].(*infrav2.SwitchServiceReportBGPRoutesRequest)
+ }
+ run(
+ arg0,
+ arg1,
+ )
+ })
+ return _c
+}
+
+func (_c *SwitchServiceClient_ReportBGPRoutes_Call) Return(switchServiceReportBGPRoutesResponse *infrav2.SwitchServiceReportBGPRoutesResponse, err error) *SwitchServiceClient_ReportBGPRoutes_Call {
+ _c.Call.Return(switchServiceReportBGPRoutesResponse, err)
+ return _c
+}
+
+func (_c *SwitchServiceClient_ReportBGPRoutes_Call) RunAndReturn(run func(context1 context.Context, switchServiceReportBGPRoutesRequest *infrav2.SwitchServiceReportBGPRoutesRequest) (*infrav2.SwitchServiceReportBGPRoutesResponse, error)) *SwitchServiceClient_ReportBGPRoutes_Call {
+ _c.Call.Return(run)
+ return _c
+}
diff --git a/go/tests/mocks/metalstack/infra/v2/infrav2connect/SwitchServiceHandler.go b/go/tests/mocks/metalstack/infra/v2/infrav2connect/SwitchServiceHandler.go
index d93b3a2e..8c25f43e 100644
--- a/go/tests/mocks/metalstack/infra/v2/infrav2connect/SwitchServiceHandler.go
+++ b/go/tests/mocks/metalstack/infra/v2/infrav2connect/SwitchServiceHandler.go
@@ -241,3 +241,71 @@ func (_c *SwitchServiceHandler_Register_Call) RunAndReturn(run func(context1 con
_c.Call.Return(run)
return _c
}
+
+// ReportBGPRoutes provides a mock function for the type SwitchServiceHandler
+func (_mock *SwitchServiceHandler) ReportBGPRoutes(context1 context.Context, switchServiceReportBGPRoutesRequest *infrav2.SwitchServiceReportBGPRoutesRequest) (*infrav2.SwitchServiceReportBGPRoutesResponse, error) {
+ ret := _mock.Called(context1, switchServiceReportBGPRoutesRequest)
+
+ if len(ret) == 0 {
+ panic("no return value specified for ReportBGPRoutes")
+ }
+
+ var r0 *infrav2.SwitchServiceReportBGPRoutesResponse
+ var r1 error
+ if returnFunc, ok := ret.Get(0).(func(context.Context, *infrav2.SwitchServiceReportBGPRoutesRequest) (*infrav2.SwitchServiceReportBGPRoutesResponse, error)); ok {
+ return returnFunc(context1, switchServiceReportBGPRoutesRequest)
+ }
+ if returnFunc, ok := ret.Get(0).(func(context.Context, *infrav2.SwitchServiceReportBGPRoutesRequest) *infrav2.SwitchServiceReportBGPRoutesResponse); ok {
+ r0 = returnFunc(context1, switchServiceReportBGPRoutesRequest)
+ } else {
+ if ret.Get(0) != nil {
+ r0 = ret.Get(0).(*infrav2.SwitchServiceReportBGPRoutesResponse)
+ }
+ }
+ if returnFunc, ok := ret.Get(1).(func(context.Context, *infrav2.SwitchServiceReportBGPRoutesRequest) error); ok {
+ r1 = returnFunc(context1, switchServiceReportBGPRoutesRequest)
+ } else {
+ r1 = ret.Error(1)
+ }
+ return r0, r1
+}
+
+// SwitchServiceHandler_ReportBGPRoutes_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ReportBGPRoutes'
+type SwitchServiceHandler_ReportBGPRoutes_Call struct {
+ *mock.Call
+}
+
+// ReportBGPRoutes is a helper method to define mock.On call
+// - context1 context.Context
+// - switchServiceReportBGPRoutesRequest *infrav2.SwitchServiceReportBGPRoutesRequest
+func (_e *SwitchServiceHandler_Expecter) ReportBGPRoutes(context1 interface{}, switchServiceReportBGPRoutesRequest interface{}) *SwitchServiceHandler_ReportBGPRoutes_Call {
+ return &SwitchServiceHandler_ReportBGPRoutes_Call{Call: _e.mock.On("ReportBGPRoutes", context1, switchServiceReportBGPRoutesRequest)}
+}
+
+func (_c *SwitchServiceHandler_ReportBGPRoutes_Call) Run(run func(context1 context.Context, switchServiceReportBGPRoutesRequest *infrav2.SwitchServiceReportBGPRoutesRequest)) *SwitchServiceHandler_ReportBGPRoutes_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ var arg0 context.Context
+ if args[0] != nil {
+ arg0 = args[0].(context.Context)
+ }
+ var arg1 *infrav2.SwitchServiceReportBGPRoutesRequest
+ if args[1] != nil {
+ arg1 = args[1].(*infrav2.SwitchServiceReportBGPRoutesRequest)
+ }
+ run(
+ arg0,
+ arg1,
+ )
+ })
+ return _c
+}
+
+func (_c *SwitchServiceHandler_ReportBGPRoutes_Call) Return(switchServiceReportBGPRoutesResponse *infrav2.SwitchServiceReportBGPRoutesResponse, err error) *SwitchServiceHandler_ReportBGPRoutes_Call {
+ _c.Call.Return(switchServiceReportBGPRoutesResponse, err)
+ return _c
+}
+
+func (_c *SwitchServiceHandler_ReportBGPRoutes_Call) RunAndReturn(run func(context1 context.Context, switchServiceReportBGPRoutesRequest *infrav2.SwitchServiceReportBGPRoutesRequest) (*infrav2.SwitchServiceReportBGPRoutesResponse, error)) *SwitchServiceHandler_ReportBGPRoutes_Call {
+ _c.Call.Return(run)
+ return _c
+}
diff --git a/go/tests/validation/common.go b/go/tests/validation/common.go
index bdc5a379..84500990 100644
--- a/go/tests/validation/common.go
+++ b/go/tests/validation/common.go
@@ -27,7 +27,7 @@ func validateProtos(t *testing.T, tests prototests) {
t.Errorf("validate error = %v, wantErr %v", err, tt.wantErr)
}
if err != nil && tt.wantErr {
- if diff := cmp.Diff(err.Error(), tt.wantErrorMessage); diff != "" {
+ if diff := cmp.Diff(tt.wantErrorMessage, err.Error()); diff != "" {
t.Errorf("validate error = %v, diff %v", err, diff)
}
}
diff --git a/go/tests/validation/switch_test.go b/go/tests/validation/switch_test.go
index 9bc216c3..d8af3dd7 100644
--- a/go/tests/validation/switch_test.go
+++ b/go/tests/validation/switch_test.go
@@ -4,65 +4,70 @@ import (
"testing"
apiv2 "github.com/metal-stack/api/go/metalstack/api/v2"
- "google.golang.org/protobuf/proto"
)
-func TestValidateSwitch(t *testing.T) {
+func TestValidateMACAddress(t *testing.T) {
tests := prototests{
{
- name: "SwitchNic with invalid MAC",
+ name: "Valid MAC address",
msg: &apiv2.SwitchNic{
- Name: "eth0",
- Identifier: "swp1",
- Mac: "abc",
- Vrf: proto.String("10"),
+ Mac: "11:22:33:44:55:66",
+ Name: "Ethernet0",
+ Identifier: "Eth1/1",
+ },
+ wantErr: false,
+ },
+ {
+ name: "Too long",
+ msg: &apiv2.SwitchNic{
+ Mac: "11:22:33:44:55:66:77",
+ Name: "Ethernet0",
+ Identifier: "Eth1/1",
},
wantErr: true,
- wantErrorMessage: `validation error: mac: this string must be a valid macaddress`,
+ wantErrorMessage: "validation error: mac: this string must be a valid macaddress",
},
{
- name: "SwitchNic with valid lowercase MAC",
+ name: "Too short",
msg: &apiv2.SwitchNic{
- Name: "eth0",
- Identifier: "swp1",
- Mac: "00:80:41:ae:fd:7e",
- Vrf: proto.String("10"),
+ Mac: "11:22:33:44:55",
+ Name: "Ethernet0",
+ Identifier: "Eth1/1",
},
- wantErr: false,
+ wantErr: true,
+ wantErrorMessage: "validation error: mac: this string must be a valid macaddress",
},
{
- name: "SwitchNic with valid uppercase MAC",
+ name: "Invalid separator",
msg: &apiv2.SwitchNic{
- Name: "eth0",
- Identifier: "swp1",
- Mac: "00:80:41:AE:FD:7E",
- Vrf: proto.String("10"),
+ Mac: "11.22.33.44.55.66",
+ Name: "Ethernet0",
+ Identifier: "Eth1/1",
},
- wantErr: false,
+ wantErr: true,
+ wantErrorMessage: "validation error: mac: this string must be a valid macaddress",
},
{
- name: "Switch with valid id",
- msg: &apiv2.Switch{
- Id: "leaf01",
- Partition: "p1",
- ManagementIp: "1.2.3.4",
- ManagementUser: proto.String("admin"),
- ConsoleCommand: proto.String("ssh"),
+ name: "Invalid character",
+ msg: &apiv2.SwitchNic{
+ Mac: "11:22:33:44:55:gg",
+ Name: "Ethernet0",
+ Identifier: "Eth1/1",
},
- wantErr: false,
+ wantErr: true,
+ wantErrorMessage: "validation error: mac: this string must be a valid macaddress",
},
{
- name: "Switch with invalid id",
- msg: &apiv2.Switch{
- Id: "_1",
- Partition: "p1",
- ManagementIp: "1.2.3.4",
- ManagementUser: proto.String("admin"),
- ConsoleCommand: proto.String("ssh"),
+ name: "Uppercase and lowercase allowed",
+ msg: &apiv2.SwitchNic{
+ Mac: "11:22:33:44:55:aA",
+ Name: "Ethernet0",
+ Identifier: "Eth1/1",
},
wantErr: true,
- wantErrorMessage: `validation error: id: value must be a valid hostname`,
+ wantErrorMessage: "validation error: mac: this string must be a valid macaddress",
},
}
+
validateProtos(t, tests)
}
diff --git a/proto/metalstack/api/v2/switch.proto b/proto/metalstack/api/v2/switch.proto
index 873b1d3a..2ba315a1 100644
--- a/proto/metalstack/api/v2/switch.proto
+++ b/proto/metalstack/api/v2/switch.proto
@@ -42,6 +42,8 @@ message Switch {
SwitchOS os = 11;
// MachineConnections map machines to the nics they are connected to.
repeated MachineConnection machine_connections = 12;
+ // Type is the role of the switch.
+ SwitchType type = 13 [(buf.validate.field).enum.defined_only = true];
}
// SwitchOS holds information about the NOS and versions running on the switch.
@@ -189,3 +191,19 @@ enum SwitchPortStatus {
// SWITCH_PORT_STATUS_UNKNOWN means the status of this port is unknown.
SWITCH_PORT_STATUS_UNKNOWN = 3 [(enum_string_value) = "unknown"];
}
+
+// 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"];
+}
diff --git a/proto/metalstack/infra/v2/switch.proto b/proto/metalstack/infra/v2/switch.proto
index d89dc204..3e91a1ec 100644
--- a/proto/metalstack/infra/v2/switch.proto
+++ b/proto/metalstack/infra/v2/switch.proto
@@ -27,6 +27,11 @@ service SwitchService {
option (metalstack.api.v2.infra_roles) = INFRA_ROLE_EDITOR;
option (metalstack.api.v2.auditing) = AUDITING_EXCLUDED;
}
+ // ReportBGPRoutes 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;
+ }
}
// SwitchServiceGetRequest.
@@ -56,6 +61,32 @@ message SwitchServiceRegisterResponse {
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 bgp_routes = 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()"
+ };
+}
+
// SwitchServiceHeartbeatRequest.
message SwitchServiceHeartbeatRequest {
// Id of the switch.
diff --git a/python/metalstack/api/v2/switch_pb2.py b/python/metalstack/api/v2/switch_pb2.py
index bcedf32e..de3092b1 100644
--- a/python/metalstack/api/v2/switch_pb2.py
+++ b/python/metalstack/api/v2/switch_pb2.py
@@ -28,7 +28,7 @@
from metalstack.api.v2 import predefined_rules_pb2 as metalstack_dot_api_dot_v2_dot_predefined__rules__pb2
-DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1emetalstack/api/v2/switch.proto\x12\x11metalstack.api.v2\x1a\x1b\x62uf/validate/validate.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1emetalstack/api/v2/common.proto\x1a(metalstack/api/v2/predefined_rules.proto\"\xb0\x05\n\x06Switch\x12\x1d\n\x02id\x18\x01 \x01(\tB\r\xbaH\nr\x08h\x01\xc0\xb3\xae\xb1\x02\x01R\x02id\x12+\n\x04meta\x18\x02 \x01(\x0b\x32\x17.metalstack.api.v2.MetaR\x04meta\x12-\n\x0b\x64\x65scription\x18\x03 \x01(\tB\x0b\xbaH\x08r\x06\xc8\xb3\xae\xb1\x02\x01R\x0b\x64\x65scription\x12$\n\x04rack\x18\x04 \x01(\tB\x0b\xbaH\x08r\x06\xc0\xb3\xae\xb1\x02\x01H\x00R\x04rack\x88\x01\x01\x12)\n\tpartition\x18\x05 \x01(\tB\x0b\xbaH\x08r\x06\xd0\xb3\xae\xb1\x02\x01R\tpartition\x12Q\n\x0creplace_mode\x18\x06 \x01(\x0e\x32$.metalstack.api.v2.SwitchReplaceModeB\x08\xbaH\x05\x82\x01\x02\x10\x01R\x0breplaceMode\x12,\n\rmanagement_ip\x18\x07 \x01(\tB\x07\xbaH\x04r\x02p\x01R\x0cmanagementIp\x12\x38\n\x0fmanagement_user\x18\x08 \x01(\tB\n\xbaH\x07r\x05\x10\x02\x18\x80\x01H\x01R\x0emanagementUser\x88\x01\x01\x12\x38\n\x0f\x63onsole_command\x18\t \x01(\tB\n\xbaH\x07r\x05\x10\x02\x18\x80\x01H\x02R\x0e\x63onsoleCommand\x88\x01\x01\x12\x30\n\x04nics\x18\n \x03(\x0b\x32\x1c.metalstack.api.v2.SwitchNicR\x04nics\x12+\n\x02os\x18\x0b \x01(\x0b\x32\x1b.metalstack.api.v2.SwitchOSR\x02os\x12U\n\x13machine_connections\x18\x0c \x03(\x0b\x32$.metalstack.api.v2.MachineConnectionR\x12machineConnectionsB\x07\n\x05_rackB\x12\n\x10_management_userB\x12\n\x10_console_command\"\xb1\x01\n\x08SwitchOS\x12\x43\n\x06vendor\x18\x01 \x01(\x0e\x32!.metalstack.api.v2.SwitchOSVendorB\x08\xbaH\x05\x82\x01\x02\x10\x01R\x06vendor\x12%\n\x07version\x18\x02 \x01(\tB\x0b\xbaH\x08r\x06\xc0\xb3\xae\xb1\x02\x01R\x07version\x12\x39\n\x12metal_core_version\x18\x03 \x01(\tB\x0b\xbaH\x08r\x06\xc0\xb3\xae\xb1\x02\x01R\x10metalCoreVersion\"\x9c\x03\n\tSwitchNic\x12\x1f\n\x04name\x18\x01 \x01(\tB\x0b\xbaH\x08r\x06\xc0\xb3\xae\xb1\x02\x01R\x04name\x12+\n\nidentifier\x18\x02 \x01(\tB\x0b\xbaH\x08r\x06\xc0\xb3\xae\xb1\x02\x01R\nidentifier\x12\x1d\n\x03mac\x18\x03 \x01(\tB\x0b\xbaH\x08r\x06\xb8\xb3\xae\xb1\x02\x01R\x03mac\x12\"\n\x03vrf\x18\x04 \x01(\tB\x0b\xbaH\x08r\x06\xc0\xb3\xae\xb1\x02\x01H\x00R\x03vrf\x88\x01\x01\x12\x36\n\x05state\x18\x05 \x01(\x0b\x32\x1b.metalstack.api.v2.NicStateH\x01R\x05state\x88\x01\x01\x12@\n\nbgp_filter\x18\x06 \x01(\x0b\x32\x1c.metalstack.api.v2.BGPFilterH\x02R\tbgpFilter\x88\x01\x01\x12P\n\x0e\x62gp_port_state\x18\x07 \x01(\x0b\x32%.metalstack.api.v2.SwitchBGPPortStateH\x03R\x0c\x62gpPortState\x88\x01\x01\x42\x06\n\x04_vrfB\x08\n\x06_stateB\r\n\x0b_bgp_filterB\x11\n\x0f_bgp_port_state\"T\n\tBGPFilter\x12\"\n\x05\x63idrs\x18\x01 \x03(\tB\x0c\xbaH\t\x92\x01\x06\xe0\xb3\xae\xb1\x02\x01R\x05\x63idrs\x12#\n\x04vnis\x18\x02 \x03(\tB\x0f\xbaH\x0c\x92\x01\t\"\x07r\x05\x10\x02\x18\x80\x01R\x04vnis\"\x92\x03\n\x12SwitchBGPPortState\x12\'\n\x08neighbor\x18\x01 \x01(\tB\x0b\xbaH\x08r\x06\xc0\xb3\xae\xb1\x02\x01R\x08neighbor\x12*\n\npeer_group\x18\x02 \x01(\tB\x0b\xbaH\x08r\x06\xc0\xb3\xae\xb1\x02\x01R\tpeerGroup\x12&\n\x08vrf_name\x18\x03 \x01(\tB\x0b\xbaH\x08r\x06\xc0\xb3\xae\xb1\x02\x01R\x07vrfName\x12\x42\n\tbgp_state\x18\x04 \x01(\x0e\x32\x1b.metalstack.api.v2.BGPStateB\x08\xbaH\x05\x82\x01\x02\x10\x01R\x08\x62gpState\x12S\n\x18\x62gp_timer_up_established\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\x15\x62gpTimerUpEstablished\x12.\n\x13sent_prefix_counter\x18\x06 \x01(\x04R\x11sentPrefixCounter\x12\x36\n\x17\x61\x63\x63\x65pted_prefix_counter\x18\x07 \x01(\x04R\x15\x61\x63\x63\x65ptedPrefixCounter\"\xab\x01\n\x08NicState\x12L\n\x07\x64\x65sired\x18\x01 \x01(\x0e\x32#.metalstack.api.v2.SwitchPortStatusB\x08\xbaH\x05\x82\x01\x02\x10\x01H\x00R\x07\x64\x65sired\x88\x01\x01\x12\x45\n\x06\x61\x63tual\x18\x02 \x01(\x0e\x32#.metalstack.api.v2.SwitchPortStatusB\x08\xbaH\x05\x82\x01\x02\x10\x01R\x06\x61\x63tualB\n\n\x08_desired\"b\n\x11MachineConnection\x12\x1d\n\nmachine_id\x18\x01 \x01(\tR\tmachineId\x12.\n\x03nic\x18\x02 \x01(\x0b\x32\x1c.metalstack.api.v2.SwitchNicR\x03nic\"\xe3\x01\n\x0bSwitchQuery\x12\"\n\x02id\x18\x01 \x01(\tB\r\xbaH\nr\x08h\x01\xc0\xb3\xae\xb1\x02\x01H\x00R\x02id\x88\x01\x01\x12.\n\tpartition\x18\x02 \x01(\tB\x0b\xbaH\x08r\x06\xd0\xb3\xae\xb1\x02\x01H\x01R\tpartition\x88\x01\x01\x12$\n\x04rack\x18\x03 \x01(\tB\x0b\xbaH\x08r\x06\xc0\xb3\xae\xb1\x02\x01H\x02R\x04rack\x88\x01\x01\x12\x35\n\x02os\x18\x04 \x01(\x0b\x32 .metalstack.api.v2.SwitchOSQueryH\x03R\x02os\x88\x01\x01\x42\x05\n\x03_idB\x0c\n\n_partitionB\x07\n\x05_rackB\x05\n\x03_os\"\x9c\x01\n\rSwitchOSQuery\x12H\n\x06vendor\x18\x01 \x01(\x0e\x32!.metalstack.api.v2.SwitchOSVendorB\x08\xbaH\x05\x82\x01\x02\x10\x01H\x00R\x06vendor\x88\x01\x01\x12*\n\x07version\x18\x02 \x01(\tB\x0b\xbaH\x08r\x06\xc0\xb3\xae\xb1\x02\x01H\x01R\x07version\x88\x01\x01\x42\t\n\x07_vendorB\n\n\x08_version*\x8b\x02\n\x08\x42GPState\x12\x19\n\x15\x42GP_STATE_UNSPECIFIED\x10\x00\x12\x1c\n\x0e\x42GP_STATE_IDLE\x10\x01\x1a\x08\x82\xb2\x19\x04idle\x12\"\n\x11\x42GP_STATE_CONNECT\x10\x02\x1a\x0b\x82\xb2\x19\x07\x63onnect\x12 \n\x10\x42GP_STATE_ACTIVE\x10\x03\x1a\n\x82\xb2\x19\x06\x61\x63tive\x12&\n\x13\x42GP_STATE_OPEN_SENT\x10\x04\x1a\r\x82\xb2\x19\topen-sent\x12,\n\x16\x42GP_STATE_OPEN_CONFIRM\x10\x05\x1a\x10\x82\xb2\x19\x0copen-confirm\x12*\n\x15\x42GP_STATE_ESTABLISHED\x10\x06\x1a\x0f\x82\xb2\x19\x0b\x65stablished*\x9c\x01\n\x11SwitchReplaceMode\x12#\n\x1fSWITCH_REPLACE_MODE_UNSPECIFIED\x10\x00\x12,\n\x1bSWITCH_REPLACE_MODE_REPLACE\x10\x01\x1a\x0b\x82\xb2\x19\x07replace\x12\x34\n\x1fSWITCH_REPLACE_MODE_OPERATIONAL\x10\x02\x1a\x0f\x82\xb2\x19\x0boperational*\x84\x01\n\x0eSwitchOSVendor\x12 \n\x1cSWITCH_OS_VENDOR_UNSPECIFIED\x10\x00\x12)\n\x18SWITCH_OS_VENDOR_CUMULUS\x10\x01\x1a\x0b\x82\xb2\x19\x07\x43umulus\x12%\n\x16SWITCH_OS_VENDOR_SONIC\x10\x02\x1a\t\x82\xb2\x19\x05SONiC*\xad\x01\n\x10SwitchPortStatus\x12\"\n\x1eSWITCH_PORT_STATUS_UNSPECIFIED\x10\x00\x12!\n\x15SWITCH_PORT_STATUS_UP\x10\x01\x1a\x06\x82\xb2\x19\x02up\x12%\n\x17SWITCH_PORT_STATUS_DOWN\x10\x02\x1a\x08\x82\xb2\x19\x04\x64own\x12+\n\x1aSWITCH_PORT_STATUS_UNKNOWN\x10\x03\x1a\x0b\x82\xb2\x19\x07unknownB\xc1\x01\n\x15\x63om.metalstack.api.v2B\x0bSwitchProtoP\x01Z5github.com/metal-stack/api/go/metalstack/api/v2;apiv2\xa2\x02\x03MAX\xaa\x02\x11Metalstack.Api.V2\xca\x02\x11Metalstack\\Api\\V2\xe2\x02\x1dMetalstack\\Api\\V2\\GPBMetadata\xea\x02\x13Metalstack::Api::V2b\x06proto3')
+DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1emetalstack/api/v2/switch.proto\x12\x11metalstack.api.v2\x1a\x1b\x62uf/validate/validate.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1emetalstack/api/v2/common.proto\x1a(metalstack/api/v2/predefined_rules.proto\"\xed\x05\n\x06Switch\x12\x1d\n\x02id\x18\x01 \x01(\tB\r\xbaH\nr\x08h\x01\xc0\xb3\xae\xb1\x02\x01R\x02id\x12+\n\x04meta\x18\x02 \x01(\x0b\x32\x17.metalstack.api.v2.MetaR\x04meta\x12-\n\x0b\x64\x65scription\x18\x03 \x01(\tB\x0b\xbaH\x08r\x06\xc8\xb3\xae\xb1\x02\x01R\x0b\x64\x65scription\x12$\n\x04rack\x18\x04 \x01(\tB\x0b\xbaH\x08r\x06\xc0\xb3\xae\xb1\x02\x01H\x00R\x04rack\x88\x01\x01\x12)\n\tpartition\x18\x05 \x01(\tB\x0b\xbaH\x08r\x06\xd0\xb3\xae\xb1\x02\x01R\tpartition\x12Q\n\x0creplace_mode\x18\x06 \x01(\x0e\x32$.metalstack.api.v2.SwitchReplaceModeB\x08\xbaH\x05\x82\x01\x02\x10\x01R\x0breplaceMode\x12,\n\rmanagement_ip\x18\x07 \x01(\tB\x07\xbaH\x04r\x02p\x01R\x0cmanagementIp\x12\x38\n\x0fmanagement_user\x18\x08 \x01(\tB\n\xbaH\x07r\x05\x10\x02\x18\x80\x01H\x01R\x0emanagementUser\x88\x01\x01\x12\x38\n\x0f\x63onsole_command\x18\t \x01(\tB\n\xbaH\x07r\x05\x10\x02\x18\x80\x01H\x02R\x0e\x63onsoleCommand\x88\x01\x01\x12\x30\n\x04nics\x18\n \x03(\x0b\x32\x1c.metalstack.api.v2.SwitchNicR\x04nics\x12+\n\x02os\x18\x0b \x01(\x0b\x32\x1b.metalstack.api.v2.SwitchOSR\x02os\x12U\n\x13machine_connections\x18\x0c \x03(\x0b\x32$.metalstack.api.v2.MachineConnectionR\x12machineConnections\x12;\n\x04type\x18\r \x01(\x0e\x32\x1d.metalstack.api.v2.SwitchTypeB\x08\xbaH\x05\x82\x01\x02\x10\x01R\x04typeB\x07\n\x05_rackB\x12\n\x10_management_userB\x12\n\x10_console_command\"\xb1\x01\n\x08SwitchOS\x12\x43\n\x06vendor\x18\x01 \x01(\x0e\x32!.metalstack.api.v2.SwitchOSVendorB\x08\xbaH\x05\x82\x01\x02\x10\x01R\x06vendor\x12%\n\x07version\x18\x02 \x01(\tB\x0b\xbaH\x08r\x06\xc0\xb3\xae\xb1\x02\x01R\x07version\x12\x39\n\x12metal_core_version\x18\x03 \x01(\tB\x0b\xbaH\x08r\x06\xc0\xb3\xae\xb1\x02\x01R\x10metalCoreVersion\"\x9c\x03\n\tSwitchNic\x12\x1f\n\x04name\x18\x01 \x01(\tB\x0b\xbaH\x08r\x06\xc0\xb3\xae\xb1\x02\x01R\x04name\x12+\n\nidentifier\x18\x02 \x01(\tB\x0b\xbaH\x08r\x06\xc0\xb3\xae\xb1\x02\x01R\nidentifier\x12\x1d\n\x03mac\x18\x03 \x01(\tB\x0b\xbaH\x08r\x06\xb8\xb3\xae\xb1\x02\x01R\x03mac\x12\"\n\x03vrf\x18\x04 \x01(\tB\x0b\xbaH\x08r\x06\xc0\xb3\xae\xb1\x02\x01H\x00R\x03vrf\x88\x01\x01\x12\x36\n\x05state\x18\x05 \x01(\x0b\x32\x1b.metalstack.api.v2.NicStateH\x01R\x05state\x88\x01\x01\x12@\n\nbgp_filter\x18\x06 \x01(\x0b\x32\x1c.metalstack.api.v2.BGPFilterH\x02R\tbgpFilter\x88\x01\x01\x12P\n\x0e\x62gp_port_state\x18\x07 \x01(\x0b\x32%.metalstack.api.v2.SwitchBGPPortStateH\x03R\x0c\x62gpPortState\x88\x01\x01\x42\x06\n\x04_vrfB\x08\n\x06_stateB\r\n\x0b_bgp_filterB\x11\n\x0f_bgp_port_state\"T\n\tBGPFilter\x12\"\n\x05\x63idrs\x18\x01 \x03(\tB\x0c\xbaH\t\x92\x01\x06\xe0\xb3\xae\xb1\x02\x01R\x05\x63idrs\x12#\n\x04vnis\x18\x02 \x03(\tB\x0f\xbaH\x0c\x92\x01\t\"\x07r\x05\x10\x02\x18\x80\x01R\x04vnis\"\x92\x03\n\x12SwitchBGPPortState\x12\'\n\x08neighbor\x18\x01 \x01(\tB\x0b\xbaH\x08r\x06\xc0\xb3\xae\xb1\x02\x01R\x08neighbor\x12*\n\npeer_group\x18\x02 \x01(\tB\x0b\xbaH\x08r\x06\xc0\xb3\xae\xb1\x02\x01R\tpeerGroup\x12&\n\x08vrf_name\x18\x03 \x01(\tB\x0b\xbaH\x08r\x06\xc0\xb3\xae\xb1\x02\x01R\x07vrfName\x12\x42\n\tbgp_state\x18\x04 \x01(\x0e\x32\x1b.metalstack.api.v2.BGPStateB\x08\xbaH\x05\x82\x01\x02\x10\x01R\x08\x62gpState\x12S\n\x18\x62gp_timer_up_established\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\x15\x62gpTimerUpEstablished\x12.\n\x13sent_prefix_counter\x18\x06 \x01(\x04R\x11sentPrefixCounter\x12\x36\n\x17\x61\x63\x63\x65pted_prefix_counter\x18\x07 \x01(\x04R\x15\x61\x63\x63\x65ptedPrefixCounter\"\xab\x01\n\x08NicState\x12L\n\x07\x64\x65sired\x18\x01 \x01(\x0e\x32#.metalstack.api.v2.SwitchPortStatusB\x08\xbaH\x05\x82\x01\x02\x10\x01H\x00R\x07\x64\x65sired\x88\x01\x01\x12\x45\n\x06\x61\x63tual\x18\x02 \x01(\x0e\x32#.metalstack.api.v2.SwitchPortStatusB\x08\xbaH\x05\x82\x01\x02\x10\x01R\x06\x61\x63tualB\n\n\x08_desired\"b\n\x11MachineConnection\x12\x1d\n\nmachine_id\x18\x01 \x01(\tR\tmachineId\x12.\n\x03nic\x18\x02 \x01(\x0b\x32\x1c.metalstack.api.v2.SwitchNicR\x03nic\"\xe3\x01\n\x0bSwitchQuery\x12\"\n\x02id\x18\x01 \x01(\tB\r\xbaH\nr\x08h\x01\xc0\xb3\xae\xb1\x02\x01H\x00R\x02id\x88\x01\x01\x12.\n\tpartition\x18\x02 \x01(\tB\x0b\xbaH\x08r\x06\xd0\xb3\xae\xb1\x02\x01H\x01R\tpartition\x88\x01\x01\x12$\n\x04rack\x18\x03 \x01(\tB\x0b\xbaH\x08r\x06\xc0\xb3\xae\xb1\x02\x01H\x02R\x04rack\x88\x01\x01\x12\x35\n\x02os\x18\x04 \x01(\x0b\x32 .metalstack.api.v2.SwitchOSQueryH\x03R\x02os\x88\x01\x01\x42\x05\n\x03_idB\x0c\n\n_partitionB\x07\n\x05_rackB\x05\n\x03_os\"\x9c\x01\n\rSwitchOSQuery\x12H\n\x06vendor\x18\x01 \x01(\x0e\x32!.metalstack.api.v2.SwitchOSVendorB\x08\xbaH\x05\x82\x01\x02\x10\x01H\x00R\x06vendor\x88\x01\x01\x12*\n\x07version\x18\x02 \x01(\tB\x0b\xbaH\x08r\x06\xc0\xb3\xae\xb1\x02\x01H\x01R\x07version\x88\x01\x01\x42\t\n\x07_vendorB\n\n\x08_version*\x8b\x02\n\x08\x42GPState\x12\x19\n\x15\x42GP_STATE_UNSPECIFIED\x10\x00\x12\x1c\n\x0e\x42GP_STATE_IDLE\x10\x01\x1a\x08\x82\xb2\x19\x04idle\x12\"\n\x11\x42GP_STATE_CONNECT\x10\x02\x1a\x0b\x82\xb2\x19\x07\x63onnect\x12 \n\x10\x42GP_STATE_ACTIVE\x10\x03\x1a\n\x82\xb2\x19\x06\x61\x63tive\x12&\n\x13\x42GP_STATE_OPEN_SENT\x10\x04\x1a\r\x82\xb2\x19\topen-sent\x12,\n\x16\x42GP_STATE_OPEN_CONFIRM\x10\x05\x1a\x10\x82\xb2\x19\x0copen-confirm\x12*\n\x15\x42GP_STATE_ESTABLISHED\x10\x06\x1a\x0f\x82\xb2\x19\x0b\x65stablished*\x9c\x01\n\x11SwitchReplaceMode\x12#\n\x1fSWITCH_REPLACE_MODE_UNSPECIFIED\x10\x00\x12,\n\x1bSWITCH_REPLACE_MODE_REPLACE\x10\x01\x1a\x0b\x82\xb2\x19\x07replace\x12\x34\n\x1fSWITCH_REPLACE_MODE_OPERATIONAL\x10\x02\x1a\x0f\x82\xb2\x19\x0boperational*\x84\x01\n\x0eSwitchOSVendor\x12 \n\x1cSWITCH_OS_VENDOR_UNSPECIFIED\x10\x00\x12)\n\x18SWITCH_OS_VENDOR_CUMULUS\x10\x01\x1a\x0b\x82\xb2\x19\x07\x43umulus\x12%\n\x16SWITCH_OS_VENDOR_SONIC\x10\x02\x1a\t\x82\xb2\x19\x05SONiC*\xad\x01\n\x10SwitchPortStatus\x12\"\n\x1eSWITCH_PORT_STATUS_UNSPECIFIED\x10\x00\x12!\n\x15SWITCH_PORT_STATUS_UP\x10\x01\x1a\x06\x82\xb2\x19\x02up\x12%\n\x17SWITCH_PORT_STATUS_DOWN\x10\x02\x1a\x08\x82\xb2\x19\x04\x64own\x12+\n\x1aSWITCH_PORT_STATUS_UNKNOWN\x10\x03\x1a\x0b\x82\xb2\x19\x07unknown*\xdd\x01\n\nSwitchType\x12\x1b\n\x17SWITCH_TYPE_UNSPECIFIED\x10\x00\x12\x1e\n\x10SWITCH_TYPE_LEAF\x10\x01\x1a\x08\x82\xb2\x19\x04leaf\x12\x1e\n\x10SWITCH_TYPE_EXIT\x10\x02\x1a\x08\x82\xb2\x19\x04\x65xit\x12 \n\x11SWITCH_TYPE_SPINE\x10\x03\x1a\t\x82\xb2\x19\x05spine\x12&\n\x14SWITCH_TYPE_MGMTLEAF\x10\x04\x1a\x0c\x82\xb2\x19\x08mgmtleaf\x12(\n\x15SWITCH_TYPE_MGMTSPINE\x10\x05\x1a\r\x82\xb2\x19\tmgmtspineB\xc1\x01\n\x15\x63om.metalstack.api.v2B\x0bSwitchProtoP\x01Z5github.com/metal-stack/api/go/metalstack/api/v2;apiv2\xa2\x02\x03MAX\xaa\x02\x11Metalstack.Api.V2\xca\x02\x11Metalstack\\Api\\V2\xe2\x02\x1dMetalstack\\Api\\V2\\GPBMetadata\xea\x02\x13Metalstack::Api::V2b\x06proto3')
_globals = globals()
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
@@ -62,6 +62,16 @@
_globals['_SWITCHPORTSTATUS'].values_by_name["SWITCH_PORT_STATUS_DOWN"]._serialized_options = b'\202\262\031\004down'
_globals['_SWITCHPORTSTATUS'].values_by_name["SWITCH_PORT_STATUS_UNKNOWN"]._loaded_options = None
_globals['_SWITCHPORTSTATUS'].values_by_name["SWITCH_PORT_STATUS_UNKNOWN"]._serialized_options = b'\202\262\031\007unknown'
+ _globals['_SWITCHTYPE'].values_by_name["SWITCH_TYPE_LEAF"]._loaded_options = None
+ _globals['_SWITCHTYPE'].values_by_name["SWITCH_TYPE_LEAF"]._serialized_options = b'\202\262\031\004leaf'
+ _globals['_SWITCHTYPE'].values_by_name["SWITCH_TYPE_EXIT"]._loaded_options = None
+ _globals['_SWITCHTYPE'].values_by_name["SWITCH_TYPE_EXIT"]._serialized_options = b'\202\262\031\004exit'
+ _globals['_SWITCHTYPE'].values_by_name["SWITCH_TYPE_SPINE"]._loaded_options = None
+ _globals['_SWITCHTYPE'].values_by_name["SWITCH_TYPE_SPINE"]._serialized_options = b'\202\262\031\005spine'
+ _globals['_SWITCHTYPE'].values_by_name["SWITCH_TYPE_MGMTLEAF"]._loaded_options = None
+ _globals['_SWITCHTYPE'].values_by_name["SWITCH_TYPE_MGMTLEAF"]._serialized_options = b'\202\262\031\010mgmtleaf'
+ _globals['_SWITCHTYPE'].values_by_name["SWITCH_TYPE_MGMTSPINE"]._loaded_options = None
+ _globals['_SWITCHTYPE'].values_by_name["SWITCH_TYPE_MGMTSPINE"]._serialized_options = b'\202\262\031\tmgmtspine'
_globals['_SWITCH'].fields_by_name['id']._loaded_options = None
_globals['_SWITCH'].fields_by_name['id']._serialized_options = b'\272H\nr\010h\001\300\263\256\261\002\001'
_globals['_SWITCH'].fields_by_name['description']._loaded_options = None
@@ -78,6 +88,8 @@
_globals['_SWITCH'].fields_by_name['management_user']._serialized_options = b'\272H\007r\005\020\002\030\200\001'
_globals['_SWITCH'].fields_by_name['console_command']._loaded_options = None
_globals['_SWITCH'].fields_by_name['console_command']._serialized_options = b'\272H\007r\005\020\002\030\200\001'
+ _globals['_SWITCH'].fields_by_name['type']._loaded_options = None
+ _globals['_SWITCH'].fields_by_name['type']._serialized_options = b'\272H\005\202\001\002\020\001'
_globals['_SWITCHOS'].fields_by_name['vendor']._loaded_options = None
_globals['_SWITCHOS'].fields_by_name['vendor']._serialized_options = b'\272H\005\202\001\002\020\001'
_globals['_SWITCHOS'].fields_by_name['version']._loaded_options = None
@@ -118,30 +130,32 @@
_globals['_SWITCHOSQUERY'].fields_by_name['vendor']._serialized_options = b'\272H\005\202\001\002\020\001'
_globals['_SWITCHOSQUERY'].fields_by_name['version']._loaded_options = None
_globals['_SWITCHOSQUERY'].fields_by_name['version']._serialized_options = b'\272H\010r\006\300\263\256\261\002\001'
- _globals['_BGPSTATE']._serialized_start=2630
- _globals['_BGPSTATE']._serialized_end=2897
- _globals['_SWITCHREPLACEMODE']._serialized_start=2900
- _globals['_SWITCHREPLACEMODE']._serialized_end=3056
- _globals['_SWITCHOSVENDOR']._serialized_start=3059
- _globals['_SWITCHOSVENDOR']._serialized_end=3191
- _globals['_SWITCHPORTSTATUS']._serialized_start=3194
- _globals['_SWITCHPORTSTATUS']._serialized_end=3367
+ _globals['_BGPSTATE']._serialized_start=2691
+ _globals['_BGPSTATE']._serialized_end=2958
+ _globals['_SWITCHREPLACEMODE']._serialized_start=2961
+ _globals['_SWITCHREPLACEMODE']._serialized_end=3117
+ _globals['_SWITCHOSVENDOR']._serialized_start=3120
+ _globals['_SWITCHOSVENDOR']._serialized_end=3252
+ _globals['_SWITCHPORTSTATUS']._serialized_start=3255
+ _globals['_SWITCHPORTSTATUS']._serialized_end=3428
+ _globals['_SWITCHTYPE']._serialized_start=3431
+ _globals['_SWITCHTYPE']._serialized_end=3652
_globals['_SWITCH']._serialized_start=190
- _globals['_SWITCH']._serialized_end=878
- _globals['_SWITCHOS']._serialized_start=881
- _globals['_SWITCHOS']._serialized_end=1058
- _globals['_SWITCHNIC']._serialized_start=1061
- _globals['_SWITCHNIC']._serialized_end=1473
- _globals['_BGPFILTER']._serialized_start=1475
- _globals['_BGPFILTER']._serialized_end=1559
- _globals['_SWITCHBGPPORTSTATE']._serialized_start=1562
- _globals['_SWITCHBGPPORTSTATE']._serialized_end=1964
- _globals['_NICSTATE']._serialized_start=1967
- _globals['_NICSTATE']._serialized_end=2138
- _globals['_MACHINECONNECTION']._serialized_start=2140
- _globals['_MACHINECONNECTION']._serialized_end=2238
- _globals['_SWITCHQUERY']._serialized_start=2241
- _globals['_SWITCHQUERY']._serialized_end=2468
- _globals['_SWITCHOSQUERY']._serialized_start=2471
- _globals['_SWITCHOSQUERY']._serialized_end=2627
+ _globals['_SWITCH']._serialized_end=939
+ _globals['_SWITCHOS']._serialized_start=942
+ _globals['_SWITCHOS']._serialized_end=1119
+ _globals['_SWITCHNIC']._serialized_start=1122
+ _globals['_SWITCHNIC']._serialized_end=1534
+ _globals['_BGPFILTER']._serialized_start=1536
+ _globals['_BGPFILTER']._serialized_end=1620
+ _globals['_SWITCHBGPPORTSTATE']._serialized_start=1623
+ _globals['_SWITCHBGPPORTSTATE']._serialized_end=2025
+ _globals['_NICSTATE']._serialized_start=2028
+ _globals['_NICSTATE']._serialized_end=2199
+ _globals['_MACHINECONNECTION']._serialized_start=2201
+ _globals['_MACHINECONNECTION']._serialized_end=2299
+ _globals['_SWITCHQUERY']._serialized_start=2302
+ _globals['_SWITCHQUERY']._serialized_end=2529
+ _globals['_SWITCHOSQUERY']._serialized_start=2532
+ _globals['_SWITCHOSQUERY']._serialized_end=2688
# @@protoc_insertion_point(module_scope)
diff --git a/python/metalstack/api/v2/switch_pb2.pyi b/python/metalstack/api/v2/switch_pb2.pyi
index 3f89384a..3df2c25a 100644
--- a/python/metalstack/api/v2/switch_pb2.pyi
+++ b/python/metalstack/api/v2/switch_pb2.pyi
@@ -41,6 +41,15 @@ class SwitchPortStatus(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
SWITCH_PORT_STATUS_UP: _ClassVar[SwitchPortStatus]
SWITCH_PORT_STATUS_DOWN: _ClassVar[SwitchPortStatus]
SWITCH_PORT_STATUS_UNKNOWN: _ClassVar[SwitchPortStatus]
+
+class SwitchType(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
+ __slots__ = ()
+ SWITCH_TYPE_UNSPECIFIED: _ClassVar[SwitchType]
+ SWITCH_TYPE_LEAF: _ClassVar[SwitchType]
+ SWITCH_TYPE_EXIT: _ClassVar[SwitchType]
+ SWITCH_TYPE_SPINE: _ClassVar[SwitchType]
+ SWITCH_TYPE_MGMTLEAF: _ClassVar[SwitchType]
+ SWITCH_TYPE_MGMTSPINE: _ClassVar[SwitchType]
BGP_STATE_UNSPECIFIED: BGPState
BGP_STATE_IDLE: BGPState
BGP_STATE_CONNECT: BGPState
@@ -58,9 +67,15 @@ SWITCH_PORT_STATUS_UNSPECIFIED: SwitchPortStatus
SWITCH_PORT_STATUS_UP: SwitchPortStatus
SWITCH_PORT_STATUS_DOWN: SwitchPortStatus
SWITCH_PORT_STATUS_UNKNOWN: SwitchPortStatus
+SWITCH_TYPE_UNSPECIFIED: SwitchType
+SWITCH_TYPE_LEAF: SwitchType
+SWITCH_TYPE_EXIT: SwitchType
+SWITCH_TYPE_SPINE: SwitchType
+SWITCH_TYPE_MGMTLEAF: SwitchType
+SWITCH_TYPE_MGMTSPINE: SwitchType
class Switch(_message.Message):
- __slots__ = ("id", "meta", "description", "rack", "partition", "replace_mode", "management_ip", "management_user", "console_command", "nics", "os", "machine_connections")
+ __slots__ = ("id", "meta", "description", "rack", "partition", "replace_mode", "management_ip", "management_user", "console_command", "nics", "os", "machine_connections", "type")
ID_FIELD_NUMBER: _ClassVar[int]
META_FIELD_NUMBER: _ClassVar[int]
DESCRIPTION_FIELD_NUMBER: _ClassVar[int]
@@ -73,6 +88,7 @@ class Switch(_message.Message):
NICS_FIELD_NUMBER: _ClassVar[int]
OS_FIELD_NUMBER: _ClassVar[int]
MACHINE_CONNECTIONS_FIELD_NUMBER: _ClassVar[int]
+ TYPE_FIELD_NUMBER: _ClassVar[int]
id: str
meta: _common_pb2.Meta
description: str
@@ -85,7 +101,8 @@ class Switch(_message.Message):
nics: _containers.RepeatedCompositeFieldContainer[SwitchNic]
os: SwitchOS
machine_connections: _containers.RepeatedCompositeFieldContainer[MachineConnection]
- def __init__(self, id: _Optional[str] = ..., meta: _Optional[_Union[_common_pb2.Meta, _Mapping]] = ..., description: _Optional[str] = ..., rack: _Optional[str] = ..., partition: _Optional[str] = ..., replace_mode: _Optional[_Union[SwitchReplaceMode, str]] = ..., management_ip: _Optional[str] = ..., management_user: _Optional[str] = ..., console_command: _Optional[str] = ..., nics: _Optional[_Iterable[_Union[SwitchNic, _Mapping]]] = ..., os: _Optional[_Union[SwitchOS, _Mapping]] = ..., machine_connections: _Optional[_Iterable[_Union[MachineConnection, _Mapping]]] = ...) -> None: ...
+ type: SwitchType
+ def __init__(self, id: _Optional[str] = ..., meta: _Optional[_Union[_common_pb2.Meta, _Mapping]] = ..., description: _Optional[str] = ..., rack: _Optional[str] = ..., partition: _Optional[str] = ..., replace_mode: _Optional[_Union[SwitchReplaceMode, str]] = ..., management_ip: _Optional[str] = ..., management_user: _Optional[str] = ..., console_command: _Optional[str] = ..., nics: _Optional[_Iterable[_Union[SwitchNic, _Mapping]]] = ..., os: _Optional[_Union[SwitchOS, _Mapping]] = ..., machine_connections: _Optional[_Iterable[_Union[MachineConnection, _Mapping]]] = ..., type: _Optional[_Union[SwitchType, str]] = ...) -> None: ...
class SwitchOS(_message.Message):
__slots__ = ("vendor", "version", "metal_core_version")
diff --git a/python/metalstack/infra/v2/switch_connect.py b/python/metalstack/infra/v2/switch_connect.py
index 8f51f96a..b078b7fb 100644
--- a/python/metalstack/infra/v2/switch_connect.py
+++ b/python/metalstack/infra/v2/switch_connect.py
@@ -25,6 +25,9 @@ async def register(self, request: metalstack_dot_infra_dot_v2_dot_switch__pb2.Sw
async def heartbeat(self, request: metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceHeartbeatRequest, ctx: RequestContext) -> metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceHeartbeatResponse:
raise ConnectError(Code.UNIMPLEMENTED, "Not implemented")
+ async def report_b_g_p_routes(self, request: metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceReportBGPRoutesRequest, ctx: RequestContext) -> metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceReportBGPRoutesResponse:
+ raise ConnectError(Code.UNIMPLEMENTED, "Not implemented")
+
class SwitchServiceASGIApplication(ConnectASGIApplication):
def __init__(self, service: SwitchService, *, interceptors: Iterable[Interceptor]=(), read_max_bytes: int | None = None) -> None:
@@ -60,6 +63,16 @@ def __init__(self, service: SwitchService, *, interceptors: Iterable[Interceptor
),
function=service.heartbeat,
),
+ "/metalstack.infra.v2.SwitchService/ReportBGPRoutes": Endpoint.unary(
+ method=MethodInfo(
+ name="ReportBGPRoutes",
+ service_name="metalstack.infra.v2.SwitchService",
+ input=metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceReportBGPRoutesRequest,
+ output=metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceReportBGPRoutesResponse,
+ idempotency_level=IdempotencyLevel.UNKNOWN,
+ ),
+ function=service.report_b_g_p_routes,
+ ),
},
interceptors=interceptors,
read_max_bytes=read_max_bytes,
@@ -132,6 +145,26 @@ async def heartbeat(
timeout_ms=timeout_ms,
)
+ async def report_b_g_p_routes(
+ self,
+ request: metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceReportBGPRoutesRequest,
+ *,
+ headers: Headers | Mapping[str, str] | None = None,
+ timeout_ms: int | None = None,
+ ) -> metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceReportBGPRoutesResponse:
+ return await self.execute_unary(
+ request=request,
+ method=MethodInfo(
+ name="ReportBGPRoutes",
+ service_name="metalstack.infra.v2.SwitchService",
+ input=metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceReportBGPRoutesRequest,
+ output=metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceReportBGPRoutesResponse,
+ idempotency_level=IdempotencyLevel.UNKNOWN,
+ ),
+ headers=headers,
+ timeout_ms=timeout_ms,
+ )
+
class SwitchServiceSync(Protocol):
def get(self, request: metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceGetRequest, ctx: RequestContext) -> metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceGetResponse:
@@ -140,6 +173,8 @@ def register(self, request: metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchSe
raise ConnectError(Code.UNIMPLEMENTED, "Not implemented")
def heartbeat(self, request: metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceHeartbeatRequest, ctx: RequestContext) -> metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceHeartbeatResponse:
raise ConnectError(Code.UNIMPLEMENTED, "Not implemented")
+ def report_b_g_p_routes(self, request: metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceReportBGPRoutesRequest, ctx: RequestContext) -> metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceReportBGPRoutesResponse:
+ raise ConnectError(Code.UNIMPLEMENTED, "Not implemented")
class SwitchServiceWSGIApplication(ConnectWSGIApplication):
@@ -176,6 +211,16 @@ def __init__(self, service: SwitchServiceSync, interceptors: Iterable[Intercepto
),
function=service.heartbeat,
),
+ "/metalstack.infra.v2.SwitchService/ReportBGPRoutes": EndpointSync.unary(
+ method=MethodInfo(
+ name="ReportBGPRoutes",
+ service_name="metalstack.infra.v2.SwitchService",
+ input=metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceReportBGPRoutesRequest,
+ output=metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceReportBGPRoutesResponse,
+ idempotency_level=IdempotencyLevel.UNKNOWN,
+ ),
+ function=service.report_b_g_p_routes,
+ ),
},
interceptors=interceptors,
read_max_bytes=read_max_bytes,
@@ -247,3 +292,23 @@ def heartbeat(
headers=headers,
timeout_ms=timeout_ms,
)
+
+ def report_b_g_p_routes(
+ self,
+ request: metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceReportBGPRoutesRequest,
+ *,
+ headers: Headers | Mapping[str, str] | None = None,
+ timeout_ms: int | None = None,
+ ) -> metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceReportBGPRoutesResponse:
+ return self.execute_unary(
+ request=request,
+ method=MethodInfo(
+ name="ReportBGPRoutes",
+ service_name="metalstack.infra.v2.SwitchService",
+ input=metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceReportBGPRoutesRequest,
+ output=metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceReportBGPRoutesResponse,
+ idempotency_level=IdempotencyLevel.UNKNOWN,
+ ),
+ headers=headers,
+ timeout_ms=timeout_ms,
+ )
diff --git a/python/metalstack/infra/v2/switch_pb2.py b/python/metalstack/infra/v2/switch_pb2.py
index 1eaecea0..faed1fb6 100644
--- a/python/metalstack/infra/v2/switch_pb2.py
+++ b/python/metalstack/infra/v2/switch_pb2.py
@@ -30,7 +30,7 @@
from metalstack.api.v2 import switch_pb2 as metalstack_dot_api_dot_v2_dot_switch__pb2
-DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n metalstack/infra/v2/switch.proto\x12\x13metalstack.infra.v2\x1a\x1b\x62uf/validate/validate.proto\x1a\x1egoogle/protobuf/duration.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1emetalstack/api/v2/common.proto\x1a(metalstack/api/v2/predefined_rules.proto\x1a\x1emetalstack/api/v2/switch.proto\"8\n\x17SwitchServiceGetRequest\x12\x1d\n\x02id\x18\x01 \x01(\tB\r\xbaH\nr\x08h\x01\xc0\xb3\xae\xb1\x02\x01R\x02id\"M\n\x18SwitchServiceGetResponse\x12\x31\n\x06switch\x18\x01 \x01(\x0b\x32\x19.metalstack.api.v2.SwitchR\x06switch\"Q\n\x1cSwitchServiceRegisterRequest\x12\x31\n\x06switch\x18\x01 \x01(\x0b\x32\x19.metalstack.api.v2.SwitchR\x06switch\"R\n\x1dSwitchServiceRegisterResponse\x12\x31\n\x06switch\x18\x01 \x01(\x0b\x32\x19.metalstack.api.v2.SwitchR\x06switch\"\xbb\x04\n\x1dSwitchServiceHeartbeatRequest\x12\x1d\n\x02id\x18\x01 \x01(\tB\r\xbaH\nr\x08h\x01\xc0\xb3\xae\xb1\x02\x01R\x02id\x12\x35\n\x08\x64uration\x18\x02 \x01(\x0b\x32\x19.google.protobuf.DurationR\x08\x64uration\x12\x19\n\x05\x65rror\x18\x03 \x01(\tH\x00R\x05\x65rror\x88\x01\x01\x12\x63\n\x0bport_states\x18\x04 \x03(\x0b\x32\x42.metalstack.infra.v2.SwitchServiceHeartbeatRequest.PortStatesEntryR\nportStates\x12m\n\x0f\x62gp_port_states\x18\x05 \x03(\x0b\x32\x45.metalstack.infra.v2.SwitchServiceHeartbeatRequest.BgpPortStatesEntryR\rbgpPortStates\x1a\x62\n\x0fPortStatesEntry\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\x39\n\x05value\x18\x02 \x01(\x0e\x32#.metalstack.api.v2.SwitchPortStatusR\x05value:\x02\x38\x01\x1ag\n\x12\x42gpPortStatesEntry\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12;\n\x05value\x18\x02 \x01(\x0b\x32%.metalstack.api.v2.SwitchBGPPortStateR\x05value:\x02\x38\x01\x42\x08\n\x06_error\"\xb7\x01\n\x1eSwitchServiceHeartbeatResponse\x12\x0e\n\x02id\x18\x01 \x01(\tR\x02id\x12<\n\tlast_sync\x18\x02 \x01(\x0b\x32\x1f.metalstack.infra.v2.SwitchSyncR\x08lastSync\x12G\n\x0flast_sync_error\x18\x03 \x01(\x0b\x32\x1f.metalstack.infra.v2.SwitchSyncR\rlastSyncError\"\x98\x01\n\nSwitchSync\x12.\n\x04time\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\x04time\x12\x35\n\x08\x64uration\x18\x02 \x01(\x0b\x32\x19.google.protobuf.DurationR\x08\x64uration\x12\x19\n\x05\x65rror\x18\x03 \x01(\tH\x00R\x05\x65rror\x88\x01\x01\x42\x08\n\x06_error2\xfe\x02\n\rSwitchService\x12n\n\x03Get\x12,.metalstack.infra.v2.SwitchServiceGetRequest\x1a-.metalstack.infra.v2.SwitchServiceGetResponse\"\n\xe0\xf3\x18\x02\xea\xf3\x18\x02\x01\x02\x12|\n\x08Register\x12\x31.metalstack.infra.v2.SwitchServiceRegisterRequest\x1a\x32.metalstack.infra.v2.SwitchServiceRegisterResponse\"\t\xe0\xf3\x18\x02\xea\xf3\x18\x01\x01\x12\x7f\n\tHeartbeat\x12\x32.metalstack.infra.v2.SwitchServiceHeartbeatRequest\x1a\x33.metalstack.infra.v2.SwitchServiceHeartbeatResponse\"\t\xe0\xf3\x18\x02\xea\xf3\x18\x01\x01\x42\xcf\x01\n\x17\x63om.metalstack.infra.v2B\x0bSwitchProtoP\x01Z9github.com/metal-stack/api/go/metalstack/infra/v2;infrav2\xa2\x02\x03MIX\xaa\x02\x13Metalstack.Infra.V2\xca\x02\x13Metalstack\\Infra\\V2\xe2\x02\x1fMetalstack\\Infra\\V2\\GPBMetadata\xea\x02\x15Metalstack::Infra::V2b\x06proto3')
+DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n metalstack/infra/v2/switch.proto\x12\x13metalstack.infra.v2\x1a\x1b\x62uf/validate/validate.proto\x1a\x1egoogle/protobuf/duration.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1emetalstack/api/v2/common.proto\x1a(metalstack/api/v2/predefined_rules.proto\x1a\x1emetalstack/api/v2/switch.proto\"8\n\x17SwitchServiceGetRequest\x12\x1d\n\x02id\x18\x01 \x01(\tB\r\xbaH\nr\x08h\x01\xc0\xb3\xae\xb1\x02\x01R\x02id\"M\n\x18SwitchServiceGetResponse\x12\x31\n\x06switch\x18\x01 \x01(\x0b\x32\x19.metalstack.api.v2.SwitchR\x06switch\"Q\n\x1cSwitchServiceRegisterRequest\x12\x31\n\x06switch\x18\x01 \x01(\x0b\x32\x19.metalstack.api.v2.SwitchR\x06switch\"R\n\x1dSwitchServiceRegisterResponse\x12\x31\n\x06switch\x18\x01 \x01(\x0b\x32\x19.metalstack.api.v2.SwitchR\x06switch\"\x8e\x01\n#SwitchServiceReportBGPRoutesRequest\x12)\n\tswitch_id\x18\x01 \x01(\tB\x0c\xbaH\tr\x07\x10\x02\x18\x80\x01h\x01R\x08switchId\x12<\n\nbgp_routes\x18\x02 \x03(\x0b\x32\x1d.metalstack.infra.v2.BGPRouteR\tbgpRoutes\"&\n$SwitchServiceReportBGPRoutesResponse\"c\n\x08\x42GPRoute\x12\x12\n\x04\x63idr\x18\x01 \x01(\tR\x04\x63idr:C\xbaH@\x1a>\n\x04\x63idr\x12\x1e\x63idr must be a valid ip prefix\x1a\x16this.cidr.isIpPrefix()\"\xbb\x04\n\x1dSwitchServiceHeartbeatRequest\x12\x1d\n\x02id\x18\x01 \x01(\tB\r\xbaH\nr\x08h\x01\xc0\xb3\xae\xb1\x02\x01R\x02id\x12\x35\n\x08\x64uration\x18\x02 \x01(\x0b\x32\x19.google.protobuf.DurationR\x08\x64uration\x12\x19\n\x05\x65rror\x18\x03 \x01(\tH\x00R\x05\x65rror\x88\x01\x01\x12\x63\n\x0bport_states\x18\x04 \x03(\x0b\x32\x42.metalstack.infra.v2.SwitchServiceHeartbeatRequest.PortStatesEntryR\nportStates\x12m\n\x0f\x62gp_port_states\x18\x05 \x03(\x0b\x32\x45.metalstack.infra.v2.SwitchServiceHeartbeatRequest.BgpPortStatesEntryR\rbgpPortStates\x1a\x62\n\x0fPortStatesEntry\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\x39\n\x05value\x18\x02 \x01(\x0e\x32#.metalstack.api.v2.SwitchPortStatusR\x05value:\x02\x38\x01\x1ag\n\x12\x42gpPortStatesEntry\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12;\n\x05value\x18\x02 \x01(\x0b\x32%.metalstack.api.v2.SwitchBGPPortStateR\x05value:\x02\x38\x01\x42\x08\n\x06_error\"\xb7\x01\n\x1eSwitchServiceHeartbeatResponse\x12\x0e\n\x02id\x18\x01 \x01(\tR\x02id\x12<\n\tlast_sync\x18\x02 \x01(\x0b\x32\x1f.metalstack.infra.v2.SwitchSyncR\x08lastSync\x12G\n\x0flast_sync_error\x18\x03 \x01(\x0b\x32\x1f.metalstack.infra.v2.SwitchSyncR\rlastSyncError\"\x98\x01\n\nSwitchSync\x12.\n\x04time\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\x04time\x12\x35\n\x08\x64uration\x18\x02 \x01(\x0b\x32\x19.google.protobuf.DurationR\x08\x64uration\x12\x19\n\x05\x65rror\x18\x03 \x01(\tH\x00R\x05\x65rror\x88\x01\x01\x42\x08\n\x06_error2\x8f\x04\n\rSwitchService\x12n\n\x03Get\x12,.metalstack.infra.v2.SwitchServiceGetRequest\x1a-.metalstack.infra.v2.SwitchServiceGetResponse\"\n\xe0\xf3\x18\x02\xea\xf3\x18\x02\x01\x02\x12|\n\x08Register\x12\x31.metalstack.infra.v2.SwitchServiceRegisterRequest\x1a\x32.metalstack.infra.v2.SwitchServiceRegisterResponse\"\t\xe0\xf3\x18\x02\xea\xf3\x18\x01\x01\x12\x7f\n\tHeartbeat\x12\x32.metalstack.infra.v2.SwitchServiceHeartbeatRequest\x1a\x33.metalstack.infra.v2.SwitchServiceHeartbeatResponse\"\t\xe0\xf3\x18\x02\xea\xf3\x18\x01\x01\x12\x8e\x01\n\x0fReportBGPRoutes\x12\x38.metalstack.infra.v2.SwitchServiceReportBGPRoutesRequest\x1a\x39.metalstack.infra.v2.SwitchServiceReportBGPRoutesResponse\"\x06\xea\xf3\x18\x02\x01\x02\x42\xcf\x01\n\x17\x63om.metalstack.infra.v2B\x0bSwitchProtoP\x01Z9github.com/metal-stack/api/go/metalstack/infra/v2;infrav2\xa2\x02\x03MIX\xaa\x02\x13Metalstack.Infra.V2\xca\x02\x13Metalstack\\Infra\\V2\xe2\x02\x1fMetalstack\\Infra\\V2\\GPBMetadata\xea\x02\x15Metalstack::Infra::V2b\x06proto3')
_globals = globals()
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
@@ -40,6 +40,10 @@
_globals['DESCRIPTOR']._serialized_options = b'\n\027com.metalstack.infra.v2B\013SwitchProtoP\001Z9github.com/metal-stack/api/go/metalstack/infra/v2;infrav2\242\002\003MIX\252\002\023Metalstack.Infra.V2\312\002\023Metalstack\\Infra\\V2\342\002\037Metalstack\\Infra\\V2\\GPBMetadata\352\002\025Metalstack::Infra::V2'
_globals['_SWITCHSERVICEGETREQUEST'].fields_by_name['id']._loaded_options = None
_globals['_SWITCHSERVICEGETREQUEST'].fields_by_name['id']._serialized_options = b'\272H\nr\010h\001\300\263\256\261\002\001'
+ _globals['_SWITCHSERVICEREPORTBGPROUTESREQUEST'].fields_by_name['switch_id']._loaded_options = None
+ _globals['_SWITCHSERVICEREPORTBGPROUTESREQUEST'].fields_by_name['switch_id']._serialized_options = b'\272H\tr\007\020\002\030\200\001h\001'
+ _globals['_BGPROUTE']._loaded_options = None
+ _globals['_BGPROUTE']._serialized_options = b'\272H@\032>\n\004cidr\022\036cidr must be a valid ip prefix\032\026this.cidr.isIpPrefix()'
_globals['_SWITCHSERVICEHEARTBEATREQUEST_PORTSTATESENTRY']._loaded_options = None
_globals['_SWITCHSERVICEHEARTBEATREQUEST_PORTSTATESENTRY']._serialized_options = b'8\001'
_globals['_SWITCHSERVICEHEARTBEATREQUEST_BGPPORTSTATESENTRY']._loaded_options = None
@@ -52,6 +56,8 @@
_globals['_SWITCHSERVICE'].methods_by_name['Register']._serialized_options = b'\340\363\030\002\352\363\030\001\001'
_globals['_SWITCHSERVICE'].methods_by_name['Heartbeat']._loaded_options = None
_globals['_SWITCHSERVICE'].methods_by_name['Heartbeat']._serialized_options = b'\340\363\030\002\352\363\030\001\001'
+ _globals['_SWITCHSERVICE'].methods_by_name['ReportBGPRoutes']._loaded_options = None
+ _globals['_SWITCHSERVICE'].methods_by_name['ReportBGPRoutes']._serialized_options = b'\352\363\030\002\001\002'
_globals['_SWITCHSERVICEGETREQUEST']._serialized_start=257
_globals['_SWITCHSERVICEGETREQUEST']._serialized_end=313
_globals['_SWITCHSERVICEGETRESPONSE']._serialized_start=315
@@ -60,16 +66,22 @@
_globals['_SWITCHSERVICEREGISTERREQUEST']._serialized_end=475
_globals['_SWITCHSERVICEREGISTERRESPONSE']._serialized_start=477
_globals['_SWITCHSERVICEREGISTERRESPONSE']._serialized_end=559
- _globals['_SWITCHSERVICEHEARTBEATREQUEST']._serialized_start=562
- _globals['_SWITCHSERVICEHEARTBEATREQUEST']._serialized_end=1133
- _globals['_SWITCHSERVICEHEARTBEATREQUEST_PORTSTATESENTRY']._serialized_start=920
- _globals['_SWITCHSERVICEHEARTBEATREQUEST_PORTSTATESENTRY']._serialized_end=1018
- _globals['_SWITCHSERVICEHEARTBEATREQUEST_BGPPORTSTATESENTRY']._serialized_start=1020
- _globals['_SWITCHSERVICEHEARTBEATREQUEST_BGPPORTSTATESENTRY']._serialized_end=1123
- _globals['_SWITCHSERVICEHEARTBEATRESPONSE']._serialized_start=1136
- _globals['_SWITCHSERVICEHEARTBEATRESPONSE']._serialized_end=1319
- _globals['_SWITCHSYNC']._serialized_start=1322
- _globals['_SWITCHSYNC']._serialized_end=1474
- _globals['_SWITCHSERVICE']._serialized_start=1477
- _globals['_SWITCHSERVICE']._serialized_end=1859
+ _globals['_SWITCHSERVICEREPORTBGPROUTESREQUEST']._serialized_start=562
+ _globals['_SWITCHSERVICEREPORTBGPROUTESREQUEST']._serialized_end=704
+ _globals['_SWITCHSERVICEREPORTBGPROUTESRESPONSE']._serialized_start=706
+ _globals['_SWITCHSERVICEREPORTBGPROUTESRESPONSE']._serialized_end=744
+ _globals['_BGPROUTE']._serialized_start=746
+ _globals['_BGPROUTE']._serialized_end=845
+ _globals['_SWITCHSERVICEHEARTBEATREQUEST']._serialized_start=848
+ _globals['_SWITCHSERVICEHEARTBEATREQUEST']._serialized_end=1419
+ _globals['_SWITCHSERVICEHEARTBEATREQUEST_PORTSTATESENTRY']._serialized_start=1206
+ _globals['_SWITCHSERVICEHEARTBEATREQUEST_PORTSTATESENTRY']._serialized_end=1304
+ _globals['_SWITCHSERVICEHEARTBEATREQUEST_BGPPORTSTATESENTRY']._serialized_start=1306
+ _globals['_SWITCHSERVICEHEARTBEATREQUEST_BGPPORTSTATESENTRY']._serialized_end=1409
+ _globals['_SWITCHSERVICEHEARTBEATRESPONSE']._serialized_start=1422
+ _globals['_SWITCHSERVICEHEARTBEATRESPONSE']._serialized_end=1605
+ _globals['_SWITCHSYNC']._serialized_start=1608
+ _globals['_SWITCHSYNC']._serialized_end=1760
+ _globals['_SWITCHSERVICE']._serialized_start=1763
+ _globals['_SWITCHSERVICE']._serialized_end=2290
# @@protoc_insertion_point(module_scope)
diff --git a/python/metalstack/infra/v2/switch_pb2.pyi b/python/metalstack/infra/v2/switch_pb2.pyi
index 4da9f80f..6085875c 100644
--- a/python/metalstack/infra/v2/switch_pb2.pyi
+++ b/python/metalstack/infra/v2/switch_pb2.pyi
@@ -9,7 +9,7 @@ from metalstack.api.v2 import switch_pb2 as _switch_pb2
from google.protobuf.internal import containers as _containers
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
-from collections.abc import Mapping as _Mapping
+from collections.abc import Iterable as _Iterable, Mapping as _Mapping
from typing import ClassVar as _ClassVar, Optional as _Optional, Union as _Union
DESCRIPTOR: _descriptor.FileDescriptor
@@ -38,6 +38,24 @@ class SwitchServiceRegisterResponse(_message.Message):
switch: _switch_pb2.Switch
def __init__(self, switch: _Optional[_Union[_switch_pb2.Switch, _Mapping]] = ...) -> None: ...
+class SwitchServiceReportBGPRoutesRequest(_message.Message):
+ __slots__ = ("switch_id", "bgp_routes")
+ SWITCH_ID_FIELD_NUMBER: _ClassVar[int]
+ BGP_ROUTES_FIELD_NUMBER: _ClassVar[int]
+ switch_id: str
+ bgp_routes: _containers.RepeatedCompositeFieldContainer[BGPRoute]
+ def __init__(self, switch_id: _Optional[str] = ..., bgp_routes: _Optional[_Iterable[_Union[BGPRoute, _Mapping]]] = ...) -> None: ...
+
+class SwitchServiceReportBGPRoutesResponse(_message.Message):
+ __slots__ = ()
+ def __init__(self) -> None: ...
+
+class BGPRoute(_message.Message):
+ __slots__ = ("cidr",)
+ CIDR_FIELD_NUMBER: _ClassVar[int]
+ cidr: str
+ def __init__(self, cidr: _Optional[str] = ...) -> None: ...
+
class SwitchServiceHeartbeatRequest(_message.Message):
__slots__ = ("id", "duration", "error", "port_states", "bgp_port_states")
class PortStatesEntry(_message.Message):