diff --git a/.gitignore b/.gitignore index 92ca970d5..9ba311ab3 100644 --- a/.gitignore +++ b/.gitignore @@ -58,3 +58,4 @@ modules.order Module.symvers Mkfile.old dkms.conf +.DS_Store diff --git a/Makefile b/Makefile index f85a7815b..6ed86d445 100644 --- a/Makefile +++ b/Makefile @@ -11,8 +11,8 @@ subsys-clean: cd loxilb-ebpf && $(MAKE) clean build: subsys - @go build -o ${bin} -ldflags="-X 'main.buildInfo=${shell date '+%Y_%m_%d_%Hh:%Mm'}-${shell git branch --show-current}'" - + @go build -o ${bin} -ldflags="-X 'github.com/loxilb-io/loxilb/common.BuildInfo=${shell date '+%Y_%m_%d_%Hh:%Mm'}-${shell git branch --show-current}'" + clean: subsys-clean go clean diff --git a/api/models/version_get_entry.go b/api/models/version_get_entry.go new file mode 100644 index 000000000..69f1df803 --- /dev/null +++ b/api/models/version_get_entry.go @@ -0,0 +1,53 @@ +// 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" +) + +// VersionGetEntry version get entry +// +// swagger:model VersionGetEntry +type VersionGetEntry struct { + + // build info + BuildInfo string `json:"buildInfo,omitempty"` + + // Instance name + Version string `json:"version,omitempty"` +} + +// Validate validates this version get entry +func (m *VersionGetEntry) Validate(formats strfmt.Registry) error { + return nil +} + +// ContextValidate validates this version get entry based on context it is used +func (m *VersionGetEntry) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (m *VersionGetEntry) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *VersionGetEntry) UnmarshalBinary(b []byte) error { + var res VersionGetEntry + 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 1db9e93e1..20e8ac844 100644 --- a/api/restapi/configure_loxilb_rest_api.go +++ b/api/restapi/configure_loxilb_rest_api.go @@ -182,6 +182,9 @@ func configureAPI(api *operations.LoxilbRestAPIAPI) http.Handler { api.PostConfigBgpPolicyApplyHandler = operations.PostConfigBgpPolicyApplyHandlerFunc(handler.ConfigPostBGPPolicyApply) api.DeleteConfigBgpPolicyApplyHandler = operations.DeleteConfigBgpPolicyApplyHandlerFunc(handler.ConfigDeleteBGPPolicyApply) + // Version + api.GetVersionHandler = operations.GetVersionHandlerFunc(handler.ConfigGetVersion) + api.PreServerShutdown = func() {} api.ServerShutdown = func() {} diff --git a/api/restapi/embedded_spec.go b/api/restapi/embedded_spec.go index 97ad8c5a7..c81f414f1 100644 --- a/api/restapi/embedded_spec.go +++ b/api/restapi/embedded_spec.go @@ -4236,6 +4236,38 @@ func init() { } } } + }, + "/version": { + "get": { + "description": "Get version inforrmation", + "summary": "Get version inforrmation in the device", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/VersionGetEntry" + } + }, + "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" + } + } + } + } } }, "definitions": { @@ -5770,6 +5802,19 @@ func init() { } } }, + "VersionGetEntry": { + "type": "object", + "properties": { + "buildInfo": { + "description": "build info", + "type": "string" + }, + "version": { + "description": "Instance name", + "type": "string" + } + } + }, "VlanBridgeEntry": { "type": "object", "properties": { @@ -10088,6 +10133,38 @@ func init() { } } } + }, + "/version": { + "get": { + "description": "Get version inforrmation", + "summary": "Get version inforrmation in the device", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/VersionGetEntry" + } + }, + "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" + } + } + } + } } }, "definitions": { @@ -12507,6 +12584,19 @@ func init() { } } }, + "VersionGetEntry": { + "type": "object", + "properties": { + "buildInfo": { + "description": "build info", + "type": "string" + }, + "version": { + "description": "Instance name", + "type": "string" + } + } + }, "VlanBridgeEntry": { "type": "object", "properties": { diff --git a/api/restapi/handler/version.go b/api/restapi/handler/version.go new file mode 100644 index 000000000..8d09bb4e5 --- /dev/null +++ b/api/restapi/handler/version.go @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2022 NetLOX Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package handler + +import ( + "github.com/go-openapi/runtime/middleware" + "github.com/loxilb-io/loxilb/api/models" + "github.com/loxilb-io/loxilb/api/restapi/operations" + cmn "github.com/loxilb-io/loxilb/common" + tk "github.com/loxilb-io/loxilib" +) + +func ConfigGetVersion(params operations.GetVersionParams) middleware.Responder { + tk.LogIt(tk.LogDebug, "[API] version %s API called. url : %s\n", params.HTTPRequest.Method, params.HTTPRequest.URL) + var result models.VersionGetEntry + result.Version = cmn.Version + result.BuildInfo = cmn.BuildInfo + return operations.NewGetVersionOK().WithPayload(&result) +} diff --git a/api/restapi/operations/get_version.go b/api/restapi/operations/get_version.go new file mode 100644 index 000000000..d88d6762c --- /dev/null +++ b/api/restapi/operations/get_version.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" +) + +// GetVersionHandlerFunc turns a function with the right signature into a get version handler +type GetVersionHandlerFunc func(GetVersionParams) middleware.Responder + +// Handle executing the request and returning a response +func (fn GetVersionHandlerFunc) Handle(params GetVersionParams) middleware.Responder { + return fn(params) +} + +// GetVersionHandler interface for that can handle valid get version params +type GetVersionHandler interface { + Handle(GetVersionParams) middleware.Responder +} + +// NewGetVersion creates a new http.Handler for the get version operation +func NewGetVersion(ctx *middleware.Context, handler GetVersionHandler) *GetVersion { + return &GetVersion{Context: ctx, Handler: handler} +} + +/* + GetVersion swagger:route GET /version getVersion + +# Get version inforrmation in the device + +Get version inforrmation +*/ +type GetVersion struct { + Context *middleware.Context + Handler GetVersionHandler +} + +func (o *GetVersion) ServeHTTP(rw http.ResponseWriter, r *http.Request) { + route, rCtx, _ := o.Context.RouteInfo(r) + if rCtx != nil { + *r = *rCtx + } + var Params = NewGetVersionParams() + 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/get_version_parameters.go b/api/restapi/operations/get_version_parameters.go new file mode 100644 index 000000000..b261cda21 --- /dev/null +++ b/api/restapi/operations/get_version_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" +) + +// NewGetVersionParams creates a new GetVersionParams object +// +// There are no default values defined in the spec. +func NewGetVersionParams() GetVersionParams { + + return GetVersionParams{} +} + +// GetVersionParams contains all the bound params for the get version operation +// typically these are obtained from a http.Request +// +// swagger:parameters GetVersion +type GetVersionParams 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 NewGetVersionParams() beforehand. +func (o *GetVersionParams) 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_version_responses.go b/api/restapi/operations/get_version_responses.go new file mode 100644 index 000000000..d141583a0 --- /dev/null +++ b/api/restapi/operations/get_version_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" +) + +// GetVersionOKCode is the HTTP code returned for type GetVersionOK +const GetVersionOKCode int = 200 + +/* +GetVersionOK OK + +swagger:response getVersionOK +*/ +type GetVersionOK struct { + + /* + In: Body + */ + Payload *models.VersionGetEntry `json:"body,omitempty"` +} + +// NewGetVersionOK creates GetVersionOK with default headers values +func NewGetVersionOK() *GetVersionOK { + + return &GetVersionOK{} +} + +// WithPayload adds the payload to the get version o k response +func (o *GetVersionOK) WithPayload(payload *models.VersionGetEntry) *GetVersionOK { + o.Payload = payload + return o +} + +// SetPayload sets the payload to the get version o k response +func (o *GetVersionOK) SetPayload(payload *models.VersionGetEntry) { + o.Payload = payload +} + +// WriteResponse to the client +func (o *GetVersionOK) 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 + } + } +} + +// GetVersionUnauthorizedCode is the HTTP code returned for type GetVersionUnauthorized +const GetVersionUnauthorizedCode int = 401 + +/* +GetVersionUnauthorized Invalid authentication credentials + +swagger:response getVersionUnauthorized +*/ +type GetVersionUnauthorized struct { + + /* + In: Body + */ + Payload *models.Error `json:"body,omitempty"` +} + +// NewGetVersionUnauthorized creates GetVersionUnauthorized with default headers values +func NewGetVersionUnauthorized() *GetVersionUnauthorized { + + return &GetVersionUnauthorized{} +} + +// WithPayload adds the payload to the get version unauthorized response +func (o *GetVersionUnauthorized) WithPayload(payload *models.Error) *GetVersionUnauthorized { + o.Payload = payload + return o +} + +// SetPayload sets the payload to the get version unauthorized response +func (o *GetVersionUnauthorized) SetPayload(payload *models.Error) { + o.Payload = payload +} + +// WriteResponse to the client +func (o *GetVersionUnauthorized) 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 + } + } +} + +// GetVersionInternalServerErrorCode is the HTTP code returned for type GetVersionInternalServerError +const GetVersionInternalServerErrorCode int = 500 + +/* +GetVersionInternalServerError Internal service error + +swagger:response getVersionInternalServerError +*/ +type GetVersionInternalServerError struct { + + /* + In: Body + */ + Payload *models.Error `json:"body,omitempty"` +} + +// NewGetVersionInternalServerError creates GetVersionInternalServerError with default headers values +func NewGetVersionInternalServerError() *GetVersionInternalServerError { + + return &GetVersionInternalServerError{} +} + +// WithPayload adds the payload to the get version internal server error response +func (o *GetVersionInternalServerError) WithPayload(payload *models.Error) *GetVersionInternalServerError { + o.Payload = payload + return o +} + +// SetPayload sets the payload to the get version internal server error response +func (o *GetVersionInternalServerError) SetPayload(payload *models.Error) { + o.Payload = payload +} + +// WriteResponse to the client +func (o *GetVersionInternalServerError) 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 + } + } +} + +// GetVersionServiceUnavailableCode is the HTTP code returned for type GetVersionServiceUnavailable +const GetVersionServiceUnavailableCode int = 503 + +/* +GetVersionServiceUnavailable Maintanence mode + +swagger:response getVersionServiceUnavailable +*/ +type GetVersionServiceUnavailable struct { + + /* + In: Body + */ + Payload *models.Error `json:"body,omitempty"` +} + +// NewGetVersionServiceUnavailable creates GetVersionServiceUnavailable with default headers values +func NewGetVersionServiceUnavailable() *GetVersionServiceUnavailable { + + return &GetVersionServiceUnavailable{} +} + +// WithPayload adds the payload to the get version service unavailable response +func (o *GetVersionServiceUnavailable) WithPayload(payload *models.Error) *GetVersionServiceUnavailable { + o.Payload = payload + return o +} + +// SetPayload sets the payload to the get version service unavailable response +func (o *GetVersionServiceUnavailable) SetPayload(payload *models.Error) { + o.Payload = payload +} + +// WriteResponse to the client +func (o *GetVersionServiceUnavailable) 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_version_urlbuilder.go b/api/restapi/operations/get_version_urlbuilder.go new file mode 100644 index 000000000..ca4c6d5f3 --- /dev/null +++ b/api/restapi/operations/get_version_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" +) + +// GetVersionURL generates an URL for the get version operation +type GetVersionURL 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 *GetVersionURL) WithBasePath(bp string) *GetVersionURL { + 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 *GetVersionURL) SetBasePath(bp string) { + o._basePath = bp +} + +// Build a url path and query string +func (o *GetVersionURL) Build() (*url.URL, error) { + var _result url.URL + + var _path = "/version" + + _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 *GetVersionURL) 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 *GetVersionURL) String() string { + return o.Must(o.Build()).String() +} + +// BuildFull builds a full url with scheme, host, path and query string +func (o *GetVersionURL) BuildFull(scheme, host string) (*url.URL, error) { + if scheme == "" { + return nil, errors.New("scheme is required for a full url on GetVersionURL") + } + if host == "" { + return nil, errors.New("host is required for a full url on GetVersionURL") + } + + 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 *GetVersionURL) 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 4eccb25a7..f65a6b381 100644 --- a/api/restapi/operations/loxilb_rest_api_api.go +++ b/api/restapi/operations/loxilb_rest_api_api.go @@ -192,6 +192,9 @@ func NewLoxilbRestAPIAPI(spec *loads.Document) *LoxilbRestAPIAPI { GetStatusProcessHandler: GetStatusProcessHandlerFunc(func(params GetStatusProcessParams) middleware.Responder { return middleware.NotImplemented("operation GetStatusProcess has not yet been implemented") }), + GetVersionHandler: GetVersionHandlerFunc(func(params GetVersionParams) middleware.Responder { + return middleware.NotImplemented("operation GetVersion has not yet been implemented") + }), PostConfigBfdHandler: PostConfigBfdHandlerFunc(func(params PostConfigBfdParams) middleware.Responder { return middleware.NotImplemented("operation PostConfigBfd has not yet been implemented") }), @@ -400,6 +403,8 @@ type LoxilbRestAPIAPI struct { GetStatusFilesystemHandler GetStatusFilesystemHandler // GetStatusProcessHandler sets the operation handler for the get status process operation GetStatusProcessHandler GetStatusProcessHandler + // GetVersionHandler sets the operation handler for the get version operation + GetVersionHandler GetVersionHandler // 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 @@ -675,6 +680,9 @@ func (o *LoxilbRestAPIAPI) Validate() error { if o.GetStatusProcessHandler == nil { unregistered = append(unregistered, "GetStatusProcessHandler") } + if o.GetVersionHandler == nil { + unregistered = append(unregistered, "GetVersionHandler") + } if o.PostConfigBfdHandler == nil { unregistered = append(unregistered, "PostConfigBfdHandler") } @@ -1035,6 +1043,10 @@ func (o *LoxilbRestAPIAPI) initHandlerCache() { o.handlers["GET"] = make(map[string]http.Handler) } o.handlers["GET"]["/status/process"] = NewGetStatusProcess(o.context, o.GetStatusProcessHandler) + if o.handlers["GET"] == nil { + o.handlers["GET"] = make(map[string]http.Handler) + } + o.handlers["GET"]["/version"] = NewGetVersion(o.context, o.GetVersionHandler) if o.handlers["POST"] == nil { o.handlers["POST"] = make(map[string]http.Handler) } diff --git a/api/restapi/server.go b/api/restapi/server.go index c61df9e24..105444517 100644 --- a/api/restapi/server.go +++ b/api/restapi/server.go @@ -3,12 +3,12 @@ package restapi import ( + "github.com/loxilb-io/loxilb/options" "context" "crypto/tls" "crypto/x509" "errors" "fmt" - "github.com/loxilb-io/loxilb/options" "log" "net" "net/http" diff --git a/api/swagger.yml b/api/swagger.yml index a1144e51d..ac75898f5 100644 --- a/api/swagger.yml +++ b/api/swagger.yml @@ -2808,7 +2808,31 @@ paths: description: Maintenance mode schema: $ref: '#/definitions/Error' - +#---------------------------------------------- +# Version +#---------------------------------------------- + '/version': + get: + summary: Get version information in the device + description: Get version information + responses: + '200': + description: OK + schema: + $ref: '#/definitions/VersionGetEntry' + '401': + description: Invalid authentication credentials + schema: + $ref: '#/definitions/Error' + '500': + description: Internal service error + schema: + $ref: '#/definitions/Error' + '503': + description: Maintenance mode + schema: + $ref: '#/definitions/Error' + #---------------------------------------------- # BFD #---------------------------------------------- @@ -4099,6 +4123,16 @@ definitions: type: string description: Current state for BFD session + VersionGetEntry: + type: object + properties: + version: + type: string + description: Instance name + buildInfo: + type: string + description: build info + BfdEntry: type: object properties: diff --git a/common/common.go b/common/common.go index 6e3e5b6b0..7a741ea17 100644 --- a/common/common.go +++ b/common/common.go @@ -20,6 +20,12 @@ import ( "net" ) +const ( + Version = "0.9.7-beta" +) + +var BuildInfo string = "" + // This file defines the go interface implementation needed to interact with loxinet go module const ( diff --git a/main.go b/main.go index 8f14699f3..e214c54fe 100644 --- a/main.go +++ b/main.go @@ -22,12 +22,13 @@ import ( "time" "github.com/jessevdk/go-flags" + "github.com/loxilb-io/loxilb/common" opts "github.com/loxilb-io/loxilb/options" ln "github.com/loxilb-io/loxilb/pkg/loxinet" ) -var version string = "0.9.7-beta" -var buildInfo string = "" +// var version string = "0.9.7-beta" +// var buildInfo string = "" func main() { fmt.Printf("loxilb start\n") @@ -40,7 +41,7 @@ func main() { } if opts.Opts.Version { - fmt.Printf("loxilb version: %s %s\n", version, buildInfo) + fmt.Printf("loxilb version: %s %s\n", common.Version, common.BuildInfo) os.Exit(0) }