From 4eb1bed9b55cab91814f118ee4a2057479ed4826 Mon Sep 17 00:00:00 2001 From: Ilja Rotar Date: Wed, 18 Jun 2025 15:04:07 +0200 Subject: [PATCH 1/8] Add infra switch service and basic switch types for api v2 --- proto/metalstack/api/v2/switch.proto | 198 +++++++++++++++++++++++++ proto/metalstack/infra/v2/switch.proto | 59 ++++++++ 2 files changed, 257 insertions(+) create mode 100644 proto/metalstack/api/v2/switch.proto create mode 100644 proto/metalstack/infra/v2/switch.proto diff --git a/proto/metalstack/api/v2/switch.proto b/proto/metalstack/api/v2/switch.proto new file mode 100644 index 00000000..4a1ef63a --- /dev/null +++ b/proto/metalstack/api/v2/switch.proto @@ -0,0 +1,198 @@ +syntax = "proto3"; + +package metalstack.api.v2; + +import "buf/validate/validate.proto"; + +// Switch represents a network switch +message Switch { + // ID of the switch + string id = 1 [(buf.validate.field).string = { + hostname: true + min_len: 2 + max_len: 128 + }]; + // Description of the switch + string description = 2 [(buf.validate.field).string = { + min_len: 2 + max_len: 128 + }]; + // Rack ID if the switch resides in a rack + optional string rack_id = 3 [(buf.validate.field).string = { + min_len: 2 + max_len: 128 + }]; + // Partition ID of the partition the switch belongs to + string partition_id = 4 [(buf.validate.field).string = { + min_len: 2 + max_len: 128 + }]; + // Type signifies what role a switch has, e.g. whether it is a leaf switch, or a spine, etc. + SwitchType type = 5 [(buf.validate.field).enum.defined_only = true]; + // Replace mode is used to mark a switch ready for replacement + SwitchReplaceMode replace_mode = 6 [(buf.validate.field).enum.defined_only = true]; + // Management IP is the switch's IP for management access + string management_ip = 7 [(buf.validate.field).string.ip = true]; + // Management user is the user name to use for management access + string management_user = 8 [(buf.validate.field).string = { + min_len: 2 + max_len: 128 + }]; + // Console command is the command for accessing the switch's console + string console_command = 9 [(buf.validate.field).string = { + min_len: 2 + max_len: 128 + }]; + // Switch NICs are the front panel ports of the switch + repeated SwitchNic switch_nics = 10; +} + +// SwitchOS holds information about the NOS and versions running on the switch +message SwitchOS { + // Switch OS vendor identifies what NOS distribution is running on the switch, e.g. SONiC + SwitchOSVendor vendor = 1 [(buf.validate.field).enum.defined_only = true]; + // Version specifies what NOS version is currently installed on the switch + string version = 2 [(buf.validate.field).string = { + min_len: 2 + max_len: 128 + }]; + // Metal core version is the currently running version of the metal-core + string metal_core_version = 3 [(buf.validate.field).string = { + min_len: 2 + max_len: 128 + }]; +} + +// SwitchNic represents a front panel port and its configuration +message SwitchNic { + // Name of the switch port + string name = 1 [(buf.validate.field).string = { + min_len: 2 + max_len: 128 + }]; + // Identifier of the port + string identifier = 2 [(buf.validate.field).string = { + min_len: 2 + max_len: 128 + }]; + // MAC address of the port + string mac_address = 3 [(validate.rules).string.pattern = "^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$"]; + // VRF name if the port is bound in one + optional string vrf = 4 [(buf.validate.field).string = { + min_len: 2 + max_len: 128 + }]; + // Actual port status + SwitchPortStatus actual = 5 [(buf.validate.field).enum.defined_only = true]; + // BGP filter optionally configured on a port + optional BGPFilter bgp_filter = 6; + // BGP port state represents the current BGP status of the port + optional SwitchBGPPortState bgp_port_state = 7; +} + +// BGP filter can be used to restrict BGP based on CIDRs and VNIs +message BGPFilter { + // CIDRs for which to allow BGP + repeated string cidrs = 1; + option (buf.validate.message).cel = { + id: "cidrs" + message: "given cidrs must be valid" + expression: "this.cidrs.all(m, m.isIpPrefix())" + }; + // VNIs for which to allow BGP + repeated string vnis = 2 [(buf.validate.field).string = { + min_len: 2 + max_len: 128 + }]; +} + +// SwitchBGPPortState holds information about the BGP state of a port +message SwitchBGPPortState { + // Neighbor of this port + string neighbor = 1 [(buf.validate.field).string = { + min_len: 2 + max_len: 128 + }]; + // Peer group of this port + string peer_group = 2 [(buf.validate.field).string = { + min_len: 2 + max_len: 128 + }]; + // VRF name of the VRF this port is bound to + string vrf_name = 3 [(buf.validate.field).string = { + min_len: 2 + max_len: 128 + }]; + // BGP state of the connection on this port + BGPState bgp_state = 4 [(buf.validate.field).enum.defined_only = true]; + // BGP timer up established reports the uptime of this port's BGP connection + uint64 bgp_timer_up_established = 5; + // Sent prefix counter counts the prefixes sent by the switch on this port + uint64 sent_prefix_counter = 6; + // Accepted prefix counter counts the prefixes received on this port + uint64 accepted_prefix_counter = 7; +} + +// BGPState represents the state of a BGP session +enum BGPState { + // BGP_STATE_UNSPECIFIED is not specified + BGP_STATE_UNSPECIFIED = 0; + // BGP_STATE_IDLE is the Idle state of a BGP session + BGP_STATE_IDLE = 1 [(enum_string_value) = "idle"]; + // BGP_STATE_CONNECT is the Connect state of a BGP session + BGP_STATE_CONNECT = 2 [(enum_string_value) = "connect"]; + // BGP_STATE_ACTIVE is the Active state of a BGP session + BGP_STATE_ACTIVE = 3 [(enum_string_value) = "active"]; + // BGP_STATE_OPEN_SENT is the OpenSent state of a BGP session + BGP_STATE_OPEN_SENT = 4 [(enum_string_value) = "open-sent"]; + // BGP_STATE_OPEN_CONFIRM is the OpenConfirm state of a BGP session + BGP_STATE_OPEN_CONFIRM = 5 [(enum_string_value) = "open-confirm"]; + // BGP_STATE_ESTABLISHED is the Established state of a BGP session + BGP_STATE_ESTABLISHED = 6 [(enum_string_value) = "established"]; +} + +// SwitchReplaceMode is used to mark a switch ready for replacement +enum SwitchReplaceMode { + // SWITCH_REPLACE_MODE_UNSPECIFIED is not specified + SWITCH_REPLACE_MODE_UNSPECIFIED = 0; + // SWITCH_REPLACE_MODE_REPLACE means this switch is waiting to be replaced + SWITCH_REPLACE_MODE_REPLACE = 1 [(enum_string_value) = "replace"]; + // SWITCH_REPLACE_MODE_OPERATIONAL means this switch is operational and cannot be replaced + SWITCH_REPLACE_MODE_OPERATIONAL = 2 [(enum_string_value) = "operational"]; +} + +// SwitchOSVendor represents a NOS distribution +enum SwitchOSVendor { + // SWITCH_OS_VENDOR_UNSPECIFIED is not specified + SWITCH_OS_VENDOR_UNSPECIFIED = 0; + // SWITCH_OS_VENDOR_CUMULUS means this switch is running on Cumulus Linux + SWITCH_OS_VENDOR_CUMULUS = 1 [(enum_string_value) = "cumulus"]; + // SWITCH_OS_VENDOR_SONIC means this switch is running on SONiC NOS + SWITCH_OS_VENDOR_SONIC = 2 [(enum_string_value) = "sonic"]; +} + +// SwitchPortStatus specifies the state of a switch port +enum SwitchPortStatus { + // SWITCH_PORT_STATUS_UNSPECIFIED is not specified + SWITCH_PORT_STATUS_UNSPECIFED = 0; + // SWITCH_PORT_STATUS_UP means this port is up + SWITCH_PORT_STATUS_UP = 1 [(enum_string_value) = "up"]; + // SWITCH_PORT_STATUS_DOWN means this port is down + SWITCH_PORT_STATUS_DOWN = 2 [(enum_string_value) = "down"]; +} + +// SwitchType represents the role of a switch +enum SwitchType { + // SWITCH_TYPE_UNSPECIFIED is not specified + SWITCH_TYPE_UNSPECIFIED = 0; + // SWITCH_TYPE_LEAF is a leaf switch + SWITCH_TYPE_LEAF = 1 [(enum_string_value) = "leaf"]; + // SWITCH_TYPE_EXIT is an exit switch + SWITCH_TYPE_EXIT = 2 [(enum_string_value) = "exit"]; + // SWITCH_TYPE_SPINE is a spine switch + SWITCH_TYPE_SPINE = 3 [(enum_string_value) = "spine"]; + // SWITCH_TYPE_MGMTLEAF is a special type of leaf used only for management tasks + SWITCH_TYPE_MGMTLEAF = 4 [(enum_string_value) = "mgmtleaf"]; + // SWITCH_TYPE_MGMTSPINE is a special type of spine used only for management tasks + SWITCH_TYPE_MGMTSPINE = 5 [(enum_string_value) = "mgmtspine"]; +} diff --git a/proto/metalstack/infra/v2/switch.proto b/proto/metalstack/infra/v2/switch.proto new file mode 100644 index 00000000..0d5eca81 --- /dev/null +++ b/proto/metalstack/infra/v2/switch.proto @@ -0,0 +1,59 @@ +syntax = "proto3"; + +package metalstack.infra.v2; + +import "metalstack/api/v2/common.proto"; + +// SwitchService serves switch related functions +service SwitchService { + // Register a switch + rpc Register(SwitchServiceRegisterRequest) returns (SwitchServiceRegisterResponse) { + option (metalstack.api.v2.infra_roles) = INFRA_ROLE_EDITOR; + option (metalstack.api.v2.infra_roles) = INFRA_ROLE_VIEWER; + option (metalstack.api.v2.auditing) = AUDITING_EXCLUDED; + } + // Report BGP routes of a switch + rpc ReportBGPRoutes(SwitchServiceReportBGPRoutesRequest) returns (SwitchServiceReportBGPRoutesResponse) { + option (metalstack.api.v2.infra_roles) = INFRA_ROLE_EDITOR; + option (metalstack.api.v2.infra_roles) = INFRA_ROLE_VIEWER; + option (metalstack.api.v2.auditing) = AUDITING_EXCLUDED; + } +} + +// SwitchServiceRegisterRequest +message SwitchServiceRegisterRequest { + // Switch to register + metalstack.api.v2.Switch switch = 1; +} + +// SwitchServiceRegisterResponse +message SwitchServiceRegisterResponse { + // Switch that was registered + metalstack.api.v2.Switch switch = 1; +} + +// SwitchServiceReportBGPRoutesRequest +message SwitchServiceReportBGPRoutesRequest { + // Switch ID of the switch that reports its routes + string switch_id = 1 [(buf.validate.field).string = { + hostname: true + min_len: 2 + max_len: 128 + }]; + // BGP routes collected on the switch + repeated BGPRoute bgpRoutes = 2; +} + +// SwitchServiceReportBGPRoutesResponse +message SwitchServiceReportBGPRoutesResponse {} + +// BGPRoute represents the route to a prefix +message BGPRoute { + // CIDR of the network that is routed to + string cidr = 1; + option (buf.validate.message).cel = { + id: "cidr" + message: "cidr must be a valid ip prefix" + expression: "this.cidr.isIpPrefix()" + }; +} From 9582ceae92be8bf34690a0ada85d4148fa906711 Mon Sep 17 00:00:00 2001 From: Ilja Rotar Date: Wed, 18 Jun 2025 15:31:30 +0200 Subject: [PATCH 2/8] add tests for mac validation --- doc/index.html | 911 +++++++++++++++-- go/client/client.go | 12 +- go/metalstack/api/v2/switch.pb.go | 928 ++++++++++++++++++ .../infra/v2/infrav2connect/switch.connect.go | 141 +++ go/metalstack/infra/v2/switch.pb.go | 338 +++++++ go/permissions/servicepermissions.go | 13 +- go/tests/mock_clients.go | 15 +- .../v2/infrav2connect/SwitchServiceClient.go | 92 ++ .../v2/infrav2connect/SwitchServiceHandler.go | 92 ++ go/tests/validation/switch_test.go | 78 ++ proto/metalstack/api/v2/switch.proto | 7 +- proto/metalstack/infra/v2/switch.proto | 4 +- 12 files changed, 2527 insertions(+), 104 deletions(-) create mode 100644 go/metalstack/api/v2/switch.pb.go create mode 100644 go/metalstack/infra/v2/infrav2connect/switch.connect.go create mode 100644 go/metalstack/infra/v2/switch.pb.go create mode 100644 go/tests/mocks/metalstack/infra/v2/infrav2connect/SwitchServiceClient.go create mode 100644 go/tests/mocks/metalstack/infra/v2/infrav2connect/SwitchServiceHandler.go create mode 100644 go/tests/validation/switch_test.go diff --git a/doc/index.html b/doc/index.html index b0223a0a..4cbf7d5f 100644 --- a/doc/index.html +++ b/doc/index.html @@ -1340,6 +1340,57 @@

Table of Contents

+
  • + metalstack/api/v2/switch.proto + +
  • + +
  • metalstack/api/v2/user.proto
      @@ -1416,6 +1467,41 @@

      Table of Contents

  • + +
  • + metalstack/infra/v2/switch.proto + +
  • +
  • Scalar Value Types
  • @@ -9861,13 +9947,13 @@

    ProjectService

    -

    metalstack/api/v2/user.proto

    Top +

    metalstack/api/v2/switch.proto

    Top

    -

    User

    -

    User is a end user of the platform

    +

    BGPFilter

    +

    BGP filter can be used to restrict BGP based on CIDRs and VNIs

    @@ -9877,52 +9963,104 @@

    User

    - + - - + + - + + + + + + + +
    logincidrs string

    Login the login at the provider

    repeated

    CIDRs for which to allow BGP

    namevnisstringrepeated

    VNIs for which to allow BGP

    + + + + + +

    Switch

    +

    Switch represents a network switch

    + + + + + + + + + + - + - + - + - + + + + + + + + - + - - - - + + + + - - - - + + + + - - + + - + + + + + + + + + + + + + + + + + + + + + + @@ -9932,15 +10070,8 @@

    User

    -

    UserServiceGetRequest

    -

    UserServiceGetRequest is the request to get the user

    - - - - - -

    UserServiceGetResponse

    -

    UserServiceGetResponse the response when userservice get request was called

    +

    SwitchBGPPortState

    +

    SwitchBGPPortState holds information about the BGP state of a port

    FieldTypeLabelDescription
    id string

    Name of the user

    ID of the switch

    emaildescription string

    Email of the user

    Description of the switch

    avatar_urlrack_idstringoptional

    Rack ID if the switch resides in a rack

    partition_id string

    AvatarUrl of the user

    Partition ID of the partition the switch belongs to

    tenantsTenantrepeated

    Tenants the user belongs to

    typeSwitchType

    Type signifies what role a switch has, e.g. whether it is a leaf switch, or a spine, etc.

    projectsProjectrepeated

    Projects the user belongs to

    replace_modeSwitchReplaceMode

    Replace mode is used to mark a switch ready for replacement

    default_tenantTenantmanagement_ipstring

    DefaultTenant this user belongs to

    Management IP is the switch's IP for management access

    management_userstring

    Management user is the user name to use for management access

    console_commandstring

    Console command is the command for accessing the switch's console

    switch_nicsSwitchNicrepeated

    Switch NICs are the front panel ports of the switch

    @@ -9950,10 +10081,52 @@

    UserServiceGetResponse

    - - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -9963,41 +10136,8 @@

    UserServiceGetResponse

    - - - - - - -

    UserService

    -

    UserService exposes rpc calls for users

    -
    userUserneighborstring

    User is the user

    Neighbor of this port

    peer_groupstring

    Peer group of this port

    vrf_namestring

    VRF name of the VRF this port is bound to

    bgp_stateBGPState

    BGP state of the connection on this port

    bgp_timer_up_establisheduint64

    BGP timer up established reports the uptime of this port's BGP connection

    sent_prefix_counteruint64

    Sent prefix counter counts the prefixes sent by the switch on this port

    accepted_prefix_counteruint64

    Accepted prefix counter counts the prefixes received on this port

    - - - - - - - - - - - - - -
    Method NameRequest TypeResponse TypeDescription
    GetUserServiceGetRequestUserServiceGetResponse

    Get a User

    - - - - -
    -

    metalstack/api/v2/version.proto

    Top -
    -

    - - -

    Version

    -

    Version of the application

    +

    SwitchNic

    +

    SwitchNic represents a front panel port and its configuration

    @@ -10007,31 +10147,52 @@

    Version

    - + - + - + - + - + - + - + + + + + + + + - + + + + + + + + + + + + + + + @@ -10041,15 +10202,8 @@

    Version

    -

    VersionServiceGetRequest

    -

    VersionServiceGetRequest is the request payload to get the version

    - - - - - -

    VersionServiceGetResponse

    -

    VersionServiceGetResponse is the response payload with the version

    +

    SwitchOS

    +

    SwitchOS holds information about the NOS and versions running on the switch

    versionname string

    Version of the application

    Name of the switch port

    revisionidentifier string

    Revision of the application

    Identifier of the port

    git_sha1mac_address string

    GitSHA1 of the application

    MAC address of the port

    build_datevrf stringoptional

    VRF name if the port is bound in one

    actualSwitchPortStatus

    BuildDate of the application

    Actual port status

    bgp_filterBGPFilteroptional

    BGP filter optionally configured on a port

    bgp_port_stateSwitchBGPPortStateoptional

    BGP port state represents the current BGP status of the port

    @@ -10058,17 +10212,438 @@

    VersionServiceGetResponse

    + + + + + + + - + - + - -
    vendorSwitchOSVendor

    Switch OS vendor identifies what NOS distribution is running on the switch, e.g. SONiC

    versionVersionstring

    Version of the application

    Version specifies what NOS version is currently installed on the switch

    - - + + metal_core_version + string + +

    Metal core version is the currently running version of the metal-core

    + + + + + + + + + + + +

    BGPState

    +

    BGPState represents the state of a BGP session

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameNumberDescription
    BGP_STATE_UNSPECIFIED0

    BGP_STATE_UNSPECIFIED is not specified

    BGP_STATE_IDLE1

    BGP_STATE_IDLE is the Idle state of a BGP session

    BGP_STATE_CONNECT2

    BGP_STATE_CONNECT is the Connect state of a BGP session

    BGP_STATE_ACTIVE3

    BGP_STATE_ACTIVE is the Active state of a BGP session

    BGP_STATE_OPEN_SENT4

    BGP_STATE_OPEN_SENT is the OpenSent state of a BGP session

    BGP_STATE_OPEN_CONFIRM5

    BGP_STATE_OPEN_CONFIRM is the OpenConfirm state of a BGP session

    BGP_STATE_ESTABLISHED6

    BGP_STATE_ESTABLISHED is the Established state of a BGP session

    + +

    SwitchOSVendor

    +

    SwitchOSVendor represents a NOS distribution

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameNumberDescription
    SWITCH_OS_VENDOR_UNSPECIFIED0

    SWITCH_OS_VENDOR_UNSPECIFIED is not specified

    SWITCH_OS_VENDOR_CUMULUS1

    SWITCH_OS_VENDOR_CUMULUS means this switch is running on Cumulus Linux

    SWITCH_OS_VENDOR_SONIC2

    SWITCH_OS_VENDOR_SONIC means this switch is running on SONiC NOS

    + +

    SwitchPortStatus

    +

    SwitchPortStatus specifies the state of a switch port

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameNumberDescription
    SWITCH_PORT_STATUS_UNSPECIFIED0

    SWITCH_PORT_STATUS_UNSPECIFIED is not specified

    SWITCH_PORT_STATUS_UP1

    SWITCH_PORT_STATUS_UP means this port is up

    SWITCH_PORT_STATUS_DOWN2

    SWITCH_PORT_STATUS_DOWN means this port is down

    + +

    SwitchReplaceMode

    +

    SwitchReplaceMode is used to mark a switch ready for replacement

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameNumberDescription
    SWITCH_REPLACE_MODE_UNSPECIFIED0

    SWITCH_REPLACE_MODE_UNSPECIFIED is not specified

    SWITCH_REPLACE_MODE_REPLACE1

    SWITCH_REPLACE_MODE_REPLACE means this switch is waiting to be replaced

    SWITCH_REPLACE_MODE_OPERATIONAL2

    SWITCH_REPLACE_MODE_OPERATIONAL means this switch is operational and cannot be replaced

    + +

    SwitchType

    +

    SwitchType represents the role of a switch

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameNumberDescription
    SWITCH_TYPE_UNSPECIFIED0

    SWITCH_TYPE_UNSPECIFIED is not specified

    SWITCH_TYPE_LEAF1

    SWITCH_TYPE_LEAF is a leaf switch

    SWITCH_TYPE_EXIT2

    SWITCH_TYPE_EXIT is an exit switch

    SWITCH_TYPE_SPINE3

    SWITCH_TYPE_SPINE is a spine switch

    SWITCH_TYPE_MGMTLEAF4

    SWITCH_TYPE_MGMTLEAF is a special type of leaf used only for management tasks

    SWITCH_TYPE_MGMTSPINE5

    SWITCH_TYPE_MGMTSPINE is a special type of spine used only for management tasks

    + + + + + + + +
    +

    metalstack/api/v2/user.proto

    Top +
    +

    + + +

    User

    +

    User is a end user of the platform

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    FieldTypeLabelDescription
    loginstring

    Login the login at the provider

    namestring

    Name of the user

    emailstring

    Email of the user

    avatar_urlstring

    AvatarUrl of the user

    tenantsTenantrepeated

    Tenants the user belongs to

    projectsProjectrepeated

    Projects the user belongs to

    default_tenantTenant

    DefaultTenant this user belongs to

    + + + + + +

    UserServiceGetRequest

    +

    UserServiceGetRequest is the request to get the user

    + + + + + +

    UserServiceGetResponse

    +

    UserServiceGetResponse the response when userservice get request was called

    + + + + + + + + + + + + + + + + +
    FieldTypeLabelDescription
    userUser

    User is the user

    + + + + + + + + + + + +

    UserService

    +

    UserService exposes rpc calls for users

    + + + + + + + + + + + + + + +
    Method NameRequest TypeResponse TypeDescription
    GetUserServiceGetRequestUserServiceGetResponse

    Get a User

    + + + + +
    +

    metalstack/api/v2/version.proto

    Top +
    +

    + + +

    Version

    +

    Version of the application

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    FieldTypeLabelDescription
    versionstring

    Version of the application

    revisionstring

    Revision of the application

    git_sha1string

    GitSHA1 of the application

    build_datestring

    BuildDate of the application

    + + + + + +

    VersionServiceGetRequest

    +

    VersionServiceGetRequest is the request payload to get the version

    + + + + + +

    VersionServiceGetResponse

    +

    VersionServiceGetResponse is the response payload with the version

    + + + + + + + + + + + + + + + + +
    FieldTypeLabelDescription
    versionVersion

    Version of the application

    + + @@ -10145,6 +10720,156 @@

    BMCService

    + +
    +

    metalstack/infra/v2/switch.proto

    Top +
    +

    + + +

    BGPRoute

    +

    BGPRoute represents the route to a prefix

    + + + + + + + + + + + + + + + + +
    FieldTypeLabelDescription
    cidrstring

    CIDR of the network that is routed to

    + + + + + +

    SwitchServiceRegisterRequest

    +

    SwitchServiceRegisterRequest

    + + + + + + + + + + + + + + + + +
    FieldTypeLabelDescription
    switchmetalstack.api.v2.Switch

    Switch to register

    + + + + + +

    SwitchServiceRegisterResponse

    +

    SwitchServiceRegisterResponse

    + + + + + + + + + + + + + + + + +
    FieldTypeLabelDescription
    switchmetalstack.api.v2.Switch

    Switch that was registered

    + + + + + +

    SwitchServiceReportBGPRoutesRequest

    +

    SwitchServiceReportBGPRoutesRequest

    + + + + + + + + + + + + + + + + + + + + + + + +
    FieldTypeLabelDescription
    switch_idstring

    Switch ID of the switch that reports its routes

    bgp_routesBGPRouterepeated

    BGP routes collected on the switch

    + + + + + +

    SwitchServiceReportBGPRoutesResponse

    +

    SwitchServiceReportBGPRoutesResponse

    + + + + + + + + + + + +

    SwitchService

    +

    SwitchService serves switch related functions

    + + + + + + + + + + + + + + + + + + + + + +
    Method NameRequest TypeResponse TypeDescription
    RegisterSwitchServiceRegisterRequestSwitchServiceRegisterResponse

    Register a switch

    ReportBGPRoutesSwitchServiceReportBGPRoutesRequestSwitchServiceReportBGPRoutesResponse

    Report BGP routes of a switch

    + + +

    Scalar Value Types

    diff --git a/go/client/client.go b/go/client/client.go index 77bb4cc3..8029a001 100755 --- a/go/client/client.go +++ b/go/client/client.go @@ -70,10 +70,12 @@ type ( Infrav2 interface { BMC() infrav2connect.BMCServiceClient + Switch() infrav2connect.SwitchServiceClient } infrav2 struct { - bmcservice infrav2connect.BMCServiceClient + bmcservice infrav2connect.BMCServiceClient + switchservice infrav2connect.SwitchServiceClient } ) @@ -256,6 +258,11 @@ func (c client) Infrav2() Infrav2 { c.config.BaseURL, compress.WithAll(compress.LevelBalanced), ), + switchservice: infrav2connect.NewSwitchServiceClient( + c.config.HttpClient(), + c.config.BaseURL, + compress.WithAll(compress.LevelBalanced), + ), } return a } @@ -263,3 +270,6 @@ func (c client) Infrav2() Infrav2 { func (c *infrav2) BMC() infrav2connect.BMCServiceClient { return c.bmcservice } +func (c *infrav2) Switch() infrav2connect.SwitchServiceClient { + return c.switchservice +} diff --git a/go/metalstack/api/v2/switch.pb.go b/go/metalstack/api/v2/switch.pb.go new file mode 100644 index 00000000..27475093 --- /dev/null +++ b/go/metalstack/api/v2/switch.pb.go @@ -0,0 +1,928 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.6 +// protoc (unknown) +// source: metalstack/api/v2/switch.proto + +package apiv2 + +import ( + _ "buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go/buf/validate" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// BGPState represents the state of a BGP session +type BGPState int32 + +const ( + // BGP_STATE_UNSPECIFIED is not specified + BGPState_BGP_STATE_UNSPECIFIED BGPState = 0 + // BGP_STATE_IDLE is the Idle state of a BGP session + BGPState_BGP_STATE_IDLE BGPState = 1 + // BGP_STATE_CONNECT is the Connect state of a BGP session + BGPState_BGP_STATE_CONNECT BGPState = 2 + // BGP_STATE_ACTIVE is the Active state of a BGP session + BGPState_BGP_STATE_ACTIVE BGPState = 3 + // BGP_STATE_OPEN_SENT is the OpenSent state of a BGP session + BGPState_BGP_STATE_OPEN_SENT BGPState = 4 + // BGP_STATE_OPEN_CONFIRM is the OpenConfirm state of a BGP session + BGPState_BGP_STATE_OPEN_CONFIRM BGPState = 5 + // BGP_STATE_ESTABLISHED is the Established state of a BGP session + BGPState_BGP_STATE_ESTABLISHED BGPState = 6 +) + +// Enum value maps for BGPState. +var ( + BGPState_name = map[int32]string{ + 0: "BGP_STATE_UNSPECIFIED", + 1: "BGP_STATE_IDLE", + 2: "BGP_STATE_CONNECT", + 3: "BGP_STATE_ACTIVE", + 4: "BGP_STATE_OPEN_SENT", + 5: "BGP_STATE_OPEN_CONFIRM", + 6: "BGP_STATE_ESTABLISHED", + } + BGPState_value = map[string]int32{ + "BGP_STATE_UNSPECIFIED": 0, + "BGP_STATE_IDLE": 1, + "BGP_STATE_CONNECT": 2, + "BGP_STATE_ACTIVE": 3, + "BGP_STATE_OPEN_SENT": 4, + "BGP_STATE_OPEN_CONFIRM": 5, + "BGP_STATE_ESTABLISHED": 6, + } +) + +func (x BGPState) Enum() *BGPState { + p := new(BGPState) + *p = x + return p +} + +func (x BGPState) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (BGPState) Descriptor() protoreflect.EnumDescriptor { + return file_metalstack_api_v2_switch_proto_enumTypes[0].Descriptor() +} + +func (BGPState) Type() protoreflect.EnumType { + return &file_metalstack_api_v2_switch_proto_enumTypes[0] +} + +func (x BGPState) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use BGPState.Descriptor instead. +func (BGPState) EnumDescriptor() ([]byte, []int) { + return file_metalstack_api_v2_switch_proto_rawDescGZIP(), []int{0} +} + +// SwitchReplaceMode is used to mark a switch ready for replacement +type SwitchReplaceMode int32 + +const ( + // SWITCH_REPLACE_MODE_UNSPECIFIED is not specified + SwitchReplaceMode_SWITCH_REPLACE_MODE_UNSPECIFIED SwitchReplaceMode = 0 + // SWITCH_REPLACE_MODE_REPLACE means this switch is waiting to be replaced + SwitchReplaceMode_SWITCH_REPLACE_MODE_REPLACE SwitchReplaceMode = 1 + // SWITCH_REPLACE_MODE_OPERATIONAL means this switch is operational and cannot be replaced + SwitchReplaceMode_SWITCH_REPLACE_MODE_OPERATIONAL SwitchReplaceMode = 2 +) + +// Enum value maps for SwitchReplaceMode. +var ( + SwitchReplaceMode_name = map[int32]string{ + 0: "SWITCH_REPLACE_MODE_UNSPECIFIED", + 1: "SWITCH_REPLACE_MODE_REPLACE", + 2: "SWITCH_REPLACE_MODE_OPERATIONAL", + } + SwitchReplaceMode_value = map[string]int32{ + "SWITCH_REPLACE_MODE_UNSPECIFIED": 0, + "SWITCH_REPLACE_MODE_REPLACE": 1, + "SWITCH_REPLACE_MODE_OPERATIONAL": 2, + } +) + +func (x SwitchReplaceMode) Enum() *SwitchReplaceMode { + p := new(SwitchReplaceMode) + *p = x + return p +} + +func (x SwitchReplaceMode) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (SwitchReplaceMode) Descriptor() protoreflect.EnumDescriptor { + return file_metalstack_api_v2_switch_proto_enumTypes[1].Descriptor() +} + +func (SwitchReplaceMode) Type() protoreflect.EnumType { + return &file_metalstack_api_v2_switch_proto_enumTypes[1] +} + +func (x SwitchReplaceMode) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use SwitchReplaceMode.Descriptor instead. +func (SwitchReplaceMode) EnumDescriptor() ([]byte, []int) { + return file_metalstack_api_v2_switch_proto_rawDescGZIP(), []int{1} +} + +// SwitchOSVendor represents a NOS distribution +type SwitchOSVendor int32 + +const ( + // SWITCH_OS_VENDOR_UNSPECIFIED is not specified + SwitchOSVendor_SWITCH_OS_VENDOR_UNSPECIFIED SwitchOSVendor = 0 + // SWITCH_OS_VENDOR_CUMULUS means this switch is running on Cumulus Linux + SwitchOSVendor_SWITCH_OS_VENDOR_CUMULUS SwitchOSVendor = 1 + // SWITCH_OS_VENDOR_SONIC means this switch is running on SONiC NOS + SwitchOSVendor_SWITCH_OS_VENDOR_SONIC SwitchOSVendor = 2 +) + +// Enum value maps for SwitchOSVendor. +var ( + SwitchOSVendor_name = map[int32]string{ + 0: "SWITCH_OS_VENDOR_UNSPECIFIED", + 1: "SWITCH_OS_VENDOR_CUMULUS", + 2: "SWITCH_OS_VENDOR_SONIC", + } + SwitchOSVendor_value = map[string]int32{ + "SWITCH_OS_VENDOR_UNSPECIFIED": 0, + "SWITCH_OS_VENDOR_CUMULUS": 1, + "SWITCH_OS_VENDOR_SONIC": 2, + } +) + +func (x SwitchOSVendor) Enum() *SwitchOSVendor { + p := new(SwitchOSVendor) + *p = x + return p +} + +func (x SwitchOSVendor) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (SwitchOSVendor) Descriptor() protoreflect.EnumDescriptor { + return file_metalstack_api_v2_switch_proto_enumTypes[2].Descriptor() +} + +func (SwitchOSVendor) Type() protoreflect.EnumType { + return &file_metalstack_api_v2_switch_proto_enumTypes[2] +} + +func (x SwitchOSVendor) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use SwitchOSVendor.Descriptor instead. +func (SwitchOSVendor) EnumDescriptor() ([]byte, []int) { + return file_metalstack_api_v2_switch_proto_rawDescGZIP(), []int{2} +} + +// SwitchPortStatus specifies the state of a switch port +type SwitchPortStatus int32 + +const ( + // SWITCH_PORT_STATUS_UNSPECIFIED is not specified + SwitchPortStatus_SWITCH_PORT_STATUS_UNSPECIFIED SwitchPortStatus = 0 + // SWITCH_PORT_STATUS_UP means this port is up + SwitchPortStatus_SWITCH_PORT_STATUS_UP SwitchPortStatus = 1 + // SWITCH_PORT_STATUS_DOWN means this port is down + SwitchPortStatus_SWITCH_PORT_STATUS_DOWN SwitchPortStatus = 2 +) + +// Enum value maps for SwitchPortStatus. +var ( + SwitchPortStatus_name = map[int32]string{ + 0: "SWITCH_PORT_STATUS_UNSPECIFIED", + 1: "SWITCH_PORT_STATUS_UP", + 2: "SWITCH_PORT_STATUS_DOWN", + } + SwitchPortStatus_value = map[string]int32{ + "SWITCH_PORT_STATUS_UNSPECIFIED": 0, + "SWITCH_PORT_STATUS_UP": 1, + "SWITCH_PORT_STATUS_DOWN": 2, + } +) + +func (x SwitchPortStatus) Enum() *SwitchPortStatus { + p := new(SwitchPortStatus) + *p = x + return p +} + +func (x SwitchPortStatus) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (SwitchPortStatus) Descriptor() protoreflect.EnumDescriptor { + return file_metalstack_api_v2_switch_proto_enumTypes[3].Descriptor() +} + +func (SwitchPortStatus) Type() protoreflect.EnumType { + return &file_metalstack_api_v2_switch_proto_enumTypes[3] +} + +func (x SwitchPortStatus) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use SwitchPortStatus.Descriptor instead. +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"` + // ID of the switch + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // Description of the switch + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` + // Rack ID if the switch resides in a rack + RackId *string `protobuf:"bytes,3,opt,name=rack_id,json=rackId,proto3,oneof" json:"rack_id,omitempty"` + // Partition ID of the partition the switch belongs to + PartitionId string `protobuf:"bytes,4,opt,name=partition_id,json=partitionId,proto3" json:"partition_id,omitempty"` + // Type signifies what role a switch has, e.g. whether it is a leaf switch, or a spine, etc. + Type SwitchType `protobuf:"varint,5,opt,name=type,proto3,enum=metalstack.api.v2.SwitchType" json:"type,omitempty"` + // Replace mode is used to mark a switch ready for replacement + ReplaceMode SwitchReplaceMode `protobuf:"varint,6,opt,name=replace_mode,json=replaceMode,proto3,enum=metalstack.api.v2.SwitchReplaceMode" json:"replace_mode,omitempty"` + // Management IP is the switch's IP for management access + ManagementIp string `protobuf:"bytes,7,opt,name=management_ip,json=managementIp,proto3" json:"management_ip,omitempty"` + // Management user is the user name to use for management access + ManagementUser string `protobuf:"bytes,8,opt,name=management_user,json=managementUser,proto3" json:"management_user,omitempty"` + // Console command is the command for accessing the switch's console + ConsoleCommand string `protobuf:"bytes,9,opt,name=console_command,json=consoleCommand,proto3" json:"console_command,omitempty"` + // Switch NICs are the front panel ports of the switch + SwitchNics []*SwitchNic `protobuf:"bytes,10,rep,name=switch_nics,json=switchNics,proto3" json:"switch_nics,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Switch) Reset() { + *x = Switch{} + mi := &file_metalstack_api_v2_switch_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Switch) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Switch) ProtoMessage() {} + +func (x *Switch) ProtoReflect() protoreflect.Message { + mi := &file_metalstack_api_v2_switch_proto_msgTypes[0] + 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 Switch.ProtoReflect.Descriptor instead. +func (*Switch) Descriptor() ([]byte, []int) { + return file_metalstack_api_v2_switch_proto_rawDescGZIP(), []int{0} +} + +func (x *Switch) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Switch) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *Switch) GetRackId() string { + if x != nil && x.RackId != nil { + return *x.RackId + } + return "" +} + +func (x *Switch) GetPartitionId() string { + if x != nil { + return x.PartitionId + } + return "" +} + +func (x *Switch) GetType() SwitchType { + if x != nil { + return x.Type + } + return SwitchType_SWITCH_TYPE_UNSPECIFIED +} + +func (x *Switch) GetReplaceMode() SwitchReplaceMode { + if x != nil { + return x.ReplaceMode + } + return SwitchReplaceMode_SWITCH_REPLACE_MODE_UNSPECIFIED +} + +func (x *Switch) GetManagementIp() string { + if x != nil { + return x.ManagementIp + } + return "" +} + +func (x *Switch) GetManagementUser() string { + if x != nil { + return x.ManagementUser + } + return "" +} + +func (x *Switch) GetConsoleCommand() string { + if x != nil { + return x.ConsoleCommand + } + return "" +} + +func (x *Switch) GetSwitchNics() []*SwitchNic { + if x != nil { + return x.SwitchNics + } + return nil +} + +// SwitchOS holds information about the NOS and versions running on the switch +type SwitchOS struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Switch OS vendor identifies what NOS distribution is running on the switch, e.g. SONiC + Vendor SwitchOSVendor `protobuf:"varint,1,opt,name=vendor,proto3,enum=metalstack.api.v2.SwitchOSVendor" json:"vendor,omitempty"` + // Version specifies what NOS version is currently installed on the switch + Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"` + // Metal core version is the currently running version of the metal-core + MetalCoreVersion string `protobuf:"bytes,3,opt,name=metal_core_version,json=metalCoreVersion,proto3" json:"metal_core_version,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SwitchOS) Reset() { + *x = SwitchOS{} + mi := &file_metalstack_api_v2_switch_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SwitchOS) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SwitchOS) ProtoMessage() {} + +func (x *SwitchOS) ProtoReflect() protoreflect.Message { + mi := &file_metalstack_api_v2_switch_proto_msgTypes[1] + 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 SwitchOS.ProtoReflect.Descriptor instead. +func (*SwitchOS) Descriptor() ([]byte, []int) { + return file_metalstack_api_v2_switch_proto_rawDescGZIP(), []int{1} +} + +func (x *SwitchOS) GetVendor() SwitchOSVendor { + if x != nil { + return x.Vendor + } + return SwitchOSVendor_SWITCH_OS_VENDOR_UNSPECIFIED +} + +func (x *SwitchOS) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +func (x *SwitchOS) GetMetalCoreVersion() string { + if x != nil { + return x.MetalCoreVersion + } + return "" +} + +// SwitchNic represents a front panel port and its configuration +type SwitchNic struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Name of the switch port + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // Identifier of the port + Identifier string `protobuf:"bytes,2,opt,name=identifier,proto3" json:"identifier,omitempty"` + // MAC address of the port + MacAddress string `protobuf:"bytes,3,opt,name=mac_address,json=macAddress,proto3" json:"mac_address,omitempty"` + // VRF name if the port is bound in one + Vrf *string `protobuf:"bytes,4,opt,name=vrf,proto3,oneof" json:"vrf,omitempty"` + // Actual port status + Actual SwitchPortStatus `protobuf:"varint,5,opt,name=actual,proto3,enum=metalstack.api.v2.SwitchPortStatus" json:"actual,omitempty"` + // BGP filter optionally configured on a port + BgpFilter *BGPFilter `protobuf:"bytes,6,opt,name=bgp_filter,json=bgpFilter,proto3,oneof" json:"bgp_filter,omitempty"` + // BGP port state represents the current BGP status of the port + BgpPortState *SwitchBGPPortState `protobuf:"bytes,7,opt,name=bgp_port_state,json=bgpPortState,proto3,oneof" json:"bgp_port_state,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SwitchNic) Reset() { + *x = SwitchNic{} + mi := &file_metalstack_api_v2_switch_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SwitchNic) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SwitchNic) ProtoMessage() {} + +func (x *SwitchNic) ProtoReflect() protoreflect.Message { + mi := &file_metalstack_api_v2_switch_proto_msgTypes[2] + 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 SwitchNic.ProtoReflect.Descriptor instead. +func (*SwitchNic) Descriptor() ([]byte, []int) { + return file_metalstack_api_v2_switch_proto_rawDescGZIP(), []int{2} +} + +func (x *SwitchNic) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *SwitchNic) GetIdentifier() string { + if x != nil { + return x.Identifier + } + return "" +} + +func (x *SwitchNic) GetMacAddress() string { + if x != nil { + return x.MacAddress + } + return "" +} + +func (x *SwitchNic) GetVrf() string { + if x != nil && x.Vrf != nil { + return *x.Vrf + } + return "" +} + +func (x *SwitchNic) GetActual() SwitchPortStatus { + if x != nil { + return x.Actual + } + return SwitchPortStatus_SWITCH_PORT_STATUS_UNSPECIFIED +} + +func (x *SwitchNic) GetBgpFilter() *BGPFilter { + if x != nil { + return x.BgpFilter + } + return nil +} + +func (x *SwitchNic) GetBgpPortState() *SwitchBGPPortState { + if x != nil { + return x.BgpPortState + } + return nil +} + +// BGP filter can be used to restrict BGP based on CIDRs and VNIs +type BGPFilter struct { + state protoimpl.MessageState `protogen:"open.v1"` + // CIDRs for which to allow BGP + Cidrs []string `protobuf:"bytes,1,rep,name=cidrs,proto3" json:"cidrs,omitempty"` + // VNIs for which to allow BGP + Vnis []string `protobuf:"bytes,2,rep,name=vnis,proto3" json:"vnis,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *BGPFilter) Reset() { + *x = BGPFilter{} + mi := &file_metalstack_api_v2_switch_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *BGPFilter) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BGPFilter) ProtoMessage() {} + +func (x *BGPFilter) ProtoReflect() protoreflect.Message { + mi := &file_metalstack_api_v2_switch_proto_msgTypes[3] + 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 BGPFilter.ProtoReflect.Descriptor instead. +func (*BGPFilter) Descriptor() ([]byte, []int) { + return file_metalstack_api_v2_switch_proto_rawDescGZIP(), []int{3} +} + +func (x *BGPFilter) GetCidrs() []string { + if x != nil { + return x.Cidrs + } + return nil +} + +func (x *BGPFilter) GetVnis() []string { + if x != nil { + return x.Vnis + } + return nil +} + +// SwitchBGPPortState holds information about the BGP state of a port +type SwitchBGPPortState struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Neighbor of this port + Neighbor string `protobuf:"bytes,1,opt,name=neighbor,proto3" json:"neighbor,omitempty"` + // Peer group of this port + PeerGroup string `protobuf:"bytes,2,opt,name=peer_group,json=peerGroup,proto3" json:"peer_group,omitempty"` + // VRF name of the VRF this port is bound to + VrfName string `protobuf:"bytes,3,opt,name=vrf_name,json=vrfName,proto3" json:"vrf_name,omitempty"` + // BGP state of the connection on this port + BgpState BGPState `protobuf:"varint,4,opt,name=bgp_state,json=bgpState,proto3,enum=metalstack.api.v2.BGPState" json:"bgp_state,omitempty"` + // BGP timer up established reports the uptime of this port's BGP connection + BgpTimerUpEstablished uint64 `protobuf:"varint,5,opt,name=bgp_timer_up_established,json=bgpTimerUpEstablished,proto3" json:"bgp_timer_up_established,omitempty"` + // Sent prefix counter counts the prefixes sent by the switch on this port + SentPrefixCounter uint64 `protobuf:"varint,6,opt,name=sent_prefix_counter,json=sentPrefixCounter,proto3" json:"sent_prefix_counter,omitempty"` + // Accepted prefix counter counts the prefixes received on this port + AcceptedPrefixCounter uint64 `protobuf:"varint,7,opt,name=accepted_prefix_counter,json=acceptedPrefixCounter,proto3" json:"accepted_prefix_counter,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SwitchBGPPortState) Reset() { + *x = SwitchBGPPortState{} + mi := &file_metalstack_api_v2_switch_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SwitchBGPPortState) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SwitchBGPPortState) ProtoMessage() {} + +func (x *SwitchBGPPortState) ProtoReflect() protoreflect.Message { + mi := &file_metalstack_api_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 SwitchBGPPortState.ProtoReflect.Descriptor instead. +func (*SwitchBGPPortState) Descriptor() ([]byte, []int) { + return file_metalstack_api_v2_switch_proto_rawDescGZIP(), []int{4} +} + +func (x *SwitchBGPPortState) GetNeighbor() string { + if x != nil { + return x.Neighbor + } + return "" +} + +func (x *SwitchBGPPortState) GetPeerGroup() string { + if x != nil { + return x.PeerGroup + } + return "" +} + +func (x *SwitchBGPPortState) GetVrfName() string { + if x != nil { + return x.VrfName + } + return "" +} + +func (x *SwitchBGPPortState) GetBgpState() BGPState { + if x != nil { + return x.BgpState + } + return BGPState_BGP_STATE_UNSPECIFIED +} + +func (x *SwitchBGPPortState) GetBgpTimerUpEstablished() uint64 { + if x != nil { + return x.BgpTimerUpEstablished + } + return 0 +} + +func (x *SwitchBGPPortState) GetSentPrefixCounter() uint64 { + if x != nil { + return x.SentPrefixCounter + } + return 0 +} + +func (x *SwitchBGPPortState) GetAcceptedPrefixCounter() uint64 { + if x != nil { + return x.AcceptedPrefixCounter + } + return 0 +} + +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\x1emetalstack/api/v2/common.proto\"\xa0\x04\n" + + "\x06Switch\x12\x1c\n" + + "\x02id\x18\x01 \x01(\tB\f\xbaH\tr\a\x10\x02\x18\x80\x01h\x01R\x02id\x12,\n" + + "\vdescription\x18\x02 \x01(\tB\n" + + "\xbaH\ar\x05\x10\x02\x18\x80\x01R\vdescription\x12(\n" + + "\arack_id\x18\x03 \x01(\tB\n" + + "\xbaH\ar\x05\x10\x02\x18\x80\x01H\x00R\x06rackId\x88\x01\x01\x12-\n" + + "\fpartition_id\x18\x04 \x01(\tB\n" + + "\xbaH\ar\x05\x10\x02\x18\x80\x01R\vpartitionId\x12;\n" + + "\x04type\x18\x05 \x01(\x0e2\x1d.metalstack.api.v2.SwitchTypeB\b\xbaH\x05\x82\x01\x02\x10\x01R\x04type\x12Q\n" + + "\freplace_mode\x18\x06 \x01(\x0e2$.metalstack.api.v2.SwitchReplaceModeB\b\xbaH\x05\x82\x01\x02\x10\x01R\vreplaceMode\x12,\n" + + "\rmanagement_ip\x18\a \x01(\tB\a\xbaH\x04r\x02p\x01R\fmanagementIp\x123\n" + + "\x0fmanagement_user\x18\b \x01(\tB\n" + + "\xbaH\ar\x05\x10\x02\x18\x80\x01R\x0emanagementUser\x123\n" + + "\x0fconsole_command\x18\t \x01(\tB\n" + + "\xbaH\ar\x05\x10\x02\x18\x80\x01R\x0econsoleCommand\x12=\n" + + "\vswitch_nics\x18\n" + + " \x03(\v2\x1c.metalstack.api.v2.SwitchNicR\n" + + "switchNicsB\n" + + "\n" + + "\b_rack_id\"\xaf\x01\n" + + "\bSwitchOS\x12C\n" + + "\x06vendor\x18\x01 \x01(\x0e2!.metalstack.api.v2.SwitchOSVendorB\b\xbaH\x05\x82\x01\x02\x10\x01R\x06vendor\x12$\n" + + "\aversion\x18\x02 \x01(\tB\n" + + "\xbaH\ar\x05\x10\x02\x18\x80\x01R\aversion\x128\n" + + "\x12metal_core_version\x18\x03 \x01(\tB\n" + + "\xbaH\ar\x05\x10\x02\x18\x80\x01R\x10metalCoreVersion\"\xd1\x03\n" + + "\tSwitchNic\x12\x1e\n" + + "\x04name\x18\x01 \x01(\tB\n" + + "\xbaH\ar\x05\x10\x02\x18\x80\x01R\x04name\x12*\n" + + "\n" + + "identifier\x18\x02 \x01(\tB\n" + + "\xbaH\ar\x05\x10\x02\x18\x80\x01R\n" + + "identifier\x12P\n" + + "\vmac_address\x18\x03 \x01(\tB/\xbaH,r*2(^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$R\n" + + "macAddress\x12!\n" + + "\x03vrf\x18\x04 \x01(\tB\n" + + "\xbaH\ar\x05\x10\x02\x18\x80\x01H\x00R\x03vrf\x88\x01\x01\x12E\n" + + "\x06actual\x18\x05 \x01(\x0e2#.metalstack.api.v2.SwitchPortStatusB\b\xbaH\x05\x82\x01\x02\x10\x01R\x06actual\x12@\n" + + "\n" + + "bgp_filter\x18\x06 \x01(\v2\x1c.metalstack.api.v2.BGPFilterH\x01R\tbgpFilter\x88\x01\x01\x12P\n" + + "\x0ebgp_port_state\x18\a \x01(\v2%.metalstack.api.v2.SwitchBGPPortStateH\x02R\fbgpPortState\x88\x01\x01B\x06\n" + + "\x04_vrfB\r\n" + + "\v_bgp_filterB\x11\n" + + "\x0f_bgp_port_state\"\x92\x01\n" + + "\tBGPFilter\x12\x14\n" + + "\x05cidrs\x18\x01 \x03(\tR\x05cidrs\x12#\n" + + "\x04vnis\x18\x02 \x03(\tB\x0f\xbaH\f\x92\x01\t\"\ar\x05\x10\x02\x18\x80\x01R\x04vnis:J\xbaHG\x1aE\n" + + "\x05cidrs\x12\x19given cidrs must be valid\x1a!this.cidrs.all(m, m.isIpPrefix())\"\xf3\x02\n" + + "\x12SwitchBGPPortState\x12&\n" + + "\bneighbor\x18\x01 \x01(\tB\n" + + "\xbaH\ar\x05\x10\x02\x18\x80\x01R\bneighbor\x12)\n" + + "\n" + + "peer_group\x18\x02 \x01(\tB\n" + + "\xbaH\ar\x05\x10\x02\x18\x80\x01R\tpeerGroup\x12%\n" + + "\bvrf_name\x18\x03 \x01(\tB\n" + + "\xbaH\ar\x05\x10\x02\x18\x80\x01R\avrfName\x12B\n" + + "\tbgp_state\x18\x04 \x01(\x0e2\x1b.metalstack.api.v2.BGPStateB\b\xbaH\x05\x82\x01\x02\x10\x01R\bbgpState\x127\n" + + "\x18bgp_timer_up_established\x18\x05 \x01(\x04R\x15bgpTimerUpEstablished\x12.\n" + + "\x13sent_prefix_counter\x18\x06 \x01(\x04R\x11sentPrefixCounter\x126\n" + + "\x17accepted_prefix_counter\x18\a \x01(\x04R\x15acceptedPrefixCounter*\x8b\x02\n" + + "\bBGPState\x12\x19\n" + + "\x15BGP_STATE_UNSPECIFIED\x10\x00\x12\x1c\n" + + "\x0eBGP_STATE_IDLE\x10\x01\x1a\b\x82\xb2\x19\x04idle\x12\"\n" + + "\x11BGP_STATE_CONNECT\x10\x02\x1a\v\x82\xb2\x19\aconnect\x12 \n" + + "\x10BGP_STATE_ACTIVE\x10\x03\x1a\n" + + "\x82\xb2\x19\x06active\x12&\n" + + "\x13BGP_STATE_OPEN_SENT\x10\x04\x1a\r\x82\xb2\x19\topen-sent\x12,\n" + + "\x16BGP_STATE_OPEN_CONFIRM\x10\x05\x1a\x10\x82\xb2\x19\fopen-confirm\x12*\n" + + "\x15BGP_STATE_ESTABLISHED\x10\x06\x1a\x0f\x82\xb2\x19\vestablished*\x9c\x01\n" + + "\x11SwitchReplaceMode\x12#\n" + + "\x1fSWITCH_REPLACE_MODE_UNSPECIFIED\x10\x00\x12,\n" + + "\x1bSWITCH_REPLACE_MODE_REPLACE\x10\x01\x1a\v\x82\xb2\x19\areplace\x124\n" + + "\x1fSWITCH_REPLACE_MODE_OPERATIONAL\x10\x02\x1a\x0f\x82\xb2\x19\voperational*\x84\x01\n" + + "\x0eSwitchOSVendor\x12 \n" + + "\x1cSWITCH_OS_VENDOR_UNSPECIFIED\x10\x00\x12)\n" + + "\x18SWITCH_OS_VENDOR_CUMULUS\x10\x01\x1a\v\x82\xb2\x19\acumulus\x12%\n" + + "\x16SWITCH_OS_VENDOR_SONIC\x10\x02\x1a\t\x82\xb2\x19\x05sonic*\x80\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\b\x82\xb2\x19\x04down*\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 ( + file_metalstack_api_v2_switch_proto_rawDescOnce sync.Once + file_metalstack_api_v2_switch_proto_rawDescData []byte +) + +func file_metalstack_api_v2_switch_proto_rawDescGZIP() []byte { + file_metalstack_api_v2_switch_proto_rawDescOnce.Do(func() { + file_metalstack_api_v2_switch_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_metalstack_api_v2_switch_proto_rawDesc), len(file_metalstack_api_v2_switch_proto_rawDesc))) + }) + return file_metalstack_api_v2_switch_proto_rawDescData +} + +var file_metalstack_api_v2_switch_proto_enumTypes = make([]protoimpl.EnumInfo, 5) +var file_metalstack_api_v2_switch_proto_msgTypes = make([]protoimpl.MessageInfo, 5) +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 + (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 +} +var file_metalstack_api_v2_switch_proto_depIdxs = []int32{ + 4, // 0: metalstack.api.v2.Switch.type:type_name -> metalstack.api.v2.SwitchType + 1, // 1: metalstack.api.v2.Switch.replace_mode:type_name -> metalstack.api.v2.SwitchReplaceMode + 7, // 2: metalstack.api.v2.Switch.switch_nics:type_name -> metalstack.api.v2.SwitchNic + 2, // 3: metalstack.api.v2.SwitchOS.vendor:type_name -> metalstack.api.v2.SwitchOSVendor + 3, // 4: metalstack.api.v2.SwitchNic.actual:type_name -> metalstack.api.v2.SwitchPortStatus + 8, // 5: metalstack.api.v2.SwitchNic.bgp_filter:type_name -> metalstack.api.v2.BGPFilter + 9, // 6: metalstack.api.v2.SwitchNic.bgp_port_state:type_name -> metalstack.api.v2.SwitchBGPPortState + 0, // 7: metalstack.api.v2.SwitchBGPPortState.bgp_state:type_name -> metalstack.api.v2.BGPState + 8, // [8:8] is the sub-list for method output_type + 8, // [8:8] is the sub-list for method input_type + 8, // [8:8] is the sub-list for extension type_name + 8, // [8:8] is the sub-list for extension extendee + 0, // [0:8] is the sub-list for field type_name +} + +func init() { file_metalstack_api_v2_switch_proto_init() } +func file_metalstack_api_v2_switch_proto_init() { + if File_metalstack_api_v2_switch_proto != nil { + return + } + file_metalstack_api_v2_common_proto_init() + file_metalstack_api_v2_switch_proto_msgTypes[0].OneofWrappers = []any{} + file_metalstack_api_v2_switch_proto_msgTypes[2].OneofWrappers = []any{} + type x struct{} + out := protoimpl.TypeBuilder{ + 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: 5, + NumMessages: 5, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_metalstack_api_v2_switch_proto_goTypes, + DependencyIndexes: file_metalstack_api_v2_switch_proto_depIdxs, + EnumInfos: file_metalstack_api_v2_switch_proto_enumTypes, + MessageInfos: file_metalstack_api_v2_switch_proto_msgTypes, + }.Build() + File_metalstack_api_v2_switch_proto = out.File + file_metalstack_api_v2_switch_proto_goTypes = nil + file_metalstack_api_v2_switch_proto_depIdxs = nil +} diff --git a/go/metalstack/infra/v2/infrav2connect/switch.connect.go b/go/metalstack/infra/v2/infrav2connect/switch.connect.go new file mode 100644 index 00000000..6b7d090b --- /dev/null +++ b/go/metalstack/infra/v2/infrav2connect/switch.connect.go @@ -0,0 +1,141 @@ +// Code generated by protoc-gen-connect-go. DO NOT EDIT. +// +// Source: metalstack/infra/v2/switch.proto + +package infrav2connect + +import ( + connect "connectrpc.com/connect" + context "context" + errors "errors" + v2 "github.com/metal-stack/api/go/metalstack/infra/v2" + http "net/http" + strings "strings" +) + +// This is a compile-time assertion to ensure that this generated file and the connect package are +// compatible. If you get a compiler error that this constant is not defined, this code was +// generated with a version of connect newer than the one compiled into your binary. You can fix the +// problem by either regenerating this code with an older version of connect or updating the connect +// version compiled into your binary. +const _ = connect.IsAtLeastVersion1_13_0 + +const ( + // SwitchServiceName is the fully-qualified name of the SwitchService service. + SwitchServiceName = "metalstack.infra.v2.SwitchService" +) + +// These constants are the fully-qualified names of the RPCs defined in this package. They're +// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route. +// +// Note that these are different from the fully-qualified method names used by +// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to +// reflection-formatted method names, remove the leading slash and convert the remaining slash to a +// period. +const ( + // SwitchServiceRegisterProcedure is the fully-qualified name of the SwitchService's Register RPC. + SwitchServiceRegisterProcedure = "/metalstack.infra.v2.SwitchService/Register" + // 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. +type SwitchServiceClient interface { + // Register a switch + Register(context.Context, *connect.Request[v2.SwitchServiceRegisterRequest]) (*connect.Response[v2.SwitchServiceRegisterResponse], error) + // Report BGP routes of a switch + ReportBGPRoutes(context.Context, *connect.Request[v2.SwitchServiceReportBGPRoutesRequest]) (*connect.Response[v2.SwitchServiceReportBGPRoutesResponse], error) +} + +// NewSwitchServiceClient constructs a client for the metalstack.infra.v2.SwitchService service. By +// default, it uses the Connect protocol with the binary Protobuf Codec, asks for gzipped responses, +// and sends uncompressed requests. To use the gRPC or gRPC-Web protocols, supply the +// connect.WithGRPC() or connect.WithGRPCWeb() options. +// +// The URL supplied here should be the base URL for the Connect or gRPC server (for example, +// http://api.acme.com or https://acme.com/grpc). +func NewSwitchServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) SwitchServiceClient { + baseURL = strings.TrimRight(baseURL, "/") + switchServiceMethods := v2.File_metalstack_infra_v2_switch_proto.Services().ByName("SwitchService").Methods() + return &switchServiceClient{ + register: connect.NewClient[v2.SwitchServiceRegisterRequest, v2.SwitchServiceRegisterResponse]( + httpClient, + baseURL+SwitchServiceRegisterProcedure, + connect.WithSchema(switchServiceMethods.ByName("Register")), + 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 { + register *connect.Client[v2.SwitchServiceRegisterRequest, v2.SwitchServiceRegisterResponse] + reportBGPRoutes *connect.Client[v2.SwitchServiceReportBGPRoutesRequest, v2.SwitchServiceReportBGPRoutesResponse] +} + +// Register calls metalstack.infra.v2.SwitchService.Register. +func (c *switchServiceClient) Register(ctx context.Context, req *connect.Request[v2.SwitchServiceRegisterRequest]) (*connect.Response[v2.SwitchServiceRegisterResponse], error) { + return c.register.CallUnary(ctx, req) +} + +// ReportBGPRoutes calls metalstack.infra.v2.SwitchService.ReportBGPRoutes. +func (c *switchServiceClient) ReportBGPRoutes(ctx context.Context, req *connect.Request[v2.SwitchServiceReportBGPRoutesRequest]) (*connect.Response[v2.SwitchServiceReportBGPRoutesResponse], error) { + return c.reportBGPRoutes.CallUnary(ctx, req) +} + +// SwitchServiceHandler is an implementation of the metalstack.infra.v2.SwitchService service. +type SwitchServiceHandler interface { + // Register a switch + Register(context.Context, *connect.Request[v2.SwitchServiceRegisterRequest]) (*connect.Response[v2.SwitchServiceRegisterResponse], error) + // Report BGP routes of a switch + ReportBGPRoutes(context.Context, *connect.Request[v2.SwitchServiceReportBGPRoutesRequest]) (*connect.Response[v2.SwitchServiceReportBGPRoutesResponse], error) +} + +// NewSwitchServiceHandler builds an HTTP handler from the service implementation. It returns the +// path on which to mount the handler and the handler itself. +// +// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf +// and JSON codecs. They also support gzip compression. +func NewSwitchServiceHandler(svc SwitchServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) { + switchServiceMethods := v2.File_metalstack_infra_v2_switch_proto.Services().ByName("SwitchService").Methods() + switchServiceRegisterHandler := connect.NewUnaryHandler( + SwitchServiceRegisterProcedure, + svc.Register, + connect.WithSchema(switchServiceMethods.ByName("Register")), + connect.WithHandlerOptions(opts...), + ) + switchServiceReportBGPRoutesHandler := connect.NewUnaryHandler( + 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 SwitchServiceRegisterProcedure: + switchServiceRegisterHandler.ServeHTTP(w, r) + case SwitchServiceReportBGPRoutesProcedure: + switchServiceReportBGPRoutesHandler.ServeHTTP(w, r) + default: + http.NotFound(w, r) + } + }) +} + +// UnimplementedSwitchServiceHandler returns CodeUnimplemented from all methods. +type UnimplementedSwitchServiceHandler struct{} + +func (UnimplementedSwitchServiceHandler) Register(context.Context, *connect.Request[v2.SwitchServiceRegisterRequest]) (*connect.Response[v2.SwitchServiceRegisterResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("metalstack.infra.v2.SwitchService.Register is not implemented")) +} + +func (UnimplementedSwitchServiceHandler) ReportBGPRoutes(context.Context, *connect.Request[v2.SwitchServiceReportBGPRoutesRequest]) (*connect.Response[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 new file mode 100644 index 00000000..18a62fd1 --- /dev/null +++ b/go/metalstack/infra/v2/switch.pb.go @@ -0,0 +1,338 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.6 +// protoc (unknown) +// source: metalstack/infra/v2/switch.proto + +package infrav2 + +import ( + _ "buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go/buf/validate" + v2 "github.com/metal-stack/api/go/metalstack/api/v2" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// SwitchServiceRegisterRequest +type SwitchServiceRegisterRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Switch to register + Switch *v2.Switch `protobuf:"bytes,1,opt,name=switch,proto3" json:"switch,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SwitchServiceRegisterRequest) Reset() { + *x = SwitchServiceRegisterRequest{} + mi := &file_metalstack_infra_v2_switch_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SwitchServiceRegisterRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SwitchServiceRegisterRequest) ProtoMessage() {} + +func (x *SwitchServiceRegisterRequest) ProtoReflect() protoreflect.Message { + mi := &file_metalstack_infra_v2_switch_proto_msgTypes[0] + 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 SwitchServiceRegisterRequest.ProtoReflect.Descriptor instead. +func (*SwitchServiceRegisterRequest) Descriptor() ([]byte, []int) { + return file_metalstack_infra_v2_switch_proto_rawDescGZIP(), []int{0} +} + +func (x *SwitchServiceRegisterRequest) GetSwitch() *v2.Switch { + if x != nil { + return x.Switch + } + return nil +} + +// SwitchServiceRegisterResponse +type SwitchServiceRegisterResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Switch that was registered + Switch *v2.Switch `protobuf:"bytes,1,opt,name=switch,proto3" json:"switch,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SwitchServiceRegisterResponse) Reset() { + *x = SwitchServiceRegisterResponse{} + mi := &file_metalstack_infra_v2_switch_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SwitchServiceRegisterResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SwitchServiceRegisterResponse) ProtoMessage() {} + +func (x *SwitchServiceRegisterResponse) ProtoReflect() protoreflect.Message { + mi := &file_metalstack_infra_v2_switch_proto_msgTypes[1] + 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 SwitchServiceRegisterResponse.ProtoReflect.Descriptor instead. +func (*SwitchServiceRegisterResponse) Descriptor() ([]byte, []int) { + return file_metalstack_infra_v2_switch_proto_rawDescGZIP(), []int{1} +} + +func (x *SwitchServiceRegisterResponse) GetSwitch() *v2.Switch { + if x != nil { + return x.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[2] + 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[2] + 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{2} +} + +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[3] + 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[3] + 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{3} +} + +// 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[4] + 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[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 BGPRoute.ProtoReflect.Descriptor instead. +func (*BGPRoute) Descriptor() ([]byte, []int) { + return file_metalstack_infra_v2_switch_proto_rawDescGZIP(), []int{4} +} + +func (x *BGPRoute) GetCidr() string { + if x != nil { + return x.Cidr + } + return "" +} + +var File_metalstack_infra_v2_switch_proto protoreflect.FileDescriptor + +const file_metalstack_infra_v2_switch_proto_rawDesc = "" + + "\n" + + " metalstack/infra/v2/switch.proto\x12\x13metalstack.infra.v2\x1a\x1bbuf/validate/validate.proto\x1a\x1emetalstack/api/v2/common.proto\x1a\x1emetalstack/api/v2/switch.proto\"Q\n" + + "\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\"\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()2\xa3\x02\n" + + "\rSwitchService\x12}\n" + + "\bRegister\x121.metalstack.infra.v2.SwitchServiceRegisterRequest\x1a2.metalstack.infra.v2.SwitchServiceRegisterResponse\"\n" + + "\xe0\xf3\x18\x02\xea\xf3\x18\x02\x01\x02\x12\x92\x01\n" + + "\x0fReportBGPRoutes\x128.metalstack.infra.v2.SwitchServiceReportBGPRoutesRequest\x1a9.metalstack.infra.v2.SwitchServiceReportBGPRoutesResponse\"\n" + + "\xe0\xf3\x18\x02\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 ( + file_metalstack_infra_v2_switch_proto_rawDescOnce sync.Once + file_metalstack_infra_v2_switch_proto_rawDescData []byte +) + +func file_metalstack_infra_v2_switch_proto_rawDescGZIP() []byte { + file_metalstack_infra_v2_switch_proto_rawDescOnce.Do(func() { + file_metalstack_infra_v2_switch_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_metalstack_infra_v2_switch_proto_rawDesc), len(file_metalstack_infra_v2_switch_proto_rawDesc))) + }) + return file_metalstack_infra_v2_switch_proto_rawDescData +} + +var file_metalstack_infra_v2_switch_proto_msgTypes = make([]protoimpl.MessageInfo, 5) +var file_metalstack_infra_v2_switch_proto_goTypes = []any{ + (*SwitchServiceRegisterRequest)(nil), // 0: metalstack.infra.v2.SwitchServiceRegisterRequest + (*SwitchServiceRegisterResponse)(nil), // 1: metalstack.infra.v2.SwitchServiceRegisterResponse + (*SwitchServiceReportBGPRoutesRequest)(nil), // 2: metalstack.infra.v2.SwitchServiceReportBGPRoutesRequest + (*SwitchServiceReportBGPRoutesResponse)(nil), // 3: metalstack.infra.v2.SwitchServiceReportBGPRoutesResponse + (*BGPRoute)(nil), // 4: metalstack.infra.v2.BGPRoute + (*v2.Switch)(nil), // 5: metalstack.api.v2.Switch +} +var file_metalstack_infra_v2_switch_proto_depIdxs = []int32{ + 5, // 0: metalstack.infra.v2.SwitchServiceRegisterRequest.switch:type_name -> metalstack.api.v2.Switch + 5, // 1: metalstack.infra.v2.SwitchServiceRegisterResponse.switch:type_name -> metalstack.api.v2.Switch + 4, // 2: metalstack.infra.v2.SwitchServiceReportBGPRoutesRequest.bgp_routes:type_name -> metalstack.infra.v2.BGPRoute + 0, // 3: metalstack.infra.v2.SwitchService.Register:input_type -> metalstack.infra.v2.SwitchServiceRegisterRequest + 2, // 4: metalstack.infra.v2.SwitchService.ReportBGPRoutes:input_type -> metalstack.infra.v2.SwitchServiceReportBGPRoutesRequest + 1, // 5: metalstack.infra.v2.SwitchService.Register:output_type -> metalstack.infra.v2.SwitchServiceRegisterResponse + 3, // 6: metalstack.infra.v2.SwitchService.ReportBGPRoutes:output_type -> metalstack.infra.v2.SwitchServiceReportBGPRoutesResponse + 5, // [5:7] is the sub-list for method output_type + 3, // [3:5] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name +} + +func init() { file_metalstack_infra_v2_switch_proto_init() } +func file_metalstack_infra_v2_switch_proto_init() { + if File_metalstack_infra_v2_switch_proto != nil { + return + } + 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: 5, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_metalstack_infra_v2_switch_proto_goTypes, + DependencyIndexes: file_metalstack_infra_v2_switch_proto_depIdxs, + MessageInfos: file_metalstack_infra_v2_switch_proto_msgTypes, + }.Build() + File_metalstack_infra_v2_switch_proto = out.File + file_metalstack_infra_v2_switch_proto_goTypes = nil + file_metalstack_infra_v2_switch_proto_depIdxs = nil +} diff --git a/go/permissions/servicepermissions.go b/go/permissions/servicepermissions.go index 19738234..d202cedd 100755 --- a/go/permissions/servicepermissions.go +++ b/go/permissions/servicepermissions.go @@ -27,6 +27,7 @@ func GetServices() []string { "metalstack.api.v2.UserService", "metalstack.api.v2.VersionService", "metalstack.infra.v2.BMCService", + "metalstack.infra.v2.SwitchService", } } @@ -71,10 +72,10 @@ func GetServicePermissions() *ServicePermissions { }, Infra: Infra{ "INFRA_ROLE_EDITOR": []string{ - "/metalstack.infra.v2.BMCService/UpdateBMCInfo", + "/metalstack.infra.v2.SwitchService/ReportBGPRoutes", }, "INFRA_ROLE_VIEWER": []string{ - "/metalstack.infra.v2.BMCService/UpdateBMCInfo", + "/metalstack.infra.v2.SwitchService/ReportBGPRoutes", }, }, Tenant: Tenant{ @@ -227,6 +228,8 @@ func GetServicePermissions() *ServicePermissions { "/metalstack.api.v2.UserService/Get": true, "/metalstack.api.v2.VersionService/Get": true, "/metalstack.infra.v2.BMCService/UpdateBMCInfo": true, + "/metalstack.infra.v2.SwitchService/Register": true, + "/metalstack.infra.v2.SwitchService/ReportBGPRoutes": true, }, Visibility: Visibility{ Public: map[string]bool{ @@ -286,7 +289,9 @@ func GetServicePermissions() *ServicePermissions { "/metalstack.admin.v2.TokenService/Revoke": true, }, Infra: map[string]bool{ - "/metalstack.infra.v2.BMCService/UpdateBMCInfo": true, + "/metalstack.infra.v2.BMCService/UpdateBMCInfo": true, + "/metalstack.infra.v2.SwitchService/Register": true, + "/metalstack.infra.v2.SwitchService/ReportBGPRoutes": true, }, Tenant: map[string]bool{ "/metalstack.api.v2.ProjectService/Create": true, @@ -399,6 +404,8 @@ func GetServicePermissions() *ServicePermissions { "/metalstack.api.v2.UserService/Get": true, "/metalstack.api.v2.VersionService/Get": false, "/metalstack.infra.v2.BMCService/UpdateBMCInfo": false, + "/metalstack.infra.v2.SwitchService/Register": false, + "/metalstack.infra.v2.SwitchService/ReportBGPRoutes": false, }, } } diff --git a/go/tests/mock_clients.go b/go/tests/mock_clients.go index 63f4732c..e2e11978 100755 --- a/go/tests/mock_clients.go +++ b/go/tests/mock_clients.go @@ -80,11 +80,13 @@ type ( Version func(m *mock.Mock) } infrav2 struct { - bmcservice *infrav2mocks.BMCServiceClient + bmcservice *infrav2mocks.BMCServiceClient + switchservice *infrav2mocks.SwitchServiceClient } Infrav2MockFns struct { - BMC func(m *mock.Mock) + BMC func(m *mock.Mock) + Switch func(m *mock.Mock) } ) @@ -281,13 +283,17 @@ func (w wrapper) Infrav2(fns *Infrav2MockFns) *infrav2 { func newinfrav2(t *testing.T, fns *Infrav2MockFns) *infrav2 { a := &infrav2{ - bmcservice: infrav2mocks.NewBMCServiceClient(t), + bmcservice: infrav2mocks.NewBMCServiceClient(t), + switchservice: infrav2mocks.NewSwitchServiceClient(t), } if fns != nil { if fns.BMC != nil { fns.BMC(&a.bmcservice.Mock) } + if fns.Switch != nil { + fns.Switch(&a.switchservice.Mock) + } } @@ -297,3 +303,6 @@ func newinfrav2(t *testing.T, fns *Infrav2MockFns) *infrav2 { func (c *infrav2) BMC() infrav2connect.BMCServiceClient { return c.bmcservice } +func (c *infrav2) Switch() infrav2connect.SwitchServiceClient { + return c.switchservice +} diff --git a/go/tests/mocks/metalstack/infra/v2/infrav2connect/SwitchServiceClient.go b/go/tests/mocks/metalstack/infra/v2/infrav2connect/SwitchServiceClient.go new file mode 100644 index 00000000..39fde54f --- /dev/null +++ b/go/tests/mocks/metalstack/infra/v2/infrav2connect/SwitchServiceClient.go @@ -0,0 +1,92 @@ +// Code generated by mockery v2.53.4. DO NOT EDIT. + +package infrav2connect + +import ( + context "context" + + connect "connectrpc.com/connect" + + infrav2 "github.com/metal-stack/api/go/metalstack/infra/v2" + + mock "github.com/stretchr/testify/mock" +) + +// SwitchServiceClient is an autogenerated mock type for the SwitchServiceClient type +type SwitchServiceClient struct { + mock.Mock +} + +// Register provides a mock function with given fields: _a0, _a1 +func (_m *SwitchServiceClient) Register(_a0 context.Context, _a1 *connect.Request[infrav2.SwitchServiceRegisterRequest]) (*connect.Response[infrav2.SwitchServiceRegisterResponse], error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for Register") + } + + var r0 *connect.Response[infrav2.SwitchServiceRegisterResponse] + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *connect.Request[infrav2.SwitchServiceRegisterRequest]) (*connect.Response[infrav2.SwitchServiceRegisterResponse], error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, *connect.Request[infrav2.SwitchServiceRegisterRequest]) *connect.Response[infrav2.SwitchServiceRegisterResponse]); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*connect.Response[infrav2.SwitchServiceRegisterResponse]) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *connect.Request[infrav2.SwitchServiceRegisterRequest]) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ReportBGPRoutes provides a mock function with given fields: _a0, _a1 +func (_m *SwitchServiceClient) ReportBGPRoutes(_a0 context.Context, _a1 *connect.Request[infrav2.SwitchServiceReportBGPRoutesRequest]) (*connect.Response[infrav2.SwitchServiceReportBGPRoutesResponse], error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for ReportBGPRoutes") + } + + var r0 *connect.Response[infrav2.SwitchServiceReportBGPRoutesResponse] + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *connect.Request[infrav2.SwitchServiceReportBGPRoutesRequest]) (*connect.Response[infrav2.SwitchServiceReportBGPRoutesResponse], error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, *connect.Request[infrav2.SwitchServiceReportBGPRoutesRequest]) *connect.Response[infrav2.SwitchServiceReportBGPRoutesResponse]); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*connect.Response[infrav2.SwitchServiceReportBGPRoutesResponse]) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *connect.Request[infrav2.SwitchServiceReportBGPRoutesRequest]) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// NewSwitchServiceClient creates a new instance of SwitchServiceClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewSwitchServiceClient(t interface { + mock.TestingT + Cleanup(func()) +}) *SwitchServiceClient { + mock := &SwitchServiceClient{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/go/tests/mocks/metalstack/infra/v2/infrav2connect/SwitchServiceHandler.go b/go/tests/mocks/metalstack/infra/v2/infrav2connect/SwitchServiceHandler.go new file mode 100644 index 00000000..a8a0247a --- /dev/null +++ b/go/tests/mocks/metalstack/infra/v2/infrav2connect/SwitchServiceHandler.go @@ -0,0 +1,92 @@ +// Code generated by mockery v2.53.4. DO NOT EDIT. + +package infrav2connect + +import ( + context "context" + + connect "connectrpc.com/connect" + + infrav2 "github.com/metal-stack/api/go/metalstack/infra/v2" + + mock "github.com/stretchr/testify/mock" +) + +// SwitchServiceHandler is an autogenerated mock type for the SwitchServiceHandler type +type SwitchServiceHandler struct { + mock.Mock +} + +// Register provides a mock function with given fields: _a0, _a1 +func (_m *SwitchServiceHandler) Register(_a0 context.Context, _a1 *connect.Request[infrav2.SwitchServiceRegisterRequest]) (*connect.Response[infrav2.SwitchServiceRegisterResponse], error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for Register") + } + + var r0 *connect.Response[infrav2.SwitchServiceRegisterResponse] + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *connect.Request[infrav2.SwitchServiceRegisterRequest]) (*connect.Response[infrav2.SwitchServiceRegisterResponse], error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, *connect.Request[infrav2.SwitchServiceRegisterRequest]) *connect.Response[infrav2.SwitchServiceRegisterResponse]); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*connect.Response[infrav2.SwitchServiceRegisterResponse]) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *connect.Request[infrav2.SwitchServiceRegisterRequest]) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ReportBGPRoutes provides a mock function with given fields: _a0, _a1 +func (_m *SwitchServiceHandler) ReportBGPRoutes(_a0 context.Context, _a1 *connect.Request[infrav2.SwitchServiceReportBGPRoutesRequest]) (*connect.Response[infrav2.SwitchServiceReportBGPRoutesResponse], error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for ReportBGPRoutes") + } + + var r0 *connect.Response[infrav2.SwitchServiceReportBGPRoutesResponse] + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *connect.Request[infrav2.SwitchServiceReportBGPRoutesRequest]) (*connect.Response[infrav2.SwitchServiceReportBGPRoutesResponse], error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, *connect.Request[infrav2.SwitchServiceReportBGPRoutesRequest]) *connect.Response[infrav2.SwitchServiceReportBGPRoutesResponse]); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*connect.Response[infrav2.SwitchServiceReportBGPRoutesResponse]) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *connect.Request[infrav2.SwitchServiceReportBGPRoutesRequest]) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// NewSwitchServiceHandler creates a new instance of SwitchServiceHandler. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewSwitchServiceHandler(t interface { + mock.TestingT + Cleanup(func()) +}) *SwitchServiceHandler { + mock := &SwitchServiceHandler{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/go/tests/validation/switch_test.go b/go/tests/validation/switch_test.go new file mode 100644 index 00000000..8deb6314 --- /dev/null +++ b/go/tests/validation/switch_test.go @@ -0,0 +1,78 @@ +package validation + +import ( + "testing" + + "buf.build/go/protovalidate" + apiv2 "github.com/metal-stack/api/go/metalstack/api/v2" + "github.com/stretchr/testify/require" +) + +func TestValidateMACAddress(t *testing.T) { + validator, err := protovalidate.New() + require.NoError(t, err) + + tests := prototests{ + { + name: "Valid MAC address", + msg: &apiv2.SwitchNic{ + MacAddress: "11:22:33:44:55:66", + Name: "Ethernet0", + Identifier: "Eth1/1", + }, + wantErr: false, + }, + { + name: "Too long", + msg: &apiv2.SwitchNic{ + MacAddress: "11:22:33:44:55:66:77", + Name: "Ethernet0", + Identifier: "Eth1/1", + }, + wantErr: true, + wantErrorMessage: "validation error:\n - mac_address: value does not match regex pattern `^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$` [string.pattern]", + }, + { + name: "Too short", + msg: &apiv2.SwitchNic{ + MacAddress: "11:22:33:44:55", + Name: "Ethernet0", + Identifier: "Eth1/1", + }, + wantErr: true, + wantErrorMessage: "validation error:\n - mac_address: value does not match regex pattern `^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$` [string.pattern]", + }, + { + name: "Invalid separator", + msg: &apiv2.SwitchNic{ + MacAddress: "11.22.33.44.55.66", + Name: "Ethernet0", + Identifier: "Eth1/1", + }, + wantErr: true, + wantErrorMessage: "validation error:\n - mac_address: value does not match regex pattern `^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$` [string.pattern]", + }, + { + name: "Invalid character", + msg: &apiv2.SwitchNic{ + MacAddress: "11:22:33:44:55:gg", + Name: "Ethernet0", + Identifier: "Eth1/1", + }, + wantErr: true, + wantErrorMessage: "validation error:\n - mac_address: value does not match regex pattern `^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$` [string.pattern]", + }, + { + name: "Uppercase and lowercase allowed", + msg: &apiv2.SwitchNic{ + MacAddress: "11:22:33:44:55:aA", + Name: "Ethernet0", + Identifier: "Eth1/1", + }, + wantErr: true, + wantErrorMessage: "validation error:\n - mac_address: value does not match regex pattern `^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$` [string.pattern]", + }, + } + + validateProtos(t, tests, validator) +} diff --git a/proto/metalstack/api/v2/switch.proto b/proto/metalstack/api/v2/switch.proto index 4a1ef63a..353cbd8c 100644 --- a/proto/metalstack/api/v2/switch.proto +++ b/proto/metalstack/api/v2/switch.proto @@ -3,6 +3,7 @@ syntax = "proto3"; package metalstack.api.v2; import "buf/validate/validate.proto"; +import "metalstack/api/v2/common.proto"; // Switch represents a network switch message Switch { @@ -76,7 +77,7 @@ message SwitchNic { max_len: 128 }]; // MAC address of the port - string mac_address = 3 [(validate.rules).string.pattern = "^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$"]; + string mac_address = 3 [(buf.validate.field).string.pattern = "^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$"]; // VRF name if the port is bound in one optional string vrf = 4 [(buf.validate.field).string = { min_len: 2 @@ -100,7 +101,7 @@ message BGPFilter { expression: "this.cidrs.all(m, m.isIpPrefix())" }; // VNIs for which to allow BGP - repeated string vnis = 2 [(buf.validate.field).string = { + repeated string vnis = 2 [(buf.validate.field).repeated.items.string = { min_len: 2 max_len: 128 }]; @@ -174,7 +175,7 @@ enum SwitchOSVendor { // SwitchPortStatus specifies the state of a switch port enum SwitchPortStatus { // SWITCH_PORT_STATUS_UNSPECIFIED is not specified - SWITCH_PORT_STATUS_UNSPECIFED = 0; + SWITCH_PORT_STATUS_UNSPECIFIED = 0; // SWITCH_PORT_STATUS_UP means this port is up SWITCH_PORT_STATUS_UP = 1 [(enum_string_value) = "up"]; // SWITCH_PORT_STATUS_DOWN means this port is down diff --git a/proto/metalstack/infra/v2/switch.proto b/proto/metalstack/infra/v2/switch.proto index 0d5eca81..da51f89b 100644 --- a/proto/metalstack/infra/v2/switch.proto +++ b/proto/metalstack/infra/v2/switch.proto @@ -2,7 +2,9 @@ syntax = "proto3"; package metalstack.infra.v2; +import "buf/validate/validate.proto"; import "metalstack/api/v2/common.proto"; +import "metalstack/api/v2/switch.proto"; // SwitchService serves switch related functions service SwitchService { @@ -41,7 +43,7 @@ message SwitchServiceReportBGPRoutesRequest { max_len: 128 }]; // BGP routes collected on the switch - repeated BGPRoute bgpRoutes = 2; + repeated BGPRoute bgp_routes = 2; } // SwitchServiceReportBGPRoutesResponse From 0b29c3a0ce8b97f338c74832ba736df91a922076 Mon Sep 17 00:00:00 2001 From: Ilja Rotar Date: Wed, 18 Jun 2025 15:37:26 +0200 Subject: [PATCH 3/8] make session uptime a duration --- doc/index.html | 2 +- go/metalstack/api/v2/switch.pb.go | 63 +++++++++++++++------------- go/tests/mocks/client/Infrav2.go | 20 +++++++++ proto/metalstack/api/v2/switch.proto | 3 +- 4 files changed, 56 insertions(+), 32 deletions(-) diff --git a/doc/index.html b/doc/index.html index 4cbf7d5f..b2e3babb 100644 --- a/doc/index.html +++ b/doc/index.html @@ -10110,7 +10110,7 @@

    SwitchBGPPortState

    - + diff --git a/go/metalstack/api/v2/switch.pb.go b/go/metalstack/api/v2/switch.pb.go index 27475093..c89d4471 100644 --- a/go/metalstack/api/v2/switch.pb.go +++ b/go/metalstack/api/v2/switch.pb.go @@ -10,6 +10,7 @@ import ( _ "buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go/buf/validate" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + durationpb "google.golang.org/protobuf/types/known/durationpb" reflect "reflect" sync "sync" unsafe "unsafe" @@ -673,7 +674,7 @@ type SwitchBGPPortState struct { // BGP state of the connection on this port BgpState BGPState `protobuf:"varint,4,opt,name=bgp_state,json=bgpState,proto3,enum=metalstack.api.v2.BGPState" json:"bgp_state,omitempty"` // BGP timer up established reports the uptime of this port's BGP connection - BgpTimerUpEstablished uint64 `protobuf:"varint,5,opt,name=bgp_timer_up_established,json=bgpTimerUpEstablished,proto3" json:"bgp_timer_up_established,omitempty"` + BgpTimerUpEstablished *durationpb.Duration `protobuf:"bytes,5,opt,name=bgp_timer_up_established,json=bgpTimerUpEstablished,proto3" json:"bgp_timer_up_established,omitempty"` // Sent prefix counter counts the prefixes sent by the switch on this port SentPrefixCounter uint64 `protobuf:"varint,6,opt,name=sent_prefix_counter,json=sentPrefixCounter,proto3" json:"sent_prefix_counter,omitempty"` // Accepted prefix counter counts the prefixes received on this port @@ -740,11 +741,11 @@ func (x *SwitchBGPPortState) GetBgpState() BGPState { return BGPState_BGP_STATE_UNSPECIFIED } -func (x *SwitchBGPPortState) GetBgpTimerUpEstablished() uint64 { +func (x *SwitchBGPPortState) GetBgpTimerUpEstablished() *durationpb.Duration { if x != nil { return x.BgpTimerUpEstablished } - return 0 + return nil } func (x *SwitchBGPPortState) GetSentPrefixCounter() uint64 { @@ -765,7 +766,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\x1emetalstack/api/v2/common.proto\"\xa0\x04\n" + + "\x1emetalstack/api/v2/switch.proto\x12\x11metalstack.api.v2\x1a\x1bbuf/validate/validate.proto\x1a\x1egoogle/protobuf/duration.proto\x1a\x1emetalstack/api/v2/common.proto\"\xa0\x04\n" + "\x06Switch\x12\x1c\n" + "\x02id\x18\x01 \x01(\tB\f\xbaH\tr\a\x10\x02\x18\x80\x01h\x01R\x02id\x12,\n" + "\vdescription\x18\x02 \x01(\tB\n" + @@ -813,7 +814,7 @@ const file_metalstack_api_v2_switch_proto_rawDesc = "" + "\tBGPFilter\x12\x14\n" + "\x05cidrs\x18\x01 \x03(\tR\x05cidrs\x12#\n" + "\x04vnis\x18\x02 \x03(\tB\x0f\xbaH\f\x92\x01\t\"\ar\x05\x10\x02\x18\x80\x01R\x04vnis:J\xbaHG\x1aE\n" + - "\x05cidrs\x12\x19given cidrs must be valid\x1a!this.cidrs.all(m, m.isIpPrefix())\"\xf3\x02\n" + + "\x05cidrs\x12\x19given cidrs must be valid\x1a!this.cidrs.all(m, m.isIpPrefix())\"\x8e\x03\n" + "\x12SwitchBGPPortState\x12&\n" + "\bneighbor\x18\x01 \x01(\tB\n" + "\xbaH\ar\x05\x10\x02\x18\x80\x01R\bneighbor\x12)\n" + @@ -822,8 +823,8 @@ const file_metalstack_api_v2_switch_proto_rawDesc = "" + "\xbaH\ar\x05\x10\x02\x18\x80\x01R\tpeerGroup\x12%\n" + "\bvrf_name\x18\x03 \x01(\tB\n" + "\xbaH\ar\x05\x10\x02\x18\x80\x01R\avrfName\x12B\n" + - "\tbgp_state\x18\x04 \x01(\x0e2\x1b.metalstack.api.v2.BGPStateB\b\xbaH\x05\x82\x01\x02\x10\x01R\bbgpState\x127\n" + - "\x18bgp_timer_up_established\x18\x05 \x01(\x04R\x15bgpTimerUpEstablished\x12.\n" + + "\tbgp_state\x18\x04 \x01(\x0e2\x1b.metalstack.api.v2.BGPStateB\b\xbaH\x05\x82\x01\x02\x10\x01R\bbgpState\x12R\n" + + "\x18bgp_timer_up_established\x18\x05 \x01(\v2\x19.google.protobuf.DurationR\x15bgpTimerUpEstablished\x12.\n" + "\x13sent_prefix_counter\x18\x06 \x01(\x04R\x11sentPrefixCounter\x126\n" + "\x17accepted_prefix_counter\x18\a \x01(\x04R\x15acceptedPrefixCounter*\x8b\x02\n" + "\bBGPState\x12\x19\n" + @@ -872,31 +873,33 @@ func file_metalstack_api_v2_switch_proto_rawDescGZIP() []byte { var file_metalstack_api_v2_switch_proto_enumTypes = make([]protoimpl.EnumInfo, 5) var file_metalstack_api_v2_switch_proto_msgTypes = make([]protoimpl.MessageInfo, 5) 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 - (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 + (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 + (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 + (*durationpb.Duration)(nil), // 10: google.protobuf.Duration } var file_metalstack_api_v2_switch_proto_depIdxs = []int32{ - 4, // 0: metalstack.api.v2.Switch.type:type_name -> metalstack.api.v2.SwitchType - 1, // 1: metalstack.api.v2.Switch.replace_mode:type_name -> metalstack.api.v2.SwitchReplaceMode - 7, // 2: metalstack.api.v2.Switch.switch_nics:type_name -> metalstack.api.v2.SwitchNic - 2, // 3: metalstack.api.v2.SwitchOS.vendor:type_name -> metalstack.api.v2.SwitchOSVendor - 3, // 4: metalstack.api.v2.SwitchNic.actual:type_name -> metalstack.api.v2.SwitchPortStatus - 8, // 5: metalstack.api.v2.SwitchNic.bgp_filter:type_name -> metalstack.api.v2.BGPFilter - 9, // 6: metalstack.api.v2.SwitchNic.bgp_port_state:type_name -> metalstack.api.v2.SwitchBGPPortState - 0, // 7: metalstack.api.v2.SwitchBGPPortState.bgp_state:type_name -> metalstack.api.v2.BGPState - 8, // [8:8] is the sub-list for method output_type - 8, // [8:8] is the sub-list for method input_type - 8, // [8:8] is the sub-list for extension type_name - 8, // [8:8] is the sub-list for extension extendee - 0, // [0:8] is the sub-list for field type_name + 4, // 0: metalstack.api.v2.Switch.type:type_name -> metalstack.api.v2.SwitchType + 1, // 1: metalstack.api.v2.Switch.replace_mode:type_name -> metalstack.api.v2.SwitchReplaceMode + 7, // 2: metalstack.api.v2.Switch.switch_nics:type_name -> metalstack.api.v2.SwitchNic + 2, // 3: metalstack.api.v2.SwitchOS.vendor:type_name -> metalstack.api.v2.SwitchOSVendor + 3, // 4: metalstack.api.v2.SwitchNic.actual:type_name -> metalstack.api.v2.SwitchPortStatus + 8, // 5: metalstack.api.v2.SwitchNic.bgp_filter:type_name -> metalstack.api.v2.BGPFilter + 9, // 6: metalstack.api.v2.SwitchNic.bgp_port_state:type_name -> metalstack.api.v2.SwitchBGPPortState + 0, // 7: metalstack.api.v2.SwitchBGPPortState.bgp_state:type_name -> metalstack.api.v2.BGPState + 10, // 8: metalstack.api.v2.SwitchBGPPortState.bgp_timer_up_established:type_name -> google.protobuf.Duration + 9, // [9:9] is the sub-list for method output_type + 9, // [9:9] is the sub-list for method input_type + 9, // [9:9] is the sub-list for extension type_name + 9, // [9:9] is the sub-list for extension extendee + 0, // [0:9] is the sub-list for field type_name } func init() { file_metalstack_api_v2_switch_proto_init() } diff --git a/go/tests/mocks/client/Infrav2.go b/go/tests/mocks/client/Infrav2.go index e7f297ae..cfa1e4be 100644 --- a/go/tests/mocks/client/Infrav2.go +++ b/go/tests/mocks/client/Infrav2.go @@ -32,6 +32,26 @@ func (_m *Infrav2) BMC() infrav2connect.BMCServiceClient { return r0 } +// Switch provides a mock function with no fields +func (_m *Infrav2) Switch() infrav2connect.SwitchServiceClient { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Switch") + } + + var r0 infrav2connect.SwitchServiceClient + if rf, ok := ret.Get(0).(func() infrav2connect.SwitchServiceClient); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(infrav2connect.SwitchServiceClient) + } + } + + return r0 +} + // NewInfrav2 creates a new instance of Infrav2. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewInfrav2(t interface { diff --git a/proto/metalstack/api/v2/switch.proto b/proto/metalstack/api/v2/switch.proto index 353cbd8c..6e7ab1ab 100644 --- a/proto/metalstack/api/v2/switch.proto +++ b/proto/metalstack/api/v2/switch.proto @@ -3,6 +3,7 @@ syntax = "proto3"; package metalstack.api.v2; import "buf/validate/validate.proto"; +import "google/protobuf/duration.proto"; import "metalstack/api/v2/common.proto"; // Switch represents a network switch @@ -127,7 +128,7 @@ message SwitchBGPPortState { // BGP state of the connection on this port BGPState bgp_state = 4 [(buf.validate.field).enum.defined_only = true]; // BGP timer up established reports the uptime of this port's BGP connection - uint64 bgp_timer_up_established = 5; + google.protobuf.Duration bgp_timer_up_established = 5; // Sent prefix counter counts the prefixes sent by the switch on this port uint64 sent_prefix_counter = 6; // Accepted prefix counter counts the prefixes received on this port From c41adc65215c496d68b061c49e0fc98820100da3 Mon Sep 17 00:00:00 2001 From: Ilja Rotar Date: Wed, 18 Jun 2025 15:39:55 +0200 Subject: [PATCH 4/8] rename partition id to partition --- doc/index.html | 4 ++-- go/metalstack/api/v2/switch.pb.go | 16 ++++++++-------- proto/metalstack/api/v2/switch.proto | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/doc/index.html b/doc/index.html index b2e3babb..1b30ecaf 100644 --- a/doc/index.html +++ b/doc/index.html @@ -10015,10 +10015,10 @@

    Switch

    - + - + diff --git a/go/metalstack/api/v2/switch.pb.go b/go/metalstack/api/v2/switch.pb.go index c89d4471..1a8a312e 100644 --- a/go/metalstack/api/v2/switch.pb.go +++ b/go/metalstack/api/v2/switch.pb.go @@ -325,8 +325,8 @@ type Switch struct { Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` // Rack ID if the switch resides in a rack RackId *string `protobuf:"bytes,3,opt,name=rack_id,json=rackId,proto3,oneof" json:"rack_id,omitempty"` - // Partition ID of the partition the switch belongs to - PartitionId string `protobuf:"bytes,4,opt,name=partition_id,json=partitionId,proto3" json:"partition_id,omitempty"` + // Partition the switch belongs to + Partition string `protobuf:"bytes,4,opt,name=partition,proto3" json:"partition,omitempty"` // Type signifies what role a switch has, e.g. whether it is a leaf switch, or a spine, etc. Type SwitchType `protobuf:"varint,5,opt,name=type,proto3,enum=metalstack.api.v2.SwitchType" json:"type,omitempty"` // Replace mode is used to mark a switch ready for replacement @@ -394,9 +394,9 @@ func (x *Switch) GetRackId() string { return "" } -func (x *Switch) GetPartitionId() string { +func (x *Switch) GetPartition() string { if x != nil { - return x.PartitionId + return x.Partition } return "" } @@ -766,15 +766,15 @@ 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\x1egoogle/protobuf/duration.proto\x1a\x1emetalstack/api/v2/common.proto\"\xa0\x04\n" + + "\x1emetalstack/api/v2/switch.proto\x12\x11metalstack.api.v2\x1a\x1bbuf/validate/validate.proto\x1a\x1egoogle/protobuf/duration.proto\x1a\x1emetalstack/api/v2/common.proto\"\x9b\x04\n" + "\x06Switch\x12\x1c\n" + "\x02id\x18\x01 \x01(\tB\f\xbaH\tr\a\x10\x02\x18\x80\x01h\x01R\x02id\x12,\n" + "\vdescription\x18\x02 \x01(\tB\n" + "\xbaH\ar\x05\x10\x02\x18\x80\x01R\vdescription\x12(\n" + "\arack_id\x18\x03 \x01(\tB\n" + - "\xbaH\ar\x05\x10\x02\x18\x80\x01H\x00R\x06rackId\x88\x01\x01\x12-\n" + - "\fpartition_id\x18\x04 \x01(\tB\n" + - "\xbaH\ar\x05\x10\x02\x18\x80\x01R\vpartitionId\x12;\n" + + "\xbaH\ar\x05\x10\x02\x18\x80\x01H\x00R\x06rackId\x88\x01\x01\x12(\n" + + "\tpartition\x18\x04 \x01(\tB\n" + + "\xbaH\ar\x05\x10\x02\x18\x80\x01R\tpartition\x12;\n" + "\x04type\x18\x05 \x01(\x0e2\x1d.metalstack.api.v2.SwitchTypeB\b\xbaH\x05\x82\x01\x02\x10\x01R\x04type\x12Q\n" + "\freplace_mode\x18\x06 \x01(\x0e2$.metalstack.api.v2.SwitchReplaceModeB\b\xbaH\x05\x82\x01\x02\x10\x01R\vreplaceMode\x12,\n" + "\rmanagement_ip\x18\a \x01(\tB\a\xbaH\x04r\x02p\x01R\fmanagementIp\x123\n" + diff --git a/proto/metalstack/api/v2/switch.proto b/proto/metalstack/api/v2/switch.proto index 6e7ab1ab..a5bf20af 100644 --- a/proto/metalstack/api/v2/switch.proto +++ b/proto/metalstack/api/v2/switch.proto @@ -24,8 +24,8 @@ message Switch { min_len: 2 max_len: 128 }]; - // Partition ID of the partition the switch belongs to - string partition_id = 4 [(buf.validate.field).string = { + // Partition the switch belongs to + string partition = 4 [(buf.validate.field).string = { min_len: 2 max_len: 128 }]; From 6e770f6520163b30bf576805f7f05affb7ff68ed Mon Sep 17 00:00:00 2001 From: Stefan Majer Date: Thu, 10 Jul 2025 21:55:19 +0200 Subject: [PATCH 5/8] Merge main --- python/metalstack/api/v2/switch_pb2.py | 138 +++++++++++++++ python/metalstack/api/v2/switch_pb2.pyi | 150 +++++++++++++++++ python/metalstack/api/v2/switch_pb2_grpc.py | 4 + python/metalstack/infra/v2/switch_connecpy.py | 158 ++++++++++++++++++ python/metalstack/infra/v2/switch_pb2.py | 58 +++++++ python/metalstack/infra/v2/switch_pb2.pyi | 40 +++++ python/metalstack/infra/v2/switch_pb2_grpc.py | 125 ++++++++++++++ 7 files changed, 673 insertions(+) create mode 100644 python/metalstack/api/v2/switch_pb2.py create mode 100644 python/metalstack/api/v2/switch_pb2.pyi create mode 100644 python/metalstack/api/v2/switch_pb2_grpc.py create mode 100644 python/metalstack/infra/v2/switch_connecpy.py create mode 100644 python/metalstack/infra/v2/switch_pb2.py create mode 100644 python/metalstack/infra/v2/switch_pb2.pyi create mode 100644 python/metalstack/infra/v2/switch_pb2_grpc.py diff --git a/python/metalstack/api/v2/switch_pb2.py b/python/metalstack/api/v2/switch_pb2.py new file mode 100644 index 00000000..be457f10 --- /dev/null +++ b/python/metalstack/api/v2/switch_pb2.py @@ -0,0 +1,138 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: metalstack/api/v2/switch.proto +# Protobuf Python Version: 6.31.1 +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import runtime_version as _runtime_version +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 6, + 31, + 1, + '', + 'metalstack/api/v2/switch.proto' +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from buf.validate import validate_pb2 as buf_dot_validate_dot_validate__pb2 +from google.protobuf import duration_pb2 as google_dot_protobuf_dot_duration__pb2 +from metalstack.api.v2 import common_pb2 as metalstack_dot_api_dot_v2_dot_common__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1emetalstack/api/v2/switch.proto\x12\x11metalstack.api.v2\x1a\x1b\x62uf/validate/validate.proto\x1a\x1egoogle/protobuf/duration.proto\x1a\x1emetalstack/api/v2/common.proto\"\x9b\x04\n\x06Switch\x12\x1c\n\x02id\x18\x01 \x01(\tB\x0c\xbaH\tr\x07\x10\x02\x18\x80\x01h\x01R\x02id\x12,\n\x0b\x64\x65scription\x18\x02 \x01(\tB\n\xbaH\x07r\x05\x10\x02\x18\x80\x01R\x0b\x64\x65scription\x12(\n\x07rack_id\x18\x03 \x01(\tB\n\xbaH\x07r\x05\x10\x02\x18\x80\x01H\x00R\x06rackId\x88\x01\x01\x12(\n\tpartition\x18\x04 \x01(\tB\n\xbaH\x07r\x05\x10\x02\x18\x80\x01R\tpartition\x12;\n\x04type\x18\x05 \x01(\x0e\x32\x1d.metalstack.api.v2.SwitchTypeB\x08\xbaH\x05\x82\x01\x02\x10\x01R\x04type\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\x33\n\x0fmanagement_user\x18\x08 \x01(\tB\n\xbaH\x07r\x05\x10\x02\x18\x80\x01R\x0emanagementUser\x12\x33\n\x0f\x63onsole_command\x18\t \x01(\tB\n\xbaH\x07r\x05\x10\x02\x18\x80\x01R\x0e\x63onsoleCommand\x12=\n\x0bswitch_nics\x18\n \x03(\x0b\x32\x1c.metalstack.api.v2.SwitchNicR\nswitchNicsB\n\n\x08_rack_id\"\xaf\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\n\xbaH\x07r\x05\x10\x02\x18\x80\x01R\x07version\x12\x38\n\x12metal_core_version\x18\x03 \x01(\tB\n\xbaH\x07r\x05\x10\x02\x18\x80\x01R\x10metalCoreVersion\"\xd1\x03\n\tSwitchNic\x12\x1e\n\x04name\x18\x01 \x01(\tB\n\xbaH\x07r\x05\x10\x02\x18\x80\x01R\x04name\x12*\n\nidentifier\x18\x02 \x01(\tB\n\xbaH\x07r\x05\x10\x02\x18\x80\x01R\nidentifier\x12P\n\x0bmac_address\x18\x03 \x01(\tB/\xbaH,r*2(^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$R\nmacAddress\x12!\n\x03vrf\x18\x04 \x01(\tB\n\xbaH\x07r\x05\x10\x02\x18\x80\x01H\x00R\x03vrf\x88\x01\x01\x12\x45\n\x06\x61\x63tual\x18\x05 \x01(\x0e\x32#.metalstack.api.v2.SwitchPortStatusB\x08\xbaH\x05\x82\x01\x02\x10\x01R\x06\x61\x63tual\x12@\n\nbgp_filter\x18\x06 \x01(\x0b\x32\x1c.metalstack.api.v2.BGPFilterH\x01R\tbgpFilter\x88\x01\x01\x12P\n\x0e\x62gp_port_state\x18\x07 \x01(\x0b\x32%.metalstack.api.v2.SwitchBGPPortStateH\x02R\x0c\x62gpPortState\x88\x01\x01\x42\x06\n\x04_vrfB\r\n\x0b_bgp_filterB\x11\n\x0f_bgp_port_state\"\x92\x01\n\tBGPFilter\x12\x14\n\x05\x63idrs\x18\x01 \x03(\tR\x05\x63idrs\x12#\n\x04vnis\x18\x02 \x03(\tB\x0f\xbaH\x0c\x92\x01\t\"\x07r\x05\x10\x02\x18\x80\x01R\x04vnis:J\xbaHG\x1a\x45\n\x05\x63idrs\x12\x19given cidrs must be valid\x1a!this.cidrs.all(m, m.isIpPrefix())\"\x8e\x03\n\x12SwitchBGPPortState\x12&\n\x08neighbor\x18\x01 \x01(\tB\n\xbaH\x07r\x05\x10\x02\x18\x80\x01R\x08neighbor\x12)\n\npeer_group\x18\x02 \x01(\tB\n\xbaH\x07r\x05\x10\x02\x18\x80\x01R\tpeerGroup\x12%\n\x08vrf_name\x18\x03 \x01(\tB\n\xbaH\x07r\x05\x10\x02\x18\x80\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\x12R\n\x18\x62gp_timer_up_established\x18\x05 \x01(\x0b\x32\x19.google.protobuf.DurationR\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*\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\x63umulus\x12%\n\x16SWITCH_OS_VENDOR_SONIC\x10\x02\x1a\t\x82\xb2\x19\x05sonic*\x80\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*\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) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'metalstack.api.v2.switch_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None + _globals['DESCRIPTOR']._serialized_options = b'\n\025com.metalstack.api.v2B\013SwitchProtoP\001Z5github.com/metal-stack/api/go/metalstack/api/v2;apiv2\242\002\003MAX\252\002\021Metalstack.Api.V2\312\002\021Metalstack\\Api\\V2\342\002\035Metalstack\\Api\\V2\\GPBMetadata\352\002\023Metalstack::Api::V2' + _globals['_BGPSTATE'].values_by_name["BGP_STATE_IDLE"]._loaded_options = None + _globals['_BGPSTATE'].values_by_name["BGP_STATE_IDLE"]._serialized_options = b'\202\262\031\004idle' + _globals['_BGPSTATE'].values_by_name["BGP_STATE_CONNECT"]._loaded_options = None + _globals['_BGPSTATE'].values_by_name["BGP_STATE_CONNECT"]._serialized_options = b'\202\262\031\007connect' + _globals['_BGPSTATE'].values_by_name["BGP_STATE_ACTIVE"]._loaded_options = None + _globals['_BGPSTATE'].values_by_name["BGP_STATE_ACTIVE"]._serialized_options = b'\202\262\031\006active' + _globals['_BGPSTATE'].values_by_name["BGP_STATE_OPEN_SENT"]._loaded_options = None + _globals['_BGPSTATE'].values_by_name["BGP_STATE_OPEN_SENT"]._serialized_options = b'\202\262\031\topen-sent' + _globals['_BGPSTATE'].values_by_name["BGP_STATE_OPEN_CONFIRM"]._loaded_options = None + _globals['_BGPSTATE'].values_by_name["BGP_STATE_OPEN_CONFIRM"]._serialized_options = b'\202\262\031\014open-confirm' + _globals['_BGPSTATE'].values_by_name["BGP_STATE_ESTABLISHED"]._loaded_options = None + _globals['_BGPSTATE'].values_by_name["BGP_STATE_ESTABLISHED"]._serialized_options = b'\202\262\031\013established' + _globals['_SWITCHREPLACEMODE'].values_by_name["SWITCH_REPLACE_MODE_REPLACE"]._loaded_options = None + _globals['_SWITCHREPLACEMODE'].values_by_name["SWITCH_REPLACE_MODE_REPLACE"]._serialized_options = b'\202\262\031\007replace' + _globals['_SWITCHREPLACEMODE'].values_by_name["SWITCH_REPLACE_MODE_OPERATIONAL"]._loaded_options = None + _globals['_SWITCHREPLACEMODE'].values_by_name["SWITCH_REPLACE_MODE_OPERATIONAL"]._serialized_options = b'\202\262\031\013operational' + _globals['_SWITCHOSVENDOR'].values_by_name["SWITCH_OS_VENDOR_CUMULUS"]._loaded_options = None + _globals['_SWITCHOSVENDOR'].values_by_name["SWITCH_OS_VENDOR_CUMULUS"]._serialized_options = b'\202\262\031\007cumulus' + _globals['_SWITCHOSVENDOR'].values_by_name["SWITCH_OS_VENDOR_SONIC"]._loaded_options = None + _globals['_SWITCHOSVENDOR'].values_by_name["SWITCH_OS_VENDOR_SONIC"]._serialized_options = b'\202\262\031\005sonic' + _globals['_SWITCHPORTSTATUS'].values_by_name["SWITCH_PORT_STATUS_UP"]._loaded_options = None + _globals['_SWITCHPORTSTATUS'].values_by_name["SWITCH_PORT_STATUS_UP"]._serialized_options = b'\202\262\031\002up' + _globals['_SWITCHPORTSTATUS'].values_by_name["SWITCH_PORT_STATUS_DOWN"]._loaded_options = None + _globals['_SWITCHPORTSTATUS'].values_by_name["SWITCH_PORT_STATUS_DOWN"]._serialized_options = b'\202\262\031\004down' + _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\tr\007\020\002\030\200\001h\001' + _globals['_SWITCH'].fields_by_name['description']._loaded_options = None + _globals['_SWITCH'].fields_by_name['description']._serialized_options = b'\272H\007r\005\020\002\030\200\001' + _globals['_SWITCH'].fields_by_name['rack_id']._loaded_options = None + _globals['_SWITCH'].fields_by_name['rack_id']._serialized_options = b'\272H\007r\005\020\002\030\200\001' + _globals['_SWITCH'].fields_by_name['partition']._loaded_options = None + _globals['_SWITCH'].fields_by_name['partition']._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['_SWITCH'].fields_by_name['replace_mode']._loaded_options = None + _globals['_SWITCH'].fields_by_name['replace_mode']._serialized_options = b'\272H\005\202\001\002\020\001' + _globals['_SWITCH'].fields_by_name['management_ip']._loaded_options = None + _globals['_SWITCH'].fields_by_name['management_ip']._serialized_options = b'\272H\004r\002p\001' + _globals['_SWITCH'].fields_by_name['management_user']._loaded_options = None + _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['_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 + _globals['_SWITCHOS'].fields_by_name['version']._serialized_options = b'\272H\007r\005\020\002\030\200\001' + _globals['_SWITCHOS'].fields_by_name['metal_core_version']._loaded_options = None + _globals['_SWITCHOS'].fields_by_name['metal_core_version']._serialized_options = b'\272H\007r\005\020\002\030\200\001' + _globals['_SWITCHNIC'].fields_by_name['name']._loaded_options = None + _globals['_SWITCHNIC'].fields_by_name['name']._serialized_options = b'\272H\007r\005\020\002\030\200\001' + _globals['_SWITCHNIC'].fields_by_name['identifier']._loaded_options = None + _globals['_SWITCHNIC'].fields_by_name['identifier']._serialized_options = b'\272H\007r\005\020\002\030\200\001' + _globals['_SWITCHNIC'].fields_by_name['mac_address']._loaded_options = None + _globals['_SWITCHNIC'].fields_by_name['mac_address']._serialized_options = b'\272H,r*2(^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$' + _globals['_SWITCHNIC'].fields_by_name['vrf']._loaded_options = None + _globals['_SWITCHNIC'].fields_by_name['vrf']._serialized_options = b'\272H\007r\005\020\002\030\200\001' + _globals['_SWITCHNIC'].fields_by_name['actual']._loaded_options = None + _globals['_SWITCHNIC'].fields_by_name['actual']._serialized_options = b'\272H\005\202\001\002\020\001' + _globals['_BGPFILTER'].fields_by_name['vnis']._loaded_options = None + _globals['_BGPFILTER'].fields_by_name['vnis']._serialized_options = b'\272H\014\222\001\t\"\007r\005\020\002\030\200\001' + _globals['_BGPFILTER']._loaded_options = None + _globals['_BGPFILTER']._serialized_options = b'\272HG\032E\n\005cidrs\022\031given cidrs must be valid\032!this.cidrs.all(m, m.isIpPrefix())' + _globals['_SWITCHBGPPORTSTATE'].fields_by_name['neighbor']._loaded_options = None + _globals['_SWITCHBGPPORTSTATE'].fields_by_name['neighbor']._serialized_options = b'\272H\007r\005\020\002\030\200\001' + _globals['_SWITCHBGPPORTSTATE'].fields_by_name['peer_group']._loaded_options = None + _globals['_SWITCHBGPPORTSTATE'].fields_by_name['peer_group']._serialized_options = b'\272H\007r\005\020\002\030\200\001' + _globals['_SWITCHBGPPORTSTATE'].fields_by_name['vrf_name']._loaded_options = None + _globals['_SWITCHBGPPORTSTATE'].fields_by_name['vrf_name']._serialized_options = b'\272H\007r\005\020\002\030\200\001' + _globals['_SWITCHBGPPORTSTATE'].fields_by_name['bgp_state']._loaded_options = None + _globals['_SWITCHBGPPORTSTATE'].fields_by_name['bgp_state']._serialized_options = b'\272H\005\202\001\002\020\001' + _globals['_BGPSTATE']._serialized_start=1885 + _globals['_BGPSTATE']._serialized_end=2152 + _globals['_SWITCHREPLACEMODE']._serialized_start=2155 + _globals['_SWITCHREPLACEMODE']._serialized_end=2311 + _globals['_SWITCHOSVENDOR']._serialized_start=2314 + _globals['_SWITCHOSVENDOR']._serialized_end=2446 + _globals['_SWITCHPORTSTATUS']._serialized_start=2449 + _globals['_SWITCHPORTSTATUS']._serialized_end=2577 + _globals['_SWITCHTYPE']._serialized_start=2580 + _globals['_SWITCHTYPE']._serialized_end=2801 + _globals['_SWITCH']._serialized_start=147 + _globals['_SWITCH']._serialized_end=686 + _globals['_SWITCHOS']._serialized_start=689 + _globals['_SWITCHOS']._serialized_end=864 + _globals['_SWITCHNIC']._serialized_start=867 + _globals['_SWITCHNIC']._serialized_end=1332 + _globals['_BGPFILTER']._serialized_start=1335 + _globals['_BGPFILTER']._serialized_end=1481 + _globals['_SWITCHBGPPORTSTATE']._serialized_start=1484 + _globals['_SWITCHBGPPORTSTATE']._serialized_end=1882 +# @@protoc_insertion_point(module_scope) diff --git a/python/metalstack/api/v2/switch_pb2.pyi b/python/metalstack/api/v2/switch_pb2.pyi new file mode 100644 index 00000000..d565463b --- /dev/null +++ b/python/metalstack/api/v2/switch_pb2.pyi @@ -0,0 +1,150 @@ +import datetime + +from buf.validate import validate_pb2 as _validate_pb2 +from google.protobuf import duration_pb2 as _duration_pb2 +from metalstack.api.v2 import common_pb2 as _common_pb2 +from google.protobuf.internal import containers as _containers +from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +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 + +class BGPState(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = () + BGP_STATE_UNSPECIFIED: _ClassVar[BGPState] + BGP_STATE_IDLE: _ClassVar[BGPState] + BGP_STATE_CONNECT: _ClassVar[BGPState] + BGP_STATE_ACTIVE: _ClassVar[BGPState] + BGP_STATE_OPEN_SENT: _ClassVar[BGPState] + BGP_STATE_OPEN_CONFIRM: _ClassVar[BGPState] + BGP_STATE_ESTABLISHED: _ClassVar[BGPState] + +class SwitchReplaceMode(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = () + SWITCH_REPLACE_MODE_UNSPECIFIED: _ClassVar[SwitchReplaceMode] + SWITCH_REPLACE_MODE_REPLACE: _ClassVar[SwitchReplaceMode] + SWITCH_REPLACE_MODE_OPERATIONAL: _ClassVar[SwitchReplaceMode] + +class SwitchOSVendor(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = () + SWITCH_OS_VENDOR_UNSPECIFIED: _ClassVar[SwitchOSVendor] + SWITCH_OS_VENDOR_CUMULUS: _ClassVar[SwitchOSVendor] + SWITCH_OS_VENDOR_SONIC: _ClassVar[SwitchOSVendor] + +class SwitchPortStatus(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = () + SWITCH_PORT_STATUS_UNSPECIFIED: _ClassVar[SwitchPortStatus] + SWITCH_PORT_STATUS_UP: _ClassVar[SwitchPortStatus] + SWITCH_PORT_STATUS_DOWN: _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 +BGP_STATE_ACTIVE: BGPState +BGP_STATE_OPEN_SENT: BGPState +BGP_STATE_OPEN_CONFIRM: BGPState +BGP_STATE_ESTABLISHED: BGPState +SWITCH_REPLACE_MODE_UNSPECIFIED: SwitchReplaceMode +SWITCH_REPLACE_MODE_REPLACE: SwitchReplaceMode +SWITCH_REPLACE_MODE_OPERATIONAL: SwitchReplaceMode +SWITCH_OS_VENDOR_UNSPECIFIED: SwitchOSVendor +SWITCH_OS_VENDOR_CUMULUS: SwitchOSVendor +SWITCH_OS_VENDOR_SONIC: SwitchOSVendor +SWITCH_PORT_STATUS_UNSPECIFIED: SwitchPortStatus +SWITCH_PORT_STATUS_UP: SwitchPortStatus +SWITCH_PORT_STATUS_DOWN: 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", "description", "rack_id", "partition", "type", "replace_mode", "management_ip", "management_user", "console_command", "switch_nics") + ID_FIELD_NUMBER: _ClassVar[int] + DESCRIPTION_FIELD_NUMBER: _ClassVar[int] + RACK_ID_FIELD_NUMBER: _ClassVar[int] + PARTITION_FIELD_NUMBER: _ClassVar[int] + TYPE_FIELD_NUMBER: _ClassVar[int] + REPLACE_MODE_FIELD_NUMBER: _ClassVar[int] + MANAGEMENT_IP_FIELD_NUMBER: _ClassVar[int] + MANAGEMENT_USER_FIELD_NUMBER: _ClassVar[int] + CONSOLE_COMMAND_FIELD_NUMBER: _ClassVar[int] + SWITCH_NICS_FIELD_NUMBER: _ClassVar[int] + id: str + description: str + rack_id: str + partition: str + type: SwitchType + replace_mode: SwitchReplaceMode + management_ip: str + management_user: str + console_command: str + switch_nics: _containers.RepeatedCompositeFieldContainer[SwitchNic] + def __init__(self, id: _Optional[str] = ..., description: _Optional[str] = ..., rack_id: _Optional[str] = ..., partition: _Optional[str] = ..., type: _Optional[_Union[SwitchType, str]] = ..., replace_mode: _Optional[_Union[SwitchReplaceMode, str]] = ..., management_ip: _Optional[str] = ..., management_user: _Optional[str] = ..., console_command: _Optional[str] = ..., switch_nics: _Optional[_Iterable[_Union[SwitchNic, _Mapping]]] = ...) -> None: ... + +class SwitchOS(_message.Message): + __slots__ = ("vendor", "version", "metal_core_version") + VENDOR_FIELD_NUMBER: _ClassVar[int] + VERSION_FIELD_NUMBER: _ClassVar[int] + METAL_CORE_VERSION_FIELD_NUMBER: _ClassVar[int] + vendor: SwitchOSVendor + version: str + metal_core_version: str + def __init__(self, vendor: _Optional[_Union[SwitchOSVendor, str]] = ..., version: _Optional[str] = ..., metal_core_version: _Optional[str] = ...) -> None: ... + +class SwitchNic(_message.Message): + __slots__ = ("name", "identifier", "mac_address", "vrf", "actual", "bgp_filter", "bgp_port_state") + NAME_FIELD_NUMBER: _ClassVar[int] + IDENTIFIER_FIELD_NUMBER: _ClassVar[int] + MAC_ADDRESS_FIELD_NUMBER: _ClassVar[int] + VRF_FIELD_NUMBER: _ClassVar[int] + ACTUAL_FIELD_NUMBER: _ClassVar[int] + BGP_FILTER_FIELD_NUMBER: _ClassVar[int] + BGP_PORT_STATE_FIELD_NUMBER: _ClassVar[int] + name: str + identifier: str + mac_address: str + vrf: str + actual: SwitchPortStatus + bgp_filter: BGPFilter + bgp_port_state: SwitchBGPPortState + def __init__(self, name: _Optional[str] = ..., identifier: _Optional[str] = ..., mac_address: _Optional[str] = ..., vrf: _Optional[str] = ..., actual: _Optional[_Union[SwitchPortStatus, str]] = ..., bgp_filter: _Optional[_Union[BGPFilter, _Mapping]] = ..., bgp_port_state: _Optional[_Union[SwitchBGPPortState, _Mapping]] = ...) -> None: ... + +class BGPFilter(_message.Message): + __slots__ = ("cidrs", "vnis") + CIDRS_FIELD_NUMBER: _ClassVar[int] + VNIS_FIELD_NUMBER: _ClassVar[int] + cidrs: _containers.RepeatedScalarFieldContainer[str] + vnis: _containers.RepeatedScalarFieldContainer[str] + def __init__(self, cidrs: _Optional[_Iterable[str]] = ..., vnis: _Optional[_Iterable[str]] = ...) -> None: ... + +class SwitchBGPPortState(_message.Message): + __slots__ = ("neighbor", "peer_group", "vrf_name", "bgp_state", "bgp_timer_up_established", "sent_prefix_counter", "accepted_prefix_counter") + NEIGHBOR_FIELD_NUMBER: _ClassVar[int] + PEER_GROUP_FIELD_NUMBER: _ClassVar[int] + VRF_NAME_FIELD_NUMBER: _ClassVar[int] + BGP_STATE_FIELD_NUMBER: _ClassVar[int] + BGP_TIMER_UP_ESTABLISHED_FIELD_NUMBER: _ClassVar[int] + SENT_PREFIX_COUNTER_FIELD_NUMBER: _ClassVar[int] + ACCEPTED_PREFIX_COUNTER_FIELD_NUMBER: _ClassVar[int] + neighbor: str + peer_group: str + vrf_name: str + bgp_state: BGPState + bgp_timer_up_established: _duration_pb2.Duration + sent_prefix_counter: int + accepted_prefix_counter: int + def __init__(self, neighbor: _Optional[str] = ..., peer_group: _Optional[str] = ..., vrf_name: _Optional[str] = ..., bgp_state: _Optional[_Union[BGPState, str]] = ..., bgp_timer_up_established: _Optional[_Union[datetime.timedelta, _duration_pb2.Duration, _Mapping]] = ..., sent_prefix_counter: _Optional[int] = ..., accepted_prefix_counter: _Optional[int] = ...) -> None: ... diff --git a/python/metalstack/api/v2/switch_pb2_grpc.py b/python/metalstack/api/v2/switch_pb2_grpc.py new file mode 100644 index 00000000..2daafffe --- /dev/null +++ b/python/metalstack/api/v2/switch_pb2_grpc.py @@ -0,0 +1,4 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc + diff --git a/python/metalstack/infra/v2/switch_connecpy.py b/python/metalstack/infra/v2/switch_connecpy.py new file mode 100644 index 00000000..4fb27cbe --- /dev/null +++ b/python/metalstack/infra/v2/switch_connecpy.py @@ -0,0 +1,158 @@ +# -*- coding: utf-8 -*- +# Generated by https://github.com/i2y/connecpy/protoc-gen-connecpy. DO NOT EDIT! +# source: metalstack/infra/v2/switch.proto + +from typing import Optional, Protocol, Union + +import httpx + +from connecpy.async_client import AsyncConnecpyClient +from connecpy.base import Endpoint +from connecpy.server import ConnecpyServer +from connecpy.client import ConnecpyClient +from connecpy.context import ClientContext, ServiceContext +import metalstack.infra.v2.switch_pb2 as metalstack_dot_infra_dot_v2_dot_switch__pb2 + + +class SwitchService(Protocol): + async def Register(self, req: metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceRegisterRequest, ctx: ServiceContext) -> metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceRegisterResponse: ... + async def ReportBGPRoutes(self, req: metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceReportBGPRoutesRequest, ctx: ServiceContext) -> metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceReportBGPRoutesResponse: ... + + +class SwitchServiceServer(ConnecpyServer): + def __init__(self, *, service: SwitchService, server_path_prefix=""): + super().__init__() + self._prefix = f"{server_path_prefix}/metalstack.infra.v2.SwitchService" + self._endpoints = { + "Register": Endpoint[metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceRegisterRequest, metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceRegisterResponse]( + service_name="SwitchService", + name="Register", + function=getattr(service, "Register"), + input=metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceRegisterRequest, + output=metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceRegisterResponse, + allowed_methods=("POST",), + ), + "ReportBGPRoutes": Endpoint[metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceReportBGPRoutesRequest, metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceReportBGPRoutesResponse]( + service_name="SwitchService", + name="ReportBGPRoutes", + function=getattr(service, "ReportBGPRoutes"), + input=metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceReportBGPRoutesRequest, + output=metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceReportBGPRoutesResponse, + allowed_methods=("POST",), + ), + } + + def serviceName(self): + return "metalstack.infra.v2.SwitchService" + + +class SwitchServiceSync(Protocol): + def Register(self, req: metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceRegisterRequest, ctx: ServiceContext) -> metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceRegisterResponse: ... + def ReportBGPRoutes(self, req: metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceReportBGPRoutesRequest, ctx: ServiceContext) -> metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceReportBGPRoutesResponse: ... + + +class SwitchServiceServerSync(ConnecpyServer): + def __init__(self, *, service: SwitchServiceSync, server_path_prefix=""): + super().__init__() + self._prefix = f"{server_path_prefix}/metalstack.infra.v2.SwitchService" + self._endpoints = { + "Register": Endpoint[metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceRegisterRequest, metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceRegisterResponse]( + service_name="SwitchService", + name="Register", + function=getattr(service, "Register"), + input=metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceRegisterRequest, + output=metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceRegisterResponse, + allowed_methods=("POST",), + ), + "ReportBGPRoutes": Endpoint[metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceReportBGPRoutesRequest, metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceReportBGPRoutesResponse]( + service_name="SwitchService", + name="ReportBGPRoutes", + function=getattr(service, "ReportBGPRoutes"), + input=metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceReportBGPRoutesRequest, + output=metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceReportBGPRoutesResponse, + allowed_methods=("POST",), + ), + } + + def serviceName(self): + return "metalstack.infra.v2.SwitchService" + + +class SwitchServiceClient(ConnecpyClient): + def Register( + self, + request: metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceRegisterRequest, + *, + ctx: Optional[ClientContext] = None, + server_path_prefix: str = "", + **kwargs, + ) -> metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceRegisterResponse: + method = "POST" + return self._make_request( + url=f"{server_path_prefix}/metalstack.infra.v2.SwitchService/Register", + ctx=ctx, + request=request, + response_class=metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceRegisterResponse, + method=method, + **kwargs, + ) + + def ReportBGPRoutes( + self, + request: metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceReportBGPRoutesRequest, + *, + ctx: Optional[ClientContext] = None, + server_path_prefix: str = "", + **kwargs, + ) -> metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceReportBGPRoutesResponse: + method = "POST" + return self._make_request( + url=f"{server_path_prefix}/metalstack.infra.v2.SwitchService/ReportBGPRoutes", + ctx=ctx, + request=request, + response_class=metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceReportBGPRoutesResponse, + method=method, + **kwargs, + ) + + +class AsyncSwitchServiceClient(AsyncConnecpyClient): + async def Register( + self, + request: metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceRegisterRequest, + *, + ctx: Optional[ClientContext] = None, + server_path_prefix: str = "", + session: Union[httpx.AsyncClient, None] = None, + **kwargs, + ) -> metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceRegisterResponse: + method = "POST" + return await self._make_request( + url=f"{server_path_prefix}/metalstack.infra.v2.SwitchService/Register", + ctx=ctx, + request=request, + response_class=metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceRegisterResponse, + method=method, + session=session, + **kwargs, + ) + + async def ReportBGPRoutes( + self, + request: metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceReportBGPRoutesRequest, + *, + ctx: Optional[ClientContext] = None, + server_path_prefix: str = "", + session: Union[httpx.AsyncClient, None] = None, + **kwargs, + ) -> metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceReportBGPRoutesResponse: + method = "POST" + return await self._make_request( + url=f"{server_path_prefix}/metalstack.infra.v2.SwitchService/ReportBGPRoutes", + ctx=ctx, + request=request, + response_class=metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceReportBGPRoutesResponse, + method=method, + session=session, + **kwargs, + ) diff --git a/python/metalstack/infra/v2/switch_pb2.py b/python/metalstack/infra/v2/switch_pb2.py new file mode 100644 index 00000000..1c66336d --- /dev/null +++ b/python/metalstack/infra/v2/switch_pb2.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: metalstack/infra/v2/switch.proto +# Protobuf Python Version: 6.31.1 +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import runtime_version as _runtime_version +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 6, + 31, + 1, + '', + 'metalstack/infra/v2/switch.proto' +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from buf.validate import validate_pb2 as buf_dot_validate_dot_validate__pb2 +from metalstack.api.v2 import common_pb2 as metalstack_dot_api_dot_v2_dot_common__pb2 +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\x1emetalstack/api/v2/common.proto\x1a\x1emetalstack/api/v2/switch.proto\"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()2\xa3\x02\n\rSwitchService\x12}\n\x08Register\x12\x31.metalstack.infra.v2.SwitchServiceRegisterRequest\x1a\x32.metalstack.infra.v2.SwitchServiceRegisterResponse\"\n\xe0\xf3\x18\x02\xea\xf3\x18\x02\x01\x02\x12\x92\x01\n\x0fReportBGPRoutes\x12\x38.metalstack.infra.v2.SwitchServiceReportBGPRoutesRequest\x1a\x39.metalstack.infra.v2.SwitchServiceReportBGPRoutesResponse\"\n\xe0\xf3\x18\x02\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) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'metalstack.infra.v2.switch_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None + _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['_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['_SWITCHSERVICE'].methods_by_name['Register']._loaded_options = None + _globals['_SWITCHSERVICE'].methods_by_name['Register']._serialized_options = b'\340\363\030\002\352\363\030\002\001\002' + _globals['_SWITCHSERVICE'].methods_by_name['ReportBGPRoutes']._loaded_options = None + _globals['_SWITCHSERVICE'].methods_by_name['ReportBGPRoutes']._serialized_options = b'\340\363\030\002\352\363\030\002\001\002' + _globals['_SWITCHSERVICEREGISTERREQUEST']._serialized_start=150 + _globals['_SWITCHSERVICEREGISTERREQUEST']._serialized_end=231 + _globals['_SWITCHSERVICEREGISTERRESPONSE']._serialized_start=233 + _globals['_SWITCHSERVICEREGISTERRESPONSE']._serialized_end=315 + _globals['_SWITCHSERVICEREPORTBGPROUTESREQUEST']._serialized_start=318 + _globals['_SWITCHSERVICEREPORTBGPROUTESREQUEST']._serialized_end=460 + _globals['_SWITCHSERVICEREPORTBGPROUTESRESPONSE']._serialized_start=462 + _globals['_SWITCHSERVICEREPORTBGPROUTESRESPONSE']._serialized_end=500 + _globals['_BGPROUTE']._serialized_start=502 + _globals['_BGPROUTE']._serialized_end=601 + _globals['_SWITCHSERVICE']._serialized_start=604 + _globals['_SWITCHSERVICE']._serialized_end=895 +# @@protoc_insertion_point(module_scope) diff --git a/python/metalstack/infra/v2/switch_pb2.pyi b/python/metalstack/infra/v2/switch_pb2.pyi new file mode 100644 index 00000000..a2a3169d --- /dev/null +++ b/python/metalstack/infra/v2/switch_pb2.pyi @@ -0,0 +1,40 @@ +from buf.validate import validate_pb2 as _validate_pb2 +from metalstack.api.v2 import common_pb2 as _common_pb2 +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 Iterable as _Iterable, Mapping as _Mapping +from typing import ClassVar as _ClassVar, Optional as _Optional, Union as _Union + +DESCRIPTOR: _descriptor.FileDescriptor + +class SwitchServiceRegisterRequest(_message.Message): + __slots__ = ("switch",) + SWITCH_FIELD_NUMBER: _ClassVar[int] + switch: _switch_pb2.Switch + def __init__(self, switch: _Optional[_Union[_switch_pb2.Switch, _Mapping]] = ...) -> None: ... + +class SwitchServiceRegisterResponse(_message.Message): + __slots__ = ("switch",) + SWITCH_FIELD_NUMBER: _ClassVar[int] + 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: ... diff --git a/python/metalstack/infra/v2/switch_pb2_grpc.py b/python/metalstack/infra/v2/switch_pb2_grpc.py new file mode 100644 index 00000000..bb989b99 --- /dev/null +++ b/python/metalstack/infra/v2/switch_pb2_grpc.py @@ -0,0 +1,125 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc + +from metalstack.infra.v2 import switch_pb2 as metalstack_dot_infra_dot_v2_dot_switch__pb2 + + +class SwitchServiceStub(object): + """SwitchService serves switch related functions + """ + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.Register = channel.unary_unary( + '/metalstack.infra.v2.SwitchService/Register', + request_serializer=metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceRegisterRequest.SerializeToString, + response_deserializer=metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceRegisterResponse.FromString, + _registered_method=True) + self.ReportBGPRoutes = channel.unary_unary( + '/metalstack.infra.v2.SwitchService/ReportBGPRoutes', + request_serializer=metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceReportBGPRoutesRequest.SerializeToString, + response_deserializer=metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceReportBGPRoutesResponse.FromString, + _registered_method=True) + + +class SwitchServiceServicer(object): + """SwitchService serves switch related functions + """ + + def Register(self, request, context): + """Register a switch + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def ReportBGPRoutes(self, request, context): + """Report BGP routes of a switch + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_SwitchServiceServicer_to_server(servicer, server): + rpc_method_handlers = { + 'Register': grpc.unary_unary_rpc_method_handler( + servicer.Register, + request_deserializer=metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceRegisterRequest.FromString, + response_serializer=metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceRegisterResponse.SerializeToString, + ), + 'ReportBGPRoutes': grpc.unary_unary_rpc_method_handler( + servicer.ReportBGPRoutes, + request_deserializer=metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceReportBGPRoutesRequest.FromString, + response_serializer=metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceReportBGPRoutesResponse.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'metalstack.infra.v2.SwitchService', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + server.add_registered_method_handlers('metalstack.infra.v2.SwitchService', rpc_method_handlers) + + + # This class is part of an EXPERIMENTAL API. +class SwitchService(object): + """SwitchService serves switch related functions + """ + + @staticmethod + def Register(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/metalstack.infra.v2.SwitchService/Register', + metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceRegisterRequest.SerializeToString, + metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceRegisterResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def ReportBGPRoutes(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/metalstack.infra.v2.SwitchService/ReportBGPRoutes', + metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceReportBGPRoutesRequest.SerializeToString, + metalstack_dot_infra_dot_v2_dot_switch__pb2.SwitchServiceReportBGPRoutesResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) From c6afc984b9cd1c37acc4853f9f4f9fde96e7a05a Mon Sep 17 00:00:00 2001 From: Stefan Majer Date: Fri, 1 Aug 2025 14:03:08 +0200 Subject: [PATCH 6/8] Merge main --- python/metalstack/client/client.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/python/metalstack/client/client.py b/python/metalstack/client/client.py index 037b560a..0d8eaf08 100755 --- a/python/metalstack/client/client.py +++ b/python/metalstack/client/client.py @@ -26,6 +26,7 @@ import metalstack.api.v2.version_connecpy as api_version_connecpy import metalstack.infra.v2.bmc_connecpy as infra_bmc_connecpy +import metalstack.infra.v2.switch_connecpy as infra_switch_connecpy @@ -137,4 +138,7 @@ def __init__(self, baseurl: str, session=None): def bmc(self): return infra_bmc_connecpy.BMCServiceClient(address=self._baseurl, session=self._session) + def switch(self): + return infra_switch_connecpy.SwitchServiceClient(address=self._baseurl, session=self._session) + From 5434684c86c6b2c0a8d789d1af84718daeca9d08 Mon Sep 17 00:00:00 2001 From: Ilja Rotar Date: Thu, 18 Dec 2025 13:41:40 +0100 Subject: [PATCH 7/8] fix tests --- doc/index.html | 14 +++--- go/metalstack/api/v2/switch.pb.go | 66 ++++++++++++------------- go/tests/validation/common.go | 2 +- go/tests/validation/switch_test.go | 17 +++---- proto/metalstack/api/v2/switch.proto | 18 +++---- python/metalstack/api/v2/switch_pb2.py | 6 +-- python/metalstack/api/v2/switch_pb2.pyi | 8 +-- 7 files changed, 63 insertions(+), 68 deletions(-) diff --git a/doc/index.html b/doc/index.html index 5cd69e0c..aa5d8a4b 100644 --- a/doc/index.html +++ b/doc/index.html @@ -11529,13 +11529,6 @@

    Switch

    - - - - - - - @@ -11585,6 +11578,13 @@

    Switch

    + + + + + + +
    bgp_timer_up_establisheduint64google.protobuf.Duration

    BGP timer up established reports the uptime of this port's BGP connection

    partition_idpartition string

    Partition ID of the partition the switch belongs to

    Partition the switch belongs to

    Partition the switch belongs to.

    typeSwitchType

    Type is the role of the switch.

    replace_mode SwitchReplaceMode

    MachineConnections map machines to the nics they are connected to.

    typeSwitchType

    Type is the role of the switch.

    diff --git a/go/metalstack/api/v2/switch.pb.go b/go/metalstack/api/v2/switch.pb.go index 4b40e2b8..220f2f81 100644 --- a/go/metalstack/api/v2/switch.pb.go +++ b/go/metalstack/api/v2/switch.pb.go @@ -333,24 +333,24 @@ type Switch struct { Rack *string `protobuf:"bytes,4,opt,name=rack,proto3,oneof" json:"rack,omitempty"` // Partition the switch belongs to. Partition string `protobuf:"bytes,5,opt,name=partition,proto3" json:"partition,omitempty"` - // Type is the role of the switch. - Type SwitchType `protobuf:"varint,6,opt,name=type,proto3,enum=metalstack.api.v2.SwitchType" json:"type,omitempty"` // ReplaceMode is used to mark a switch ready for replacement. - ReplaceMode SwitchReplaceMode `protobuf:"varint,7,opt,name=replace_mode,json=replaceMode,proto3,enum=metalstack.api.v2.SwitchReplaceMode" json:"replace_mode,omitempty"` + ReplaceMode SwitchReplaceMode `protobuf:"varint,6,opt,name=replace_mode,json=replaceMode,proto3,enum=metalstack.api.v2.SwitchReplaceMode" json:"replace_mode,omitempty"` // ManagementIp is the switch's IP for management access. - ManagementIp string `protobuf:"bytes,8,opt,name=management_ip,json=managementIp,proto3" json:"management_ip,omitempty"` + ManagementIp string `protobuf:"bytes,7,opt,name=management_ip,json=managementIp,proto3" json:"management_ip,omitempty"` // ManagementUser is the user name to use for management access. - ManagementUser *string `protobuf:"bytes,9,opt,name=management_user,json=managementUser,proto3,oneof" json:"management_user,omitempty"` + ManagementUser *string `protobuf:"bytes,8,opt,name=management_user,json=managementUser,proto3,oneof" json:"management_user,omitempty"` // ConsoleCommand is the command for accessing the switch's console. - ConsoleCommand *string `protobuf:"bytes,10,opt,name=console_command,json=consoleCommand,proto3,oneof" json:"console_command,omitempty"` + ConsoleCommand *string `protobuf:"bytes,9,opt,name=console_command,json=consoleCommand,proto3,oneof" json:"console_command,omitempty"` // Nics are the front panel ports of the switch. - Nics []*SwitchNic `protobuf:"bytes,11,rep,name=nics,proto3" json:"nics,omitempty"` + Nics []*SwitchNic `protobuf:"bytes,10,rep,name=nics,proto3" json:"nics,omitempty"` // SwitchOs is the OS running on the switch. - Os *SwitchOS `protobuf:"bytes,12,opt,name=os,proto3" json:"os,omitempty"` + 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,13,rep,name=machine_connections,json=machineConnections,proto3" json:"machine_connections,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + MachineConnections []*MachineConnection `protobuf:"bytes,12,rep,name=machine_connections,json=machineConnections,proto3" json:"machine_connections,omitempty"` + // 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() { @@ -418,13 +418,6 @@ func (x *Switch) GetPartition() string { return "" } -func (x *Switch) GetType() SwitchType { - if x != nil { - return x.Type - } - return SwitchType_SWITCH_TYPE_UNSPECIFIED -} - func (x *Switch) GetReplaceMode() SwitchReplaceMode { if x != nil { return x.ReplaceMode @@ -474,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"` @@ -1043,18 +1043,18 @@ const file_metalstack_api_v2_switch_proto_rawDesc = "" + "\vdescription\x18\x03 \x01(\tB\n" + "\xbaH\ar\x05\x10\x02\x18\x80\x01R\vdescription\x12$\n" + "\x04rack\x18\x04 \x01(\tB\v\xbaH\br\x06\xc0\xb3\xae\xb1\x02\x01H\x00R\x04rack\x88\x01\x01\x12)\n" + - "\tpartition\x18\x05 \x01(\tB\v\xbaH\br\x06г\xae\xb1\x02\x01R\tpartition\x12;\n" + - "\x04type\x18\x06 \x01(\x0e2\x1d.metalstack.api.v2.SwitchTypeB\b\xbaH\x05\x82\x01\x02\x10\x01R\x04type\x12Q\n" + - "\freplace_mode\x18\a \x01(\x0e2$.metalstack.api.v2.SwitchReplaceModeB\b\xbaH\x05\x82\x01\x02\x10\x01R\vreplaceMode\x12,\n" + - "\rmanagement_ip\x18\b \x01(\tB\a\xbaH\x04r\x02p\x01R\fmanagementIp\x128\n" + - "\x0fmanagement_user\x18\t \x01(\tB\n" + + "\tpartition\x18\x05 \x01(\tB\v\xbaH\br\x06г\xae\xb1\x02\x01R\tpartition\x12Q\n" + + "\freplace_mode\x18\x06 \x01(\x0e2$.metalstack.api.v2.SwitchReplaceModeB\b\xbaH\x05\x82\x01\x02\x10\x01R\vreplaceMode\x12,\n" + + "\rmanagement_ip\x18\a \x01(\tB\a\xbaH\x04r\x02p\x01R\fmanagementIp\x128\n" + + "\x0fmanagement_user\x18\b \x01(\tB\n" + "\xbaH\ar\x05\x10\x02\x18\x80\x01H\x01R\x0emanagementUser\x88\x01\x01\x128\n" + - "\x0fconsole_command\x18\n" + - " \x01(\tB\n" + + "\x0fconsole_command\x18\t \x01(\tB\n" + "\xbaH\ar\x05\x10\x02\x18\x80\x01H\x02R\x0econsoleCommand\x88\x01\x01\x120\n" + - "\x04nics\x18\v \x03(\v2\x1c.metalstack.api.v2.SwitchNicR\x04nics\x12+\n" + - "\x02os\x18\f \x01(\v2\x1b.metalstack.api.v2.SwitchOSR\x02os\x12U\n" + - "\x13machine_connections\x18\r \x03(\v2$.metalstack.api.v2.MachineConnectionR\x12machineConnectionsB\a\n" + + "\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\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" + @@ -1181,11 +1181,11 @@ var file_metalstack_api_v2_switch_proto_goTypes = []any{ } var file_metalstack_api_v2_switch_proto_depIdxs = []int32{ 14, // 0: metalstack.api.v2.Switch.meta:type_name -> metalstack.api.v2.Meta - 4, // 1: metalstack.api.v2.Switch.type:type_name -> metalstack.api.v2.SwitchType - 1, // 2: metalstack.api.v2.Switch.replace_mode:type_name -> metalstack.api.v2.SwitchReplaceMode - 7, // 3: metalstack.api.v2.Switch.nics:type_name -> metalstack.api.v2.SwitchNic - 6, // 4: metalstack.api.v2.Switch.os:type_name -> metalstack.api.v2.SwitchOS - 11, // 5: metalstack.api.v2.Switch.machine_connections:type_name -> metalstack.api.v2.MachineConnection + 1, // 1: metalstack.api.v2.Switch.replace_mode:type_name -> metalstack.api.v2.SwitchReplaceMode + 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 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 faed3f8e..d8af3dd7 100644 --- a/go/tests/validation/switch_test.go +++ b/go/tests/validation/switch_test.go @@ -3,15 +3,10 @@ package validation import ( "testing" - "buf.build/go/protovalidate" apiv2 "github.com/metal-stack/api/go/metalstack/api/v2" - "github.com/stretchr/testify/require" ) func TestValidateMACAddress(t *testing.T) { - validator, err := protovalidate.New() - require.NoError(t, err) - tests := prototests{ { name: "Valid MAC address", @@ -30,7 +25,7 @@ func TestValidateMACAddress(t *testing.T) { Identifier: "Eth1/1", }, wantErr: true, - wantErrorMessage: "validation error:\n - mac: value does not match regex pattern `^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$` [string.pattern]", + wantErrorMessage: "validation error: mac: this string must be a valid macaddress", }, { name: "Too short", @@ -40,7 +35,7 @@ func TestValidateMACAddress(t *testing.T) { Identifier: "Eth1/1", }, wantErr: true, - wantErrorMessage: "validation error:\n - mac: value does not match regex pattern `^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$` [string.pattern]", + wantErrorMessage: "validation error: mac: this string must be a valid macaddress", }, { name: "Invalid separator", @@ -50,7 +45,7 @@ func TestValidateMACAddress(t *testing.T) { Identifier: "Eth1/1", }, wantErr: true, - wantErrorMessage: "validation error:\n - mac: value does not match regex pattern `^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$` [string.pattern]", + wantErrorMessage: "validation error: mac: this string must be a valid macaddress", }, { name: "Invalid character", @@ -60,7 +55,7 @@ func TestValidateMACAddress(t *testing.T) { Identifier: "Eth1/1", }, wantErr: true, - wantErrorMessage: "validation error:\n - mac: value does not match regex pattern `^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$` [string.pattern]", + wantErrorMessage: "validation error: mac: this string must be a valid macaddress", }, { name: "Uppercase and lowercase allowed", @@ -70,9 +65,9 @@ func TestValidateMACAddress(t *testing.T) { Identifier: "Eth1/1", }, wantErr: true, - wantErrorMessage: "validation error:\n - mac: value does not match regex pattern `^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$` [string.pattern]", + wantErrorMessage: "validation error: mac: this string must be a valid macaddress", }, } - validateProtos(t, tests, validator) + validateProtos(t, tests) } diff --git a/proto/metalstack/api/v2/switch.proto b/proto/metalstack/api/v2/switch.proto index e77b13b9..71486f47 100644 --- a/proto/metalstack/api/v2/switch.proto +++ b/proto/metalstack/api/v2/switch.proto @@ -25,28 +25,28 @@ message Switch { optional string rack = 4 [(buf.validate.field).string.(metalstack.api.v2.is_name) = true]; // Partition the switch belongs to. string partition = 5 [(buf.validate.field).string.(metalstack.api.v2.is_partition) = true]; - // Type is the role of the switch. - SwitchType type = 6 [(buf.validate.field).enum.defined_only = true]; // ReplaceMode is used to mark a switch ready for replacement. - SwitchReplaceMode replace_mode = 7 [(buf.validate.field).enum.defined_only = true]; + SwitchReplaceMode replace_mode = 6 [(buf.validate.field).enum.defined_only = true]; // ManagementIp is the switch's IP for management access. - string management_ip = 8 [(buf.validate.field).string.ip = true]; + string management_ip = 7 [(buf.validate.field).string.ip = true]; // ManagementUser is the user name to use for management access. - optional string management_user = 9 [(buf.validate.field).string = { + optional string management_user = 8 [(buf.validate.field).string = { min_len: 2 max_len: 128 }]; // ConsoleCommand is the command for accessing the switch's console. - optional string console_command = 10 [(buf.validate.field).string = { + optional string console_command = 9 [(buf.validate.field).string = { min_len: 2 max_len: 128 }]; // Nics are the front panel ports of the switch. - repeated SwitchNic nics = 11; + repeated SwitchNic nics = 10; // SwitchOs is the OS running on the switch. - SwitchOS os = 12; + SwitchOS os = 11; // MachineConnections map machines to the nics they are connected to. - repeated MachineConnection machine_connections = 13; + 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. diff --git a/python/metalstack/api/v2/switch_pb2.py b/python/metalstack/api/v2/switch_pb2.py index 0238d28a..e14ec265 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\"\xec\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\n\xbaH\x07r\x05\x10\x02\x18\x80\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\x12;\n\x04type\x18\x06 \x01(\x0e\x32\x1d.metalstack.api.v2.SwitchTypeB\x08\xbaH\x05\x82\x01\x02\x10\x01R\x04type\x12Q\n\x0creplace_mode\x18\x07 \x01(\x0e\x32$.metalstack.api.v2.SwitchReplaceModeB\x08\xbaH\x05\x82\x01\x02\x10\x01R\x0breplaceMode\x12,\n\rmanagement_ip\x18\x08 \x01(\tB\x07\xbaH\x04r\x02p\x01R\x0cmanagementIp\x12\x38\n\x0fmanagement_user\x18\t \x01(\tB\n\xbaH\x07r\x05\x10\x02\x18\x80\x01H\x01R\x0emanagementUser\x88\x01\x01\x12\x38\n\x0f\x63onsole_command\x18\n \x01(\tB\n\xbaH\x07r\x05\x10\x02\x18\x80\x01H\x02R\x0e\x63onsoleCommand\x88\x01\x01\x12\x30\n\x04nics\x18\x0b \x03(\x0b\x32\x1c.metalstack.api.v2.SwitchNicR\x04nics\x12+\n\x02os\x18\x0c \x01(\x0b\x32\x1b.metalstack.api.v2.SwitchOSR\x02os\x12U\n\x13machine_connections\x18\r \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\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') +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\"\xec\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\n\xbaH\x07r\x05\x10\x02\x18\x80\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) @@ -80,8 +80,6 @@ _globals['_SWITCH'].fields_by_name['rack']._serialized_options = b'\272H\010r\006\300\263\256\261\002\001' _globals['_SWITCH'].fields_by_name['partition']._loaded_options = None _globals['_SWITCH'].fields_by_name['partition']._serialized_options = b'\272H\010r\006\320\263\256\261\002\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['_SWITCH'].fields_by_name['replace_mode']._loaded_options = None _globals['_SWITCH'].fields_by_name['replace_mode']._serialized_options = b'\272H\005\202\001\002\020\001' _globals['_SWITCH'].fields_by_name['management_ip']._loaded_options = None @@ -90,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 diff --git a/python/metalstack/api/v2/switch_pb2.pyi b/python/metalstack/api/v2/switch_pb2.pyi index c8a0b359..3df2c25a 100644 --- a/python/metalstack/api/v2/switch_pb2.pyi +++ b/python/metalstack/api/v2/switch_pb2.pyi @@ -75,13 +75,12 @@ SWITCH_TYPE_MGMTLEAF: SwitchType SWITCH_TYPE_MGMTSPINE: SwitchType class Switch(_message.Message): - __slots__ = ("id", "meta", "description", "rack", "partition", "type", "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] RACK_FIELD_NUMBER: _ClassVar[int] PARTITION_FIELD_NUMBER: _ClassVar[int] - TYPE_FIELD_NUMBER: _ClassVar[int] REPLACE_MODE_FIELD_NUMBER: _ClassVar[int] MANAGEMENT_IP_FIELD_NUMBER: _ClassVar[int] MANAGEMENT_USER_FIELD_NUMBER: _ClassVar[int] @@ -89,12 +88,12 @@ 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 rack: str partition: str - type: SwitchType replace_mode: SwitchReplaceMode management_ip: str management_user: str @@ -102,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] = ..., type: _Optional[_Union[SwitchType, 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") From be33a1caab06e4c5928f84ca83e4f4f2d0e03a66 Mon Sep 17 00:00:00 2001 From: Ilja Rotar Date: Thu, 18 Dec 2025 13:43:21 +0100 Subject: [PATCH 8/8] revert switch description change --- go/metalstack/api/v2/switch.pb.go | 7 ++-- proto/metalstack/api/v2/switch.proto | 5 +-- python/metalstack/api/v2/switch_pb2.py | 58 +++++++++++++------------- 3 files changed, 33 insertions(+), 37 deletions(-) diff --git a/go/metalstack/api/v2/switch.pb.go b/go/metalstack/api/v2/switch.pb.go index 220f2f81..1a5cd8e4 100644 --- a/go/metalstack/api/v2/switch.pb.go +++ b/go/metalstack/api/v2/switch.pb.go @@ -1035,13 +1035,12 @@ 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\"\xec\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" + - "\x04meta\x18\x02 \x01(\v2\x17.metalstack.api.v2.MetaR\x04meta\x12,\n" + - "\vdescription\x18\x03 \x01(\tB\n" + - "\xbaH\ar\x05\x10\x02\x18\x80\x01R\vdescription\x12$\n" + + "\x04meta\x18\x02 \x01(\v2\x17.metalstack.api.v2.MetaR\x04meta\x12-\n" + + "\vdescription\x18\x03 \x01(\tB\v\xbaH\br\x06ȳ\xae\xb1\x02\x01R\vdescription\x12$\n" + "\x04rack\x18\x04 \x01(\tB\v\xbaH\br\x06\xc0\xb3\xae\xb1\x02\x01H\x00R\x04rack\x88\x01\x01\x12)\n" + "\tpartition\x18\x05 \x01(\tB\v\xbaH\br\x06г\xae\xb1\x02\x01R\tpartition\x12Q\n" + "\freplace_mode\x18\x06 \x01(\x0e2$.metalstack.api.v2.SwitchReplaceModeB\b\xbaH\x05\x82\x01\x02\x10\x01R\vreplaceMode\x12,\n" + diff --git a/proto/metalstack/api/v2/switch.proto b/proto/metalstack/api/v2/switch.proto index 71486f47..2ba315a1 100644 --- a/proto/metalstack/api/v2/switch.proto +++ b/proto/metalstack/api/v2/switch.proto @@ -17,10 +17,7 @@ message Switch { // Meta for this switch. Meta meta = 2; // Description of the switch. - string description = 3 [(buf.validate.field).string = { - min_len: 2 - max_len: 128 - }]; + string description = 3 [(buf.validate.field).string.(metalstack.api.v2.is_description) = true]; // Rack ID if the switch resides in a rack. optional string rack = 4 [(buf.validate.field).string.(metalstack.api.v2.is_name) = true]; // Partition the switch belongs to. diff --git a/python/metalstack/api/v2/switch_pb2.py b/python/metalstack/api/v2/switch_pb2.py index e14ec265..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\"\xec\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\n\xbaH\x07r\x05\x10\x02\x18\x80\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') +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) @@ -75,7 +75,7 @@ _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 - _globals['_SWITCH'].fields_by_name['description']._serialized_options = b'\272H\007r\005\020\002\030\200\001' + _globals['_SWITCH'].fields_by_name['description']._serialized_options = b'\272H\010r\006\310\263\256\261\002\001' _globals['_SWITCH'].fields_by_name['rack']._loaded_options = None _globals['_SWITCH'].fields_by_name['rack']._serialized_options = b'\272H\010r\006\300\263\256\261\002\001' _globals['_SWITCH'].fields_by_name['partition']._loaded_options = None @@ -130,32 +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=2690 - _globals['_BGPSTATE']._serialized_end=2957 - _globals['_SWITCHREPLACEMODE']._serialized_start=2960 - _globals['_SWITCHREPLACEMODE']._serialized_end=3116 - _globals['_SWITCHOSVENDOR']._serialized_start=3119 - _globals['_SWITCHOSVENDOR']._serialized_end=3251 - _globals['_SWITCHPORTSTATUS']._serialized_start=3254 - _globals['_SWITCHPORTSTATUS']._serialized_end=3427 - _globals['_SWITCHTYPE']._serialized_start=3430 - _globals['_SWITCHTYPE']._serialized_end=3651 + _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=938 - _globals['_SWITCHOS']._serialized_start=941 - _globals['_SWITCHOS']._serialized_end=1118 - _globals['_SWITCHNIC']._serialized_start=1121 - _globals['_SWITCHNIC']._serialized_end=1533 - _globals['_BGPFILTER']._serialized_start=1535 - _globals['_BGPFILTER']._serialized_end=1619 - _globals['_SWITCHBGPPORTSTATE']._serialized_start=1622 - _globals['_SWITCHBGPPORTSTATE']._serialized_end=2024 - _globals['_NICSTATE']._serialized_start=2027 - _globals['_NICSTATE']._serialized_end=2198 - _globals['_MACHINECONNECTION']._serialized_start=2200 - _globals['_MACHINECONNECTION']._serialized_end=2298 - _globals['_SWITCHQUERY']._serialized_start=2301 - _globals['_SWITCHQUERY']._serialized_end=2528 - _globals['_SWITCHOSQUERY']._serialized_start=2531 - _globals['_SWITCHOSQUERY']._serialized_end=2687 + _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)