From 136b8842369bd385236cc4f99d38e1d3fed4e5f2 Mon Sep 17 00:00:00 2001 From: Nikhil Malik Date: Thu, 22 Feb 2024 16:40:06 +0900 Subject: [PATCH] BFD session get and set API added --- api/models/bfd_entry.go | 62 +++ api/models/bfd_get_entry.go | 68 ++++ api/restapi/configure_loxilb_rest_api.go | 4 + api/restapi/embedded_spec.go | 334 +++++++++++++++++ api/restapi/handler/cluster.go | 47 +++ api/restapi/operations/get_config_bfd_all.go | 166 ++++++++ .../get_config_bfd_all_parameters.go | 46 +++ .../get_config_bfd_all_responses.go | 194 ++++++++++ .../get_config_bfd_all_urlbuilder.go | 87 +++++ api/restapi/operations/loxilb_rest_api_api.go | 24 ++ api/restapi/operations/post_config_bfd.go | 58 +++ .../operations/post_config_bfd_parameters.go | 84 +++++ .../operations/post_config_bfd_responses.go | 354 ++++++++++++++++++ .../operations/post_config_bfd_urlbuilder.go | 87 +++++ api/swagger.yml | 122 ++++++ common/common.go | 22 ++ loxinet/apiclient.go | 27 ++ loxinet/cluster.go | 42 ++- proto/bfd.go | 51 ++- 19 files changed, 1872 insertions(+), 7 deletions(-) create mode 100644 api/models/bfd_entry.go create mode 100644 api/models/bfd_get_entry.go create mode 100644 api/restapi/operations/get_config_bfd_all.go create mode 100644 api/restapi/operations/get_config_bfd_all_parameters.go create mode 100644 api/restapi/operations/get_config_bfd_all_responses.go create mode 100644 api/restapi/operations/get_config_bfd_all_urlbuilder.go create mode 100644 api/restapi/operations/post_config_bfd.go create mode 100644 api/restapi/operations/post_config_bfd_parameters.go create mode 100644 api/restapi/operations/post_config_bfd_responses.go create mode 100644 api/restapi/operations/post_config_bfd_urlbuilder.go diff --git a/api/models/bfd_entry.go b/api/models/bfd_entry.go new file mode 100644 index 00000000..84dd57d3 --- /dev/null +++ b/api/models/bfd_entry.go @@ -0,0 +1,62 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package models + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" +) + +// BfdEntry bfd entry +// +// swagger:model BfdEntry +type BfdEntry struct { + + // Instance name running BFD session + Instance string `json:"instance,omitempty"` + + // Tx interval between BFD packets(in microseconds) + Interval uint64 `json:"interval,omitempty"` + + // Remote IP + RemoteIP string `json:"remoteIp,omitempty"` + + // Retry Count to detect failure + RetryCount uint8 `json:"retryCount,omitempty"` + + // Remote IP + SourceIP string `json:"sourceIp,omitempty"` +} + +// Validate validates this bfd entry +func (m *BfdEntry) Validate(formats strfmt.Registry) error { + return nil +} + +// ContextValidate validates this bfd entry based on context it is used +func (m *BfdEntry) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (m *BfdEntry) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *BfdEntry) UnmarshalBinary(b []byte) error { + var res BfdEntry + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/api/models/bfd_get_entry.go b/api/models/bfd_get_entry.go new file mode 100644 index 00000000..35e5f426 --- /dev/null +++ b/api/models/bfd_get_entry.go @@ -0,0 +1,68 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package models + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" +) + +// BfdGetEntry bfd get entry +// +// swagger:model BfdGetEntry +type BfdGetEntry struct { + + // Instance name + Instance string `json:"instance,omitempty"` + + // Tx interval between BFD packets(in microseconds) + Interval uint64 `json:"interval,omitempty"` + + // port number to be used for BFD session + Port uint16 `json:"port,omitempty"` + + // Remote IP + RemoteIP string `json:"remoteIp,omitempty"` + + // Retry Count to detect failure + RetryCount uint8 `json:"retryCount,omitempty"` + + // Source IP to be used for BFD session + SourceIP string `json:"sourceIP,omitempty"` + + // Current state for BFD session + State string `json:"state,omitempty"` +} + +// Validate validates this bfd get entry +func (m *BfdGetEntry) Validate(formats strfmt.Registry) error { + return nil +} + +// ContextValidate validates this bfd get entry based on context it is used +func (m *BfdGetEntry) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (m *BfdGetEntry) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *BfdGetEntry) UnmarshalBinary(b []byte) error { + var res BfdGetEntry + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/api/restapi/configure_loxilb_rest_api.go b/api/restapi/configure_loxilb_rest_api.go index 14810033..bd786bd8 100644 --- a/api/restapi/configure_loxilb_rest_api.go +++ b/api/restapi/configure_loxilb_rest_api.go @@ -135,6 +135,10 @@ func configureAPI(api *operations.LoxilbRestAPIAPI) http.Handler { api.GetConfigCistateAllHandler = operations.GetConfigCistateAllHandlerFunc(handler.ConfigGetCIState) api.PostConfigCistateHandler = operations.PostConfigCistateHandlerFunc(handler.ConfigPostCIState) + // BFD + api.GetConfigBfdAllHandler = operations.GetConfigBfdAllHandlerFunc(handler.ConfigGetBFDSession) + api.PostConfigBfdHandler = operations.PostConfigBfdHandlerFunc(handler.ConfigPostBFDSession) + // Firewall api.GetConfigFirewallAllHandler = operations.GetConfigFirewallAllHandlerFunc(handler.ConfigGetFW) api.PostConfigFirewallHandler = operations.PostConfigFirewallHandlerFunc(handler.ConfigPostFW) diff --git a/api/restapi/embedded_spec.go b/api/restapi/embedded_spec.go index c8716d11..1d7053ea 100644 --- a/api/restapi/embedded_spec.go +++ b/api/restapi/embedded_spec.go @@ -37,6 +37,110 @@ func init() { "host": "0.0.0.0:11111", "basePath": "/netlox/v1", "paths": { + "/config/bfd": { + "post": { + "description": "Create vlan interface in the device", + "summary": "Create vlan interface in the device", + "parameters": [ + { + "description": "Attributes for Vlan Interface", + "name": "attr", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/BfdEntry" + } + } + ], + "responses": { + "204": { + "description": "OK" + }, + "400": { + "description": "Malformed arguments for API call", + "schema": { + "$ref": "#/definitions/Error" + } + }, + "401": { + "description": "Invalid authentication credentials", + "schema": { + "$ref": "#/definitions/Error" + } + }, + "403": { + "description": "Capacity insufficient", + "schema": { + "$ref": "#/definitions/Error" + } + }, + "404": { + "description": "Resource not found", + "schema": { + "$ref": "#/definitions/Error" + } + }, + "409": { + "description": "Resource Conflict. BFD session not found", + "schema": { + "$ref": "#/definitions/Error" + } + }, + "500": { + "description": "Internal service error", + "schema": { + "$ref": "#/definitions/Error" + } + }, + "503": { + "description": "Maintanence mode", + "schema": { + "$ref": "#/definitions/Error" + } + } + } + } + }, + "/config/bfd/all": { + "get": { + "description": "Get BFD session inforrmation", + "summary": "Get BFD session inforrmation in the device", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "properties": { + "Attr": { + "type": "array", + "items": { + "$ref": "#/definitions/BfdGetEntry" + } + } + } + } + }, + "401": { + "description": "Invalid authentication credentials", + "schema": { + "$ref": "#/definitions/Error" + } + }, + "500": { + "description": "Internal service error", + "schema": { + "$ref": "#/definitions/Error" + } + }, + "503": { + "description": "Maintanence mode", + "schema": { + "$ref": "#/definitions/Error" + } + } + } + } + }, "/config/bgp/global": { "post": { "description": "Adds a BGP global config", @@ -3359,6 +3463,69 @@ func init() { } } }, + "BfdEntry": { + "type": "object", + "properties": { + "instance": { + "description": "Instance name running BFD session", + "type": "string" + }, + "interval": { + "description": "Tx interval between BFD packets(in microseconds)", + "type": "integer", + "format": "uint64" + }, + "remoteIp": { + "description": "Remote IP", + "type": "string" + }, + "retryCount": { + "description": "Retry Count to detect failure", + "type": "integer", + "format": "uint8" + }, + "sourceIp": { + "description": "Remote IP", + "type": "string" + } + } + }, + "BfdGetEntry": { + "type": "object", + "properties": { + "instance": { + "description": "Instance name", + "type": "string" + }, + "interval": { + "description": "Tx interval between BFD packets(in microseconds)", + "type": "integer", + "format": "uint64" + }, + "port": { + "description": "port number to be used for BFD session", + "type": "integer", + "format": "uint16" + }, + "remoteIp": { + "description": "Remote IP", + "type": "string" + }, + "retryCount": { + "description": "Retry Count to detect failure", + "type": "integer", + "format": "uint8" + }, + "sourceIP": { + "description": "Source IP to be used for BFD session", + "type": "string" + }, + "state": { + "description": "Current state for BFD session", + "type": "string" + } + } + }, "CIStatusEntry": { "type": "object", "properties": { @@ -4512,6 +4679,110 @@ func init() { "host": "0.0.0.0:11111", "basePath": "/netlox/v1", "paths": { + "/config/bfd": { + "post": { + "description": "Create vlan interface in the device", + "summary": "Create vlan interface in the device", + "parameters": [ + { + "description": "Attributes for Vlan Interface", + "name": "attr", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/BfdEntry" + } + } + ], + "responses": { + "204": { + "description": "OK" + }, + "400": { + "description": "Malformed arguments for API call", + "schema": { + "$ref": "#/definitions/Error" + } + }, + "401": { + "description": "Invalid authentication credentials", + "schema": { + "$ref": "#/definitions/Error" + } + }, + "403": { + "description": "Capacity insufficient", + "schema": { + "$ref": "#/definitions/Error" + } + }, + "404": { + "description": "Resource not found", + "schema": { + "$ref": "#/definitions/Error" + } + }, + "409": { + "description": "Resource Conflict. BFD session not found", + "schema": { + "$ref": "#/definitions/Error" + } + }, + "500": { + "description": "Internal service error", + "schema": { + "$ref": "#/definitions/Error" + } + }, + "503": { + "description": "Maintanence mode", + "schema": { + "$ref": "#/definitions/Error" + } + } + } + } + }, + "/config/bfd/all": { + "get": { + "description": "Get BFD session inforrmation", + "summary": "Get BFD session inforrmation in the device", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "properties": { + "Attr": { + "type": "array", + "items": { + "$ref": "#/definitions/BfdGetEntry" + } + } + } + } + }, + "401": { + "description": "Invalid authentication credentials", + "schema": { + "$ref": "#/definitions/Error" + } + }, + "500": { + "description": "Internal service error", + "schema": { + "$ref": "#/definitions/Error" + } + }, + "503": { + "description": "Maintanence mode", + "schema": { + "$ref": "#/definitions/Error" + } + } + } + } + }, "/config/bgp/global": { "post": { "description": "Adds a BGP global config", @@ -7834,6 +8105,69 @@ func init() { } } }, + "BfdEntry": { + "type": "object", + "properties": { + "instance": { + "description": "Instance name running BFD session", + "type": "string" + }, + "interval": { + "description": "Tx interval between BFD packets(in microseconds)", + "type": "integer", + "format": "uint64" + }, + "remoteIp": { + "description": "Remote IP", + "type": "string" + }, + "retryCount": { + "description": "Retry Count to detect failure", + "type": "integer", + "format": "uint8" + }, + "sourceIp": { + "description": "Remote IP", + "type": "string" + } + } + }, + "BfdGetEntry": { + "type": "object", + "properties": { + "instance": { + "description": "Instance name", + "type": "string" + }, + "interval": { + "description": "Tx interval between BFD packets(in microseconds)", + "type": "integer", + "format": "uint64" + }, + "port": { + "description": "port number to be used for BFD session", + "type": "integer", + "format": "uint16" + }, + "remoteIp": { + "description": "Remote IP", + "type": "string" + }, + "retryCount": { + "description": "Retry Count to detect failure", + "type": "integer", + "format": "uint8" + }, + "sourceIP": { + "description": "Source IP to be used for BFD session", + "type": "string" + }, + "state": { + "description": "Current state for BFD session", + "type": "string" + } + } + }, "CIStatusEntry": { "type": "object", "properties": { diff --git a/api/restapi/handler/cluster.go b/api/restapi/handler/cluster.go index eb27c5e2..c4a8ea43 100644 --- a/api/restapi/handler/cluster.go +++ b/api/restapi/handler/cluster.go @@ -62,3 +62,50 @@ func ConfigPostCIState(params operations.PostConfigCistateParams) middleware.Res } return &ResultResponse{Result: "Success"} } + +func ConfigGetBFDSession(params operations.GetConfigBfdAllParams) middleware.Responder { + var result []*models.BfdGetEntry + result = make([]*models.BfdGetEntry, 0) + tk.LogIt(tk.LogDebug, "[API] Status %s API called. url : %s\n", params.HTTPRequest.Method, params.HTTPRequest.URL) + bfdMod, err := ApiHooks.NetBFDGet() + if err != nil { + tk.LogIt(tk.LogDebug, "[API] Error occur : %v\n", err) + return &ResultResponse{Result: err.Error()} + } + for _, h := range bfdMod { + var tempResult models.BfdGetEntry + tempResult.Instance = h.Instance + tempResult.RemoteIP = h.RemoteIP.String() + tempResult.SourceIP = h.SourceIP.String() + tempResult.Interval = h.Interval + tempResult.Port = h.Port + tempResult.RetryCount = h.RetryCount + tempResult.State = h.State + + result = append(result, &tempResult) + } + + return operations.NewGetConfigBfdAllOK().WithPayload(&operations.GetConfigBfdAllOKBody{Attr: result}) +} + +func ConfigPostBFDSession(params operations.PostConfigBfdParams) middleware.Responder { + tk.LogIt(tk.LogDebug, "[API] HA %s API called. url : %s\n", params.HTTPRequest.Method, params.HTTPRequest.URL) + + var bfdMod cmn.BFDMod + + // Update BFD Session + bfdMod.Instance = params.Attr.Instance + bfdMod.RemoteIP = net.ParseIP(params.Attr.RemoteIP) + bfdMod.SourceIP = net.ParseIP(params.Attr.SourceIP) + bfdMod.Interval = params.Attr.Interval + bfdMod.RetryCount = params.Attr.RetryCount + + tk.LogIt(tk.LogDebug, "[API] Instance %s BFD session update : %s, Interval: %d, RetryCount: %d\n", + bfdMod.Instance, bfdMod.RemoteIP, bfdMod.Interval, bfdMod.RetryCount) + _, err := ApiHooks.NetBFDAdd(&bfdMod) + if err != nil { + tk.LogIt(tk.LogDebug, "[API] Error occur : %v\n", err) + return &ResultResponse{Result: err.Error()} + } + return &ResultResponse{Result: "Success"} +} diff --git a/api/restapi/operations/get_config_bfd_all.go b/api/restapi/operations/get_config_bfd_all.go new file mode 100644 index 00000000..1450cf53 --- /dev/null +++ b/api/restapi/operations/get_config_bfd_all.go @@ -0,0 +1,166 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the generate command + +import ( + "context" + "net/http" + "strconv" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime/middleware" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" + + "github.com/loxilb-io/loxilb/api/models" +) + +// GetConfigBfdAllHandlerFunc turns a function with the right signature into a get config bfd all handler +type GetConfigBfdAllHandlerFunc func(GetConfigBfdAllParams) middleware.Responder + +// Handle executing the request and returning a response +func (fn GetConfigBfdAllHandlerFunc) Handle(params GetConfigBfdAllParams) middleware.Responder { + return fn(params) +} + +// GetConfigBfdAllHandler interface for that can handle valid get config bfd all params +type GetConfigBfdAllHandler interface { + Handle(GetConfigBfdAllParams) middleware.Responder +} + +// NewGetConfigBfdAll creates a new http.Handler for the get config bfd all operation +func NewGetConfigBfdAll(ctx *middleware.Context, handler GetConfigBfdAllHandler) *GetConfigBfdAll { + return &GetConfigBfdAll{Context: ctx, Handler: handler} +} + +/* + GetConfigBfdAll swagger:route GET /config/bfd/all getConfigBfdAll + +# Get BFD session inforrmation in the device + +Get BFD session inforrmation +*/ +type GetConfigBfdAll struct { + Context *middleware.Context + Handler GetConfigBfdAllHandler +} + +func (o *GetConfigBfdAll) ServeHTTP(rw http.ResponseWriter, r *http.Request) { + route, rCtx, _ := o.Context.RouteInfo(r) + if rCtx != nil { + *r = *rCtx + } + var Params = NewGetConfigBfdAllParams() + if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params + o.Context.Respond(rw, r, route.Produces, route, err) + return + } + + res := o.Handler.Handle(Params) // actually handle the request + o.Context.Respond(rw, r, route.Produces, route, res) + +} + +// GetConfigBfdAllOKBody get config bfd all o k body +// +// swagger:model GetConfigBfdAllOKBody +type GetConfigBfdAllOKBody struct { + + // attr + Attr []*models.BfdGetEntry `json:"Attr"` +} + +// Validate validates this get config bfd all o k body +func (o *GetConfigBfdAllOKBody) Validate(formats strfmt.Registry) error { + var res []error + + if err := o.validateAttr(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *GetConfigBfdAllOKBody) validateAttr(formats strfmt.Registry) error { + if swag.IsZero(o.Attr) { // not required + return nil + } + + for i := 0; i < len(o.Attr); i++ { + if swag.IsZero(o.Attr[i]) { // not required + continue + } + + if o.Attr[i] != nil { + if err := o.Attr[i].Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("getConfigBfdAllOK" + "." + "Attr" + "." + strconv.Itoa(i)) + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("getConfigBfdAllOK" + "." + "Attr" + "." + strconv.Itoa(i)) + } + return err + } + } + + } + + return nil +} + +// ContextValidate validate this get config bfd all o k body based on the context it is used +func (o *GetConfigBfdAllOKBody) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + var res []error + + if err := o.contextValidateAttr(ctx, formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *GetConfigBfdAllOKBody) contextValidateAttr(ctx context.Context, formats strfmt.Registry) error { + + for i := 0; i < len(o.Attr); i++ { + + if o.Attr[i] != nil { + if err := o.Attr[i].ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("getConfigBfdAllOK" + "." + "Attr" + "." + strconv.Itoa(i)) + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("getConfigBfdAllOK" + "." + "Attr" + "." + strconv.Itoa(i)) + } + return err + } + } + + } + + return nil +} + +// MarshalBinary interface implementation +func (o *GetConfigBfdAllOKBody) MarshalBinary() ([]byte, error) { + if o == nil { + return nil, nil + } + return swag.WriteJSON(o) +} + +// UnmarshalBinary interface implementation +func (o *GetConfigBfdAllOKBody) UnmarshalBinary(b []byte) error { + var res GetConfigBfdAllOKBody + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *o = res + return nil +} diff --git a/api/restapi/operations/get_config_bfd_all_parameters.go b/api/restapi/operations/get_config_bfd_all_parameters.go new file mode 100644 index 00000000..bd810a2c --- /dev/null +++ b/api/restapi/operations/get_config_bfd_all_parameters.go @@ -0,0 +1,46 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "net/http" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime/middleware" +) + +// NewGetConfigBfdAllParams creates a new GetConfigBfdAllParams object +// +// There are no default values defined in the spec. +func NewGetConfigBfdAllParams() GetConfigBfdAllParams { + + return GetConfigBfdAllParams{} +} + +// GetConfigBfdAllParams contains all the bound params for the get config bfd all operation +// typically these are obtained from a http.Request +// +// swagger:parameters GetConfigBfdAll +type GetConfigBfdAllParams struct { + + // HTTP Request Object + HTTPRequest *http.Request `json:"-"` +} + +// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls. +// +// To ensure default values, the struct must have been initialized with NewGetConfigBfdAllParams() beforehand. +func (o *GetConfigBfdAllParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error { + var res []error + + o.HTTPRequest = r + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/api/restapi/operations/get_config_bfd_all_responses.go b/api/restapi/operations/get_config_bfd_all_responses.go new file mode 100644 index 00000000..29b4c249 --- /dev/null +++ b/api/restapi/operations/get_config_bfd_all_responses.go @@ -0,0 +1,194 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "net/http" + + "github.com/go-openapi/runtime" + + "github.com/loxilb-io/loxilb/api/models" +) + +// GetConfigBfdAllOKCode is the HTTP code returned for type GetConfigBfdAllOK +const GetConfigBfdAllOKCode int = 200 + +/* +GetConfigBfdAllOK OK + +swagger:response getConfigBfdAllOK +*/ +type GetConfigBfdAllOK struct { + + /* + In: Body + */ + Payload *GetConfigBfdAllOKBody `json:"body,omitempty"` +} + +// NewGetConfigBfdAllOK creates GetConfigBfdAllOK with default headers values +func NewGetConfigBfdAllOK() *GetConfigBfdAllOK { + + return &GetConfigBfdAllOK{} +} + +// WithPayload adds the payload to the get config bfd all o k response +func (o *GetConfigBfdAllOK) WithPayload(payload *GetConfigBfdAllOKBody) *GetConfigBfdAllOK { + o.Payload = payload + return o +} + +// SetPayload sets the payload to the get config bfd all o k response +func (o *GetConfigBfdAllOK) SetPayload(payload *GetConfigBfdAllOKBody) { + o.Payload = payload +} + +// WriteResponse to the client +func (o *GetConfigBfdAllOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.WriteHeader(200) + if o.Payload != nil { + payload := o.Payload + if err := producer.Produce(rw, payload); err != nil { + panic(err) // let the recovery middleware deal with this + } + } +} + +// GetConfigBfdAllUnauthorizedCode is the HTTP code returned for type GetConfigBfdAllUnauthorized +const GetConfigBfdAllUnauthorizedCode int = 401 + +/* +GetConfigBfdAllUnauthorized Invalid authentication credentials + +swagger:response getConfigBfdAllUnauthorized +*/ +type GetConfigBfdAllUnauthorized struct { + + /* + In: Body + */ + Payload *models.Error `json:"body,omitempty"` +} + +// NewGetConfigBfdAllUnauthorized creates GetConfigBfdAllUnauthorized with default headers values +func NewGetConfigBfdAllUnauthorized() *GetConfigBfdAllUnauthorized { + + return &GetConfigBfdAllUnauthorized{} +} + +// WithPayload adds the payload to the get config bfd all unauthorized response +func (o *GetConfigBfdAllUnauthorized) WithPayload(payload *models.Error) *GetConfigBfdAllUnauthorized { + o.Payload = payload + return o +} + +// SetPayload sets the payload to the get config bfd all unauthorized response +func (o *GetConfigBfdAllUnauthorized) SetPayload(payload *models.Error) { + o.Payload = payload +} + +// WriteResponse to the client +func (o *GetConfigBfdAllUnauthorized) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.WriteHeader(401) + if o.Payload != nil { + payload := o.Payload + if err := producer.Produce(rw, payload); err != nil { + panic(err) // let the recovery middleware deal with this + } + } +} + +// GetConfigBfdAllInternalServerErrorCode is the HTTP code returned for type GetConfigBfdAllInternalServerError +const GetConfigBfdAllInternalServerErrorCode int = 500 + +/* +GetConfigBfdAllInternalServerError Internal service error + +swagger:response getConfigBfdAllInternalServerError +*/ +type GetConfigBfdAllInternalServerError struct { + + /* + In: Body + */ + Payload *models.Error `json:"body,omitempty"` +} + +// NewGetConfigBfdAllInternalServerError creates GetConfigBfdAllInternalServerError with default headers values +func NewGetConfigBfdAllInternalServerError() *GetConfigBfdAllInternalServerError { + + return &GetConfigBfdAllInternalServerError{} +} + +// WithPayload adds the payload to the get config bfd all internal server error response +func (o *GetConfigBfdAllInternalServerError) WithPayload(payload *models.Error) *GetConfigBfdAllInternalServerError { + o.Payload = payload + return o +} + +// SetPayload sets the payload to the get config bfd all internal server error response +func (o *GetConfigBfdAllInternalServerError) SetPayload(payload *models.Error) { + o.Payload = payload +} + +// WriteResponse to the client +func (o *GetConfigBfdAllInternalServerError) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.WriteHeader(500) + if o.Payload != nil { + payload := o.Payload + if err := producer.Produce(rw, payload); err != nil { + panic(err) // let the recovery middleware deal with this + } + } +} + +// GetConfigBfdAllServiceUnavailableCode is the HTTP code returned for type GetConfigBfdAllServiceUnavailable +const GetConfigBfdAllServiceUnavailableCode int = 503 + +/* +GetConfigBfdAllServiceUnavailable Maintanence mode + +swagger:response getConfigBfdAllServiceUnavailable +*/ +type GetConfigBfdAllServiceUnavailable struct { + + /* + In: Body + */ + Payload *models.Error `json:"body,omitempty"` +} + +// NewGetConfigBfdAllServiceUnavailable creates GetConfigBfdAllServiceUnavailable with default headers values +func NewGetConfigBfdAllServiceUnavailable() *GetConfigBfdAllServiceUnavailable { + + return &GetConfigBfdAllServiceUnavailable{} +} + +// WithPayload adds the payload to the get config bfd all service unavailable response +func (o *GetConfigBfdAllServiceUnavailable) WithPayload(payload *models.Error) *GetConfigBfdAllServiceUnavailable { + o.Payload = payload + return o +} + +// SetPayload sets the payload to the get config bfd all service unavailable response +func (o *GetConfigBfdAllServiceUnavailable) SetPayload(payload *models.Error) { + o.Payload = payload +} + +// WriteResponse to the client +func (o *GetConfigBfdAllServiceUnavailable) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.WriteHeader(503) + if o.Payload != nil { + payload := o.Payload + if err := producer.Produce(rw, payload); err != nil { + panic(err) // let the recovery middleware deal with this + } + } +} diff --git a/api/restapi/operations/get_config_bfd_all_urlbuilder.go b/api/restapi/operations/get_config_bfd_all_urlbuilder.go new file mode 100644 index 00000000..a1eede14 --- /dev/null +++ b/api/restapi/operations/get_config_bfd_all_urlbuilder.go @@ -0,0 +1,87 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the generate command + +import ( + "errors" + "net/url" + golangswaggerpaths "path" +) + +// GetConfigBfdAllURL generates an URL for the get config bfd all operation +type GetConfigBfdAllURL struct { + _basePath string +} + +// WithBasePath sets the base path for this url builder, only required when it's different from the +// base path specified in the swagger spec. +// When the value of the base path is an empty string +func (o *GetConfigBfdAllURL) WithBasePath(bp string) *GetConfigBfdAllURL { + o.SetBasePath(bp) + return o +} + +// SetBasePath sets the base path for this url builder, only required when it's different from the +// base path specified in the swagger spec. +// When the value of the base path is an empty string +func (o *GetConfigBfdAllURL) SetBasePath(bp string) { + o._basePath = bp +} + +// Build a url path and query string +func (o *GetConfigBfdAllURL) Build() (*url.URL, error) { + var _result url.URL + + var _path = "/config/bfd/all" + + _basePath := o._basePath + if _basePath == "" { + _basePath = "/netlox/v1" + } + _result.Path = golangswaggerpaths.Join(_basePath, _path) + + return &_result, nil +} + +// Must is a helper function to panic when the url builder returns an error +func (o *GetConfigBfdAllURL) Must(u *url.URL, err error) *url.URL { + if err != nil { + panic(err) + } + if u == nil { + panic("url can't be nil") + } + return u +} + +// String returns the string representation of the path with query string +func (o *GetConfigBfdAllURL) String() string { + return o.Must(o.Build()).String() +} + +// BuildFull builds a full url with scheme, host, path and query string +func (o *GetConfigBfdAllURL) BuildFull(scheme, host string) (*url.URL, error) { + if scheme == "" { + return nil, errors.New("scheme is required for a full url on GetConfigBfdAllURL") + } + if host == "" { + return nil, errors.New("host is required for a full url on GetConfigBfdAllURL") + } + + base, err := o.Build() + if err != nil { + return nil, err + } + + base.Scheme = scheme + base.Host = host + return base, nil +} + +// StringFull returns the string representation of a complete url +func (o *GetConfigBfdAllURL) StringFull(scheme, host string) string { + return o.Must(o.BuildFull(scheme, host)).String() +} diff --git a/api/restapi/operations/loxilb_rest_api_api.go b/api/restapi/operations/loxilb_rest_api_api.go index 43dc1fa1..8d90df47 100644 --- a/api/restapi/operations/loxilb_rest_api_api.go +++ b/api/restapi/operations/loxilb_rest_api_api.go @@ -93,6 +93,9 @@ func NewLoxilbRestAPIAPI(spec *loads.Document) *LoxilbRestAPIAPI { DeleteConfigVlanVlanIDMemberIfNameTaggedTaggedHandler: DeleteConfigVlanVlanIDMemberIfNameTaggedTaggedHandlerFunc(func(params DeleteConfigVlanVlanIDMemberIfNameTaggedTaggedParams) middleware.Responder { return middleware.NotImplemented("operation DeleteConfigVlanVlanIDMemberIfNameTaggedTagged has not yet been implemented") }), + GetConfigBfdAllHandler: GetConfigBfdAllHandlerFunc(func(params GetConfigBfdAllParams) middleware.Responder { + return middleware.NotImplemented("operation GetConfigBfdAll has not yet been implemented") + }), GetConfigBgpNeighAllHandler: GetConfigBgpNeighAllHandlerFunc(func(params GetConfigBgpNeighAllParams) middleware.Responder { return middleware.NotImplemented("operation GetConfigBgpNeighAll has not yet been implemented") }), @@ -159,6 +162,9 @@ func NewLoxilbRestAPIAPI(spec *loads.Document) *LoxilbRestAPIAPI { GetStatusProcessHandler: GetStatusProcessHandlerFunc(func(params GetStatusProcessParams) middleware.Responder { return middleware.NotImplemented("operation GetStatusProcess has not yet been implemented") }), + PostConfigBfdHandler: PostConfigBfdHandlerFunc(func(params PostConfigBfdParams) middleware.Responder { + return middleware.NotImplemented("operation PostConfigBfd has not yet been implemented") + }), PostConfigBgpGlobalHandler: PostConfigBgpGlobalHandlerFunc(func(params PostConfigBgpGlobalParams) middleware.Responder { return middleware.NotImplemented("operation PostConfigBgpGlobal has not yet been implemented") }), @@ -286,6 +292,8 @@ type LoxilbRestAPIAPI struct { DeleteConfigVlanVlanIDHandler DeleteConfigVlanVlanIDHandler // DeleteConfigVlanVlanIDMemberIfNameTaggedTaggedHandler sets the operation handler for the delete config vlan vlan ID member if name tagged tagged operation DeleteConfigVlanVlanIDMemberIfNameTaggedTaggedHandler DeleteConfigVlanVlanIDMemberIfNameTaggedTaggedHandler + // GetConfigBfdAllHandler sets the operation handler for the get config bfd all operation + GetConfigBfdAllHandler GetConfigBfdAllHandler // GetConfigBgpNeighAllHandler sets the operation handler for the get config bgp neigh all operation GetConfigBgpNeighAllHandler GetConfigBgpNeighAllHandler // GetConfigCistateAllHandler sets the operation handler for the get config cistate all operation @@ -330,6 +338,8 @@ type LoxilbRestAPIAPI struct { GetStatusFilesystemHandler GetStatusFilesystemHandler // GetStatusProcessHandler sets the operation handler for the get status process operation GetStatusProcessHandler GetStatusProcessHandler + // PostConfigBfdHandler sets the operation handler for the post config bfd operation + PostConfigBfdHandler PostConfigBfdHandler // PostConfigBgpGlobalHandler sets the operation handler for the post config bgp global operation PostConfigBgpGlobalHandler PostConfigBgpGlobalHandler // PostConfigBgpNeighHandler sets the operation handler for the post config bgp neigh operation @@ -496,6 +506,9 @@ func (o *LoxilbRestAPIAPI) Validate() error { if o.DeleteConfigVlanVlanIDMemberIfNameTaggedTaggedHandler == nil { unregistered = append(unregistered, "DeleteConfigVlanVlanIDMemberIfNameTaggedTaggedHandler") } + if o.GetConfigBfdAllHandler == nil { + unregistered = append(unregistered, "GetConfigBfdAllHandler") + } if o.GetConfigBgpNeighAllHandler == nil { unregistered = append(unregistered, "GetConfigBgpNeighAllHandler") } @@ -562,6 +575,9 @@ func (o *LoxilbRestAPIAPI) Validate() error { if o.GetStatusProcessHandler == nil { unregistered = append(unregistered, "GetStatusProcessHandler") } + if o.PostConfigBfdHandler == nil { + unregistered = append(unregistered, "PostConfigBfdHandler") + } if o.PostConfigBgpGlobalHandler == nil { unregistered = append(unregistered, "PostConfigBgpGlobalHandler") } @@ -778,6 +794,10 @@ func (o *LoxilbRestAPIAPI) initHandlerCache() { if o.handlers["GET"] == nil { o.handlers["GET"] = make(map[string]http.Handler) } + o.handlers["GET"]["/config/bfd/all"] = NewGetConfigBfdAll(o.context, o.GetConfigBfdAllHandler) + if o.handlers["GET"] == nil { + o.handlers["GET"] = make(map[string]http.Handler) + } o.handlers["GET"]["/config/bgp/neigh/all"] = NewGetConfigBgpNeighAll(o.context, o.GetConfigBgpNeighAllHandler) if o.handlers["GET"] == nil { o.handlers["GET"] = make(map[string]http.Handler) @@ -866,6 +886,10 @@ func (o *LoxilbRestAPIAPI) initHandlerCache() { if o.handlers["POST"] == nil { o.handlers["POST"] = make(map[string]http.Handler) } + o.handlers["POST"]["/config/bfd"] = NewPostConfigBfd(o.context, o.PostConfigBfdHandler) + if o.handlers["POST"] == nil { + o.handlers["POST"] = make(map[string]http.Handler) + } o.handlers["POST"]["/config/bgp/global"] = NewPostConfigBgpGlobal(o.context, o.PostConfigBgpGlobalHandler) if o.handlers["POST"] == nil { o.handlers["POST"] = make(map[string]http.Handler) diff --git a/api/restapi/operations/post_config_bfd.go b/api/restapi/operations/post_config_bfd.go new file mode 100644 index 00000000..8a2b6936 --- /dev/null +++ b/api/restapi/operations/post_config_bfd.go @@ -0,0 +1,58 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the generate command + +import ( + "net/http" + + "github.com/go-openapi/runtime/middleware" +) + +// PostConfigBfdHandlerFunc turns a function with the right signature into a post config bfd handler +type PostConfigBfdHandlerFunc func(PostConfigBfdParams) middleware.Responder + +// Handle executing the request and returning a response +func (fn PostConfigBfdHandlerFunc) Handle(params PostConfigBfdParams) middleware.Responder { + return fn(params) +} + +// PostConfigBfdHandler interface for that can handle valid post config bfd params +type PostConfigBfdHandler interface { + Handle(PostConfigBfdParams) middleware.Responder +} + +// NewPostConfigBfd creates a new http.Handler for the post config bfd operation +func NewPostConfigBfd(ctx *middleware.Context, handler PostConfigBfdHandler) *PostConfigBfd { + return &PostConfigBfd{Context: ctx, Handler: handler} +} + +/* + PostConfigBfd swagger:route POST /config/bfd postConfigBfd + +# Create vlan interface in the device + +Create vlan interface in the device +*/ +type PostConfigBfd struct { + Context *middleware.Context + Handler PostConfigBfdHandler +} + +func (o *PostConfigBfd) ServeHTTP(rw http.ResponseWriter, r *http.Request) { + route, rCtx, _ := o.Context.RouteInfo(r) + if rCtx != nil { + *r = *rCtx + } + var Params = NewPostConfigBfdParams() + if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params + o.Context.Respond(rw, r, route.Produces, route, err) + return + } + + res := o.Handler.Handle(Params) // actually handle the request + o.Context.Respond(rw, r, route.Produces, route, res) + +} diff --git a/api/restapi/operations/post_config_bfd_parameters.go b/api/restapi/operations/post_config_bfd_parameters.go new file mode 100644 index 00000000..82b5e2da --- /dev/null +++ b/api/restapi/operations/post_config_bfd_parameters.go @@ -0,0 +1,84 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "io" + "net/http" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + "github.com/go-openapi/runtime/middleware" + "github.com/go-openapi/validate" + + "github.com/loxilb-io/loxilb/api/models" +) + +// NewPostConfigBfdParams creates a new PostConfigBfdParams object +// +// There are no default values defined in the spec. +func NewPostConfigBfdParams() PostConfigBfdParams { + + return PostConfigBfdParams{} +} + +// PostConfigBfdParams contains all the bound params for the post config bfd operation +// typically these are obtained from a http.Request +// +// swagger:parameters PostConfigBfd +type PostConfigBfdParams struct { + + // HTTP Request Object + HTTPRequest *http.Request `json:"-"` + + /*Attributes for Vlan Interface + Required: true + In: body + */ + Attr *models.BfdEntry +} + +// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls. +// +// To ensure default values, the struct must have been initialized with NewPostConfigBfdParams() beforehand. +func (o *PostConfigBfdParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error { + var res []error + + o.HTTPRequest = r + + if runtime.HasBody(r) { + defer r.Body.Close() + var body models.BfdEntry + if err := route.Consumer.Consume(r.Body, &body); err != nil { + if err == io.EOF { + res = append(res, errors.Required("attr", "body", "")) + } else { + res = append(res, errors.NewParseError("attr", "body", "", err)) + } + } else { + // validate body object + if err := body.Validate(route.Formats); err != nil { + res = append(res, err) + } + + ctx := validate.WithOperationRequest(r.Context()) + if err := body.ContextValidate(ctx, route.Formats); err != nil { + res = append(res, err) + } + + if len(res) == 0 { + o.Attr = &body + } + } + } else { + res = append(res, errors.Required("attr", "body", "")) + } + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/api/restapi/operations/post_config_bfd_responses.go b/api/restapi/operations/post_config_bfd_responses.go new file mode 100644 index 00000000..8bcdb2a1 --- /dev/null +++ b/api/restapi/operations/post_config_bfd_responses.go @@ -0,0 +1,354 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "net/http" + + "github.com/go-openapi/runtime" + + "github.com/loxilb-io/loxilb/api/models" +) + +// PostConfigBfdNoContentCode is the HTTP code returned for type PostConfigBfdNoContent +const PostConfigBfdNoContentCode int = 204 + +/* +PostConfigBfdNoContent OK + +swagger:response postConfigBfdNoContent +*/ +type PostConfigBfdNoContent struct { +} + +// NewPostConfigBfdNoContent creates PostConfigBfdNoContent with default headers values +func NewPostConfigBfdNoContent() *PostConfigBfdNoContent { + + return &PostConfigBfdNoContent{} +} + +// WriteResponse to the client +func (o *PostConfigBfdNoContent) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses + + rw.WriteHeader(204) +} + +// PostConfigBfdBadRequestCode is the HTTP code returned for type PostConfigBfdBadRequest +const PostConfigBfdBadRequestCode int = 400 + +/* +PostConfigBfdBadRequest Malformed arguments for API call + +swagger:response postConfigBfdBadRequest +*/ +type PostConfigBfdBadRequest struct { + + /* + In: Body + */ + Payload *models.Error `json:"body,omitempty"` +} + +// NewPostConfigBfdBadRequest creates PostConfigBfdBadRequest with default headers values +func NewPostConfigBfdBadRequest() *PostConfigBfdBadRequest { + + return &PostConfigBfdBadRequest{} +} + +// WithPayload adds the payload to the post config bfd bad request response +func (o *PostConfigBfdBadRequest) WithPayload(payload *models.Error) *PostConfigBfdBadRequest { + o.Payload = payload + return o +} + +// SetPayload sets the payload to the post config bfd bad request response +func (o *PostConfigBfdBadRequest) SetPayload(payload *models.Error) { + o.Payload = payload +} + +// WriteResponse to the client +func (o *PostConfigBfdBadRequest) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.WriteHeader(400) + if o.Payload != nil { + payload := o.Payload + if err := producer.Produce(rw, payload); err != nil { + panic(err) // let the recovery middleware deal with this + } + } +} + +// PostConfigBfdUnauthorizedCode is the HTTP code returned for type PostConfigBfdUnauthorized +const PostConfigBfdUnauthorizedCode int = 401 + +/* +PostConfigBfdUnauthorized Invalid authentication credentials + +swagger:response postConfigBfdUnauthorized +*/ +type PostConfigBfdUnauthorized struct { + + /* + In: Body + */ + Payload *models.Error `json:"body,omitempty"` +} + +// NewPostConfigBfdUnauthorized creates PostConfigBfdUnauthorized with default headers values +func NewPostConfigBfdUnauthorized() *PostConfigBfdUnauthorized { + + return &PostConfigBfdUnauthorized{} +} + +// WithPayload adds the payload to the post config bfd unauthorized response +func (o *PostConfigBfdUnauthorized) WithPayload(payload *models.Error) *PostConfigBfdUnauthorized { + o.Payload = payload + return o +} + +// SetPayload sets the payload to the post config bfd unauthorized response +func (o *PostConfigBfdUnauthorized) SetPayload(payload *models.Error) { + o.Payload = payload +} + +// WriteResponse to the client +func (o *PostConfigBfdUnauthorized) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.WriteHeader(401) + if o.Payload != nil { + payload := o.Payload + if err := producer.Produce(rw, payload); err != nil { + panic(err) // let the recovery middleware deal with this + } + } +} + +// PostConfigBfdForbiddenCode is the HTTP code returned for type PostConfigBfdForbidden +const PostConfigBfdForbiddenCode int = 403 + +/* +PostConfigBfdForbidden Capacity insufficient + +swagger:response postConfigBfdForbidden +*/ +type PostConfigBfdForbidden struct { + + /* + In: Body + */ + Payload *models.Error `json:"body,omitempty"` +} + +// NewPostConfigBfdForbidden creates PostConfigBfdForbidden with default headers values +func NewPostConfigBfdForbidden() *PostConfigBfdForbidden { + + return &PostConfigBfdForbidden{} +} + +// WithPayload adds the payload to the post config bfd forbidden response +func (o *PostConfigBfdForbidden) WithPayload(payload *models.Error) *PostConfigBfdForbidden { + o.Payload = payload + return o +} + +// SetPayload sets the payload to the post config bfd forbidden response +func (o *PostConfigBfdForbidden) SetPayload(payload *models.Error) { + o.Payload = payload +} + +// WriteResponse to the client +func (o *PostConfigBfdForbidden) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.WriteHeader(403) + if o.Payload != nil { + payload := o.Payload + if err := producer.Produce(rw, payload); err != nil { + panic(err) // let the recovery middleware deal with this + } + } +} + +// PostConfigBfdNotFoundCode is the HTTP code returned for type PostConfigBfdNotFound +const PostConfigBfdNotFoundCode int = 404 + +/* +PostConfigBfdNotFound Resource not found + +swagger:response postConfigBfdNotFound +*/ +type PostConfigBfdNotFound struct { + + /* + In: Body + */ + Payload *models.Error `json:"body,omitempty"` +} + +// NewPostConfigBfdNotFound creates PostConfigBfdNotFound with default headers values +func NewPostConfigBfdNotFound() *PostConfigBfdNotFound { + + return &PostConfigBfdNotFound{} +} + +// WithPayload adds the payload to the post config bfd not found response +func (o *PostConfigBfdNotFound) WithPayload(payload *models.Error) *PostConfigBfdNotFound { + o.Payload = payload + return o +} + +// SetPayload sets the payload to the post config bfd not found response +func (o *PostConfigBfdNotFound) SetPayload(payload *models.Error) { + o.Payload = payload +} + +// WriteResponse to the client +func (o *PostConfigBfdNotFound) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.WriteHeader(404) + if o.Payload != nil { + payload := o.Payload + if err := producer.Produce(rw, payload); err != nil { + panic(err) // let the recovery middleware deal with this + } + } +} + +// PostConfigBfdConflictCode is the HTTP code returned for type PostConfigBfdConflict +const PostConfigBfdConflictCode int = 409 + +/* +PostConfigBfdConflict Resource Conflict. BFD session not found + +swagger:response postConfigBfdConflict +*/ +type PostConfigBfdConflict struct { + + /* + In: Body + */ + Payload *models.Error `json:"body,omitempty"` +} + +// NewPostConfigBfdConflict creates PostConfigBfdConflict with default headers values +func NewPostConfigBfdConflict() *PostConfigBfdConflict { + + return &PostConfigBfdConflict{} +} + +// WithPayload adds the payload to the post config bfd conflict response +func (o *PostConfigBfdConflict) WithPayload(payload *models.Error) *PostConfigBfdConflict { + o.Payload = payload + return o +} + +// SetPayload sets the payload to the post config bfd conflict response +func (o *PostConfigBfdConflict) SetPayload(payload *models.Error) { + o.Payload = payload +} + +// WriteResponse to the client +func (o *PostConfigBfdConflict) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.WriteHeader(409) + if o.Payload != nil { + payload := o.Payload + if err := producer.Produce(rw, payload); err != nil { + panic(err) // let the recovery middleware deal with this + } + } +} + +// PostConfigBfdInternalServerErrorCode is the HTTP code returned for type PostConfigBfdInternalServerError +const PostConfigBfdInternalServerErrorCode int = 500 + +/* +PostConfigBfdInternalServerError Internal service error + +swagger:response postConfigBfdInternalServerError +*/ +type PostConfigBfdInternalServerError struct { + + /* + In: Body + */ + Payload *models.Error `json:"body,omitempty"` +} + +// NewPostConfigBfdInternalServerError creates PostConfigBfdInternalServerError with default headers values +func NewPostConfigBfdInternalServerError() *PostConfigBfdInternalServerError { + + return &PostConfigBfdInternalServerError{} +} + +// WithPayload adds the payload to the post config bfd internal server error response +func (o *PostConfigBfdInternalServerError) WithPayload(payload *models.Error) *PostConfigBfdInternalServerError { + o.Payload = payload + return o +} + +// SetPayload sets the payload to the post config bfd internal server error response +func (o *PostConfigBfdInternalServerError) SetPayload(payload *models.Error) { + o.Payload = payload +} + +// WriteResponse to the client +func (o *PostConfigBfdInternalServerError) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.WriteHeader(500) + if o.Payload != nil { + payload := o.Payload + if err := producer.Produce(rw, payload); err != nil { + panic(err) // let the recovery middleware deal with this + } + } +} + +// PostConfigBfdServiceUnavailableCode is the HTTP code returned for type PostConfigBfdServiceUnavailable +const PostConfigBfdServiceUnavailableCode int = 503 + +/* +PostConfigBfdServiceUnavailable Maintanence mode + +swagger:response postConfigBfdServiceUnavailable +*/ +type PostConfigBfdServiceUnavailable struct { + + /* + In: Body + */ + Payload *models.Error `json:"body,omitempty"` +} + +// NewPostConfigBfdServiceUnavailable creates PostConfigBfdServiceUnavailable with default headers values +func NewPostConfigBfdServiceUnavailable() *PostConfigBfdServiceUnavailable { + + return &PostConfigBfdServiceUnavailable{} +} + +// WithPayload adds the payload to the post config bfd service unavailable response +func (o *PostConfigBfdServiceUnavailable) WithPayload(payload *models.Error) *PostConfigBfdServiceUnavailable { + o.Payload = payload + return o +} + +// SetPayload sets the payload to the post config bfd service unavailable response +func (o *PostConfigBfdServiceUnavailable) SetPayload(payload *models.Error) { + o.Payload = payload +} + +// WriteResponse to the client +func (o *PostConfigBfdServiceUnavailable) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.WriteHeader(503) + if o.Payload != nil { + payload := o.Payload + if err := producer.Produce(rw, payload); err != nil { + panic(err) // let the recovery middleware deal with this + } + } +} diff --git a/api/restapi/operations/post_config_bfd_urlbuilder.go b/api/restapi/operations/post_config_bfd_urlbuilder.go new file mode 100644 index 00000000..f83ba61a --- /dev/null +++ b/api/restapi/operations/post_config_bfd_urlbuilder.go @@ -0,0 +1,87 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the generate command + +import ( + "errors" + "net/url" + golangswaggerpaths "path" +) + +// PostConfigBfdURL generates an URL for the post config bfd operation +type PostConfigBfdURL struct { + _basePath string +} + +// WithBasePath sets the base path for this url builder, only required when it's different from the +// base path specified in the swagger spec. +// When the value of the base path is an empty string +func (o *PostConfigBfdURL) WithBasePath(bp string) *PostConfigBfdURL { + o.SetBasePath(bp) + return o +} + +// SetBasePath sets the base path for this url builder, only required when it's different from the +// base path specified in the swagger spec. +// When the value of the base path is an empty string +func (o *PostConfigBfdURL) SetBasePath(bp string) { + o._basePath = bp +} + +// Build a url path and query string +func (o *PostConfigBfdURL) Build() (*url.URL, error) { + var _result url.URL + + var _path = "/config/bfd" + + _basePath := o._basePath + if _basePath == "" { + _basePath = "/netlox/v1" + } + _result.Path = golangswaggerpaths.Join(_basePath, _path) + + return &_result, nil +} + +// Must is a helper function to panic when the url builder returns an error +func (o *PostConfigBfdURL) Must(u *url.URL, err error) *url.URL { + if err != nil { + panic(err) + } + if u == nil { + panic("url can't be nil") + } + return u +} + +// String returns the string representation of the path with query string +func (o *PostConfigBfdURL) String() string { + return o.Must(o.Build()).String() +} + +// BuildFull builds a full url with scheme, host, path and query string +func (o *PostConfigBfdURL) BuildFull(scheme, host string) (*url.URL, error) { + if scheme == "" { + return nil, errors.New("scheme is required for a full url on PostConfigBfdURL") + } + if host == "" { + return nil, errors.New("host is required for a full url on PostConfigBfdURL") + } + + base, err := o.Build() + if err != nil { + return nil, err + } + + base.Scheme = scheme + base.Host = host + return base, nil +} + +// StringFull returns the string representation of a complete url +func (o *PostConfigBfdURL) StringFull(scheme, host string) string { + return o.Must(o.BuildFull(scheme, host)).String() +} diff --git a/api/swagger.yml b/api/swagger.yml index 0dfe7d8a..74f870eb 100644 --- a/api/swagger.yml +++ b/api/swagger.yml @@ -2290,6 +2290,78 @@ paths: schema: type: string +#---------------------------------------------- +# BFD +#---------------------------------------------- + '/config/bfd/all': + get: + summary: Get BFD session inforrmation in the device + description: Get BFD session inforrmation + responses: + '200': + description: OK + schema: + type: object + properties: + Attr: + type: array + items: + $ref: '#/definitions/BfdGetEntry' + '401': + description: Invalid authentication credentials + schema: + $ref: '#/definitions/Error' + '500': + description: Internal service error + schema: + $ref: '#/definitions/Error' + '503': + description: Maintanence mode + schema: + $ref: '#/definitions/Error' + + '/config/bfd': + post: + summary: Create vlan interface in the device + description: Create vlan interface in the device + parameters: + - name: attr + in: body + required: true + description: Attributes for Vlan Interface + schema: + $ref: '#/definitions/BfdEntry' + responses: + '204': + description: OK + '400': + description: Malformed arguments for API call + schema: + $ref: '#/definitions/Error' + '401': + description: Invalid authentication credentials + schema: + $ref: '#/definitions/Error' + '403': + description: Capacity insufficient + schema: + $ref: '#/definitions/Error' + '404': + description: Resource not found + schema: + $ref: '#/definitions/Error' + '409': + description: Resource Conflict. BFD session not found + schema: + $ref: '#/definitions/Error' + '500': + description: Internal service error + schema: + $ref: '#/definitions/Error' + '503': + description: Maintanence mode + schema: + $ref: '#/definitions/Error' #---------------------------------------------- # Schema definitions @@ -3185,3 +3257,53 @@ definitions: listenPort: type: integer description: Listen port (default 179) + + BfdGetEntry: + type: object + properties: + instance: + type: string + description: Instance name + remoteIp: + type: string + description: Remote IP + sourceIP: + type: string + description: Source IP to be used for BFD session + port: + type: integer + format: uint16 + description: port number to be used for BFD session + interval: + type: integer + format: uint64 + description: Tx interval between BFD packets(in microseconds) + retryCount: + type: integer + format: uint8 + description: Retry Count to detect failure + state: + type: string + description: Current state for BFD session + + + BfdEntry: + type: object + properties: + instance: + type: string + description: Instance name running BFD session + remoteIp: + type: string + description: Remote IP + sourceIp: + type: string + description: Remote IP + interval: + type: integer + format: uint64 + description: Tx interval between BFD packets(in microseconds) + retryCount: + type: integer + format: uint8 + description: Retry Count to detect failure \ No newline at end of file diff --git a/common/common.go b/common/common.go index 22b028b7..53534a2a 100644 --- a/common/common.go +++ b/common/common.go @@ -33,6 +33,8 @@ const ( CIStateNotDefined ) +const BFDPort = 3784 +const BFDDefRetryCount = 3 const ( // CIDefault - Default CI Instance name CIDefault = "default" @@ -660,6 +662,24 @@ type HASMod struct { Vip net.IP `json:"Addr"` } +// BFDMod - information related to a BFD session +type BFDMod struct { + // Instance - Cluster Instance + Instance string `json:"instance"` + // RemoteIP - Remote IP for BFD session + RemoteIP net.IP `json:"remoteIp"` + // Interval - Tx Interval between BFD packets + SourceIP net.IP `json:"sourceIp"` + // Port - BFD session port + Port uint16 `json:"port"` + // Interval - Tx Interval between BFD packets + Interval uint64 `json:"interval"` + // RetryCount - Retry Count for detecting failure + RetryCount uint8 `json:"retryCount"` + // State - BFD session state + State string `json:"state"` +} + // ClusterNodeMod - information related to a cluster node instance type ClusterNodeMod struct { // Instance - Cluster Instance @@ -835,5 +855,7 @@ type NetHookInterface interface { NetGoBGPNeighAdd(nm *GoBGPNeighMod) (int, error) NetGoBGPNeighDel(nm *GoBGPNeighMod) (int, error) NetGoBGPGCAdd(gc *GoBGPGlobalConfig) (int, error) + NetBFDGet() ([]BFDMod, error) + NetBFDAdd(bm *BFDMod) (int, error) NetHandlePanic() } diff --git a/loxinet/apiclient.go b/loxinet/apiclient.go index f4aee5ea..ce1bb130 100644 --- a/loxinet/apiclient.go +++ b/loxinet/apiclient.go @@ -499,6 +499,33 @@ func (na *NetAPIStruct) NetCIStateMod(hm *cmn.HASMod) (int, error) { return 0, nil } +// NetCIStateMod - Modify cluster state +func (na *NetAPIStruct) NetBFDGet() ([]cmn.BFDMod, error) { + if na.BgpPeerMode { + return nil, errors.New("running in bgp only mode") + } + mh.mtx.Lock() + defer mh.mtx.Unlock() + + return mh.has.CIBFDSessionGet() +} + +// NetCIStateMod - Modify cluster state +func (na *NetAPIStruct) NetBFDAdd(bm *cmn.BFDMod) (int, error) { + if na.BgpPeerMode { + return CIErrBase, errors.New("running in bgp only mode") + } + mh.mtx.Lock() + defer mh.mtx.Unlock() + + _, err := mh.has.CIBFDSessionAdd(*bm) + if err != nil { + return -1, err + } + + return 0, nil +} + // NetFwRuleAdd - Add a firewall rule in loxinet func (na *NetAPIStruct) NetFwRuleAdd(fm *cmn.FwRuleMod) (int, error) { if na.BgpPeerMode { diff --git a/loxinet/cluster.go b/loxinet/cluster.go index 602a493d..0a8946f9 100644 --- a/loxinet/cluster.go +++ b/loxinet/cluster.go @@ -66,6 +66,7 @@ type CIStateH struct { ClusterMap map[string]*ClusterInstance StateMap map[string]int NodeMap map[string]*ClusterNode + Bs *bfd.Struct } func (ci *CIStateH) BFDSessionNotify(instance string, remote string, ciState string) { @@ -99,8 +100,9 @@ func (ci *CIStateH) startBFDProto() { txInterval = uint32(ci.Interval) } - bs := bfd.StructNew(3784) - bfdSessConfigArgs := bfd.ConfigArgs{RemoteIP: ci.RemoteIP.String(), SourceIP: ci.SourceIP.String(), Port: 3784, Interval: txInterval, Multi: 3, Instance: cmn.CIDefault} + bs := bfd.StructNew(cmn.BFDPort) + bfdSessConfigArgs := bfd.ConfigArgs{RemoteIP: ci.RemoteIP.String(), SourceIP: ci.SourceIP.String(), + Port: cmn.BFDPort, Interval: txInterval, Multi: cmn.BFDDefRetryCount, Instance: cmn.CIDefault} err := bs.BFDAddRemote(bfdSessConfigArgs, ci) if err != nil { tk.LogIt(tk.LogCritical, "KA - Cant add BFD remote\n") @@ -116,6 +118,8 @@ func (h *CIStateH) CITicker() { // CISpawn - Spawn CI application func (ci *CIStateH) CISpawn() { + bs := bfd.StructNew(3784) + ci.Bs = bs if ci.SpawnKa { go ci.startBFDProto() } @@ -264,6 +268,40 @@ func (h *CIStateH) ClusterNodeDelete(node cmn.ClusterNodeMod) (int, error) { return 0, nil } +// CIStateUpdate - routine to update cluster state +func (h *CIStateH) CIBFDSessionAdd(bm cmn.BFDMod) (int, error) { + + if !h.SpawnKa { + tk.LogIt(tk.LogError, "[CLUSTER] Cluster Instance %s not running BFD\n", bm.Instance) + return -1, errors.New("bfd session not running") + } + + _, found := h.ClusterMap[bm.Instance] + if !found { + tk.LogIt(tk.LogError, "[CLUSTER] BFD SU - Cluster Instance %s not found\n", bm.Instance) + return -1, errors.New("cluster instance not found") + } + + bfdSessConfigArgs := bfd.ConfigArgs{RemoteIP: h.RemoteIP.String(), SourceIP: h.SourceIP.String(), Port: 3784, Interval: uint32(bm.Interval), Multi: bm.RetryCount, Instance: bm.Instance} + err := h.Bs.BFDAddRemote(bfdSessConfigArgs, h) + if err != nil { + tk.LogIt(tk.LogCritical, "KA - Cant add BFD remote\n") + os.Exit(1) + } + tk.LogIt(tk.LogInfo, "KA - Updated BFD remote %s:%s:%vus\n", h.RemoteIP.String(), h.SourceIP.String(), bm.Interval) + return 0, nil +} + +// CIStateUpdate - routine to update cluster state +func (h *CIStateH) CIBFDSessionGet() ([]cmn.BFDMod, error) { + if !h.SpawnKa { + tk.LogIt(tk.LogError, "[CLUSTER] BFD sessions not running\n") + return nil, errors.New("bfd session not running") + } + + return h.Bs.BFDGet() +} + // DP - sync state of cluster-node entity to data-path func (cn *ClusterNode) DP(work DpWorkT) int { diff --git a/proto/bfd.go b/proto/bfd.go index 2e924b4b..1dcaf7d4 100644 --- a/proto/bfd.go +++ b/proto/bfd.go @@ -23,8 +23,11 @@ import ( "net" "sync" "time" + "strings" + "strconv" tk "github.com/loxilb-io/loxilib" + cmn "github.com/loxilb-io/loxilb/common" ) type SessionState uint8 @@ -36,6 +39,13 @@ const ( BFDUp ) +var BFDStateMap = map[uint8]string { + uint8(BFDAdminDown):"BFDAdminDown", + uint8(BFDDown): "BFDDown", + uint8(BFDInit): "BFDInit", + uint8(BFDUp): "BFDUp", +} + const ( BFDMinSysTXIntervalUs = 100000 BFDDflSysTXIntervalUs = 200000 @@ -109,17 +119,24 @@ func (bs *Struct) BFDAddRemote(args ConfigArgs, cbs Notifer) error { sess := bs.BFDSessMap[args.RemoteIP] if sess != nil { + var update bool if sess.Instance == args.Instance { - if sess.DesMinTxInt != args.Interval { + if args.Interval != 0 && sess.DesMinTxInt != args.Interval { + sess.DesMinTxInt = args.Interval + sess.ReqMinRxInt = args.Interval + sess.ReqMinEchoInt = args.Interval + update = true + } + if args.Multi != 0 && sess.MyMulti != args.Multi { + sess.MyMulti = args.Multi + update = true + } + if update { sess.Fin <- true sess.TxTicker.Stop() sess.RxTicker.Stop() sess.State = BFDDown - sess.DesMinTxInt = args.Interval - sess.ReqMinRxInt = args.Interval - sess.ReqMinEchoInt = args.Interval - sess.TxTicker = time.NewTicker(time.Duration(sess.DesMinTxInt) * time.Microsecond) sess.RxTicker = time.NewTicker(time.Duration(BFDMinSysRXIntervalUs) * time.Microsecond) go sess.bfdSessionTicker() @@ -137,6 +154,7 @@ func (bs *Struct) BFDAddRemote(args ConfigArgs, cbs Notifer) error { sess = new(bfdSession) sess.Instance = args.Instance sess.Notify = cbs + err := sess.initialize(args.RemoteIP, args.SourceIP, args.Port, args.Interval, args.Multi) if err != nil { return errors.New("bfd failed to init session") @@ -162,6 +180,29 @@ func (bs *Struct) BFDDeleteRemote(args ConfigArgs) error { return nil } +func (bs *Struct) BFDGet() ([]cmn.BFDMod, error) { + var res []cmn.BFDMod + + bs.BFDMtx.Lock() + defer bs.BFDMtx.Unlock() + + for _, s := range bs.BFDSessMap { + var temp cmn.BFDMod + pair := strings.Split(s.RemoteName, ":") + temp.Instance = s.Instance + temp.RemoteIP = net.ParseIP(pair[0]) + temp.SourceIP = tk.NltoIP(s.MyDisc) + port, _ := strconv.Atoi(pair[1]) + temp.Port = uint16(port) + temp.Interval = uint64(s.DesMinTxInt) + temp.RetryCount = s.MyMulti + temp.State = BFDStateMap[uint8(s.State)] + res = append(res, temp) + } + + return res, nil +} + func decodeCtrlPacket(buf []byte, size int) *WireRaw { if size < 24 {