Skip to content

Commit

Permalink
Merge pull request #18 from nik-netlox/main
Browse files Browse the repository at this point in the history
BFD session get and set API added
  • Loading branch information
TrekkieCoder authored Feb 23, 2024
2 parents e1f0736 + dca6391 commit b855588
Show file tree
Hide file tree
Showing 8 changed files with 263 additions and 3 deletions.
2 changes: 1 addition & 1 deletion cmd/create/create_loadbalancer.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func ReadCreateLoadBalancerOptions(o *CreateLoadBalancerOptions, args []string)
if val := net.ParseIP(args[0]); val != nil {
o.ExternalIP = args[0]
} else {
return fmt.Errorf("Externel IP '%s' is invalid format", args[0])
return fmt.Errorf("externel IP '%s' is invalid format", args[0])
}
return nil
}
Expand Down
1 change: 1 addition & 0 deletions cmd/get/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ func GetCmd(restOptions *api.RESTOptions) *cobra.Command {
GetCmd.AddCommand(NewGetLogLevelCmd(restOptions))
GetCmd.AddCommand(NewGetBGPNeighborCmd(restOptions))
GetCmd.AddCommand(NewGetHaStateCmd(restOptions))
GetCmd.AddCommand(NewGetBFDCmd(restOptions))

return GetCmd
}
Expand Down
97 changes: 97 additions & 0 deletions cmd/get/get_bfd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*
* 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 get

import (
"context"
"encoding/json"
"fmt"
"io"
"loxicmd/pkg/api"
"net/http"
"time"

"github.com/spf13/cobra"
)

func NewGetBFDCmd(restOptions *api.RESTOptions) *cobra.Command {
var GetBFDCmd = &cobra.Command{
Use: "bfd",
Short: "Get all BFD sessions",
Long: `It shows BFD Sessions in the LoxiLB`,

Run: func(cmd *cobra.Command, args []string) {
client := api.NewLoxiClient(restOptions)
ctx := context.TODO()
var cancel context.CancelFunc
if restOptions.Timeout > 0 {
ctx, cancel = context.WithTimeout(context.TODO(), time.Duration(restOptions.Timeout)*time.Second)
defer cancel()
}
resp, err := client.Status().SetUrl("config/bfd/all").Get(ctx)
if err != nil {
fmt.Printf("Error: %s\n", err.Error())
return
}
if resp.StatusCode == http.StatusOK {
PrintGetBFDResult(resp, *restOptions)
return
}

},
}

return GetBFDCmd
}

func PrintGetBFDResult(resp *http.Response, o api.RESTOptions) {
BFDresp := api.BFDSessionGet{}
var data [][]string
resultByte, err := io.ReadAll(resp.Body)
if err != nil {
fmt.Printf("Error: Failed to read HTTP response: (%s)\n", err.Error())
return
}

if err := json.Unmarshal(resultByte, &BFDresp); err != nil {
fmt.Printf("Error: Failed to unmarshal HTTP response: (%s)\n", err.Error())
return
}

// if json options enable, it print as a json format.
if o.PrintOption == "json" {
resultIndent, _ := json.MarshalIndent(BFDresp, "", " ")
fmt.Println(string(resultIndent))
return
}

// Table Init
table := TableInit()

// Making load balance data
for _, bfd := range BFDresp.BFDSessionAttr {
if (o.PrintOption == "wide") {
table.SetHeader(BFD_WIDE_TITLE)
data = append(data, []string{bfd.Instance, bfd.RemoteIP, bfd.SourceIP,
fmt.Sprintf("%d",bfd.Port), fmt.Sprintf("%d us",bfd.Interval), fmt.Sprintf("%d",bfd.RetryCount), bfd.State})
} else {
table.SetHeader(BFD_TITLE)
data = append(data, []string{bfd.Instance, bfd.RemoteIP, bfd.State})
}
}
// Rendering the load balance data to table
TableShow(data, table)
}
2 changes: 2 additions & 0 deletions cmd/get/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,6 @@ var (
PARAM_TITLE = []string{"Param Name", "Value"}
BGPNEIGHBOR_TITLE = []string{"Peer", "AS", "UP/Down", "State"}
HASTATE_TITLE = []string{"Instance", "HAState"}
BFD_TITLE = []string{"Instance", "RemoteIP", "State"}
BFD_WIDE_TITLE = []string{"Instance", "RemoteIP", "SourceIP", "Port", "Interval","Retry Count", "State"}
)
4 changes: 2 additions & 2 deletions cmd/set/set.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@ func SetParamCmd(restOptions *api.RESTOptions) *cobra.Command {
SetParamCmd := &cobra.Command{
Use: "set",
Short: "Set configurations",
Long: `Set the configuration like log-level`,
Long: `Set the configuration like log-level or bfd session`,
Run: func(cmd *cobra.Command, args []string) {
_ = cmd
_ = args

},
}
SetParamCmd.AddCommand(NewSetLogLevelCmd(restOptions))
SetParamCmd.AddCommand(NewSetBFDCmd(restOptions))
return SetParamCmd
}

Expand Down
95 changes: 95 additions & 0 deletions cmd/set/set_bfd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*
* 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 set

import (
"context"
"errors"
"fmt"
"loxicmd/pkg/api"
"net/http"
"time"
"net"

"github.com/spf13/cobra"
)

// NewLogLevelCmd represents the save command
func NewSetBFDCmd(restOptions *api.RESTOptions) *cobra.Command {
o := api.BFDSessionInfo{}
SetBFDCmd := &cobra.Command{
Use: "bfd remoteIP [--instance=<instance>] [--interval=<interval>] [--retryCount=<count>]",
Short: "bfd session configuration",
Long: `bfd session congfigration
--instance - Cluster Instance name
--interval - BFD packet Tx interval value in microseconds
--retryCount - Maximum number of retry to detect failure`,

Aliases: []string{"bfd-session"},
Run: func(cmd *cobra.Command, args []string) {

// Make paramMod
if err := ReadSetBfdOptions(&o, args); err != nil {
fmt.Printf("Error: %s\n", err.Error())
return
}
resp, err := SetBFDAPICall(restOptions, o)
if err != nil {
fmt.Printf("Error: %s\n", err.Error())
return
}
if resp.StatusCode == http.StatusOK {
PrintSetResult(resp, *restOptions)
return
}

},
}
SetBFDCmd.Flags().StringVarP(&o.Instance, "instance", "", "default", "Specify the cluster instance name")
SetBFDCmd.Flags().Uint64VarP(&o.Interval, "interval", "", 0, "Specify the BFD packet tx interval (in microseconds)")
SetBFDCmd.Flags().Uint8VarP(&o.RetryCount, "retryCount", "", 0, "Specify the mark num to segregate a load-balancer VIP service")

return SetBFDCmd
}

func ReadSetBfdOptions(o *api.BFDSessionInfo, args []string) error {
if len(args) > 1 {
return errors.New("set bfd command get so many args")
} else if len(args) < 1 {
return errors.New("set bfd need <RemoteIP> args")
}

if val := net.ParseIP(args[0]); val != nil {
o.RemoteIP = args[0]
} else {
return fmt.Errorf("remote IP '%s' is invalid format", args[0])
}

return nil
}


func SetBFDAPICall(restOptions *api.RESTOptions, bfdModel api.BFDSessionInfo) (*http.Response, error) {
client := api.NewLoxiClient(restOptions)
ctx := context.TODO()
var cancel context.CancelFunc
if restOptions.Timeout > 0 {
ctx, cancel = context.WithTimeout(context.TODO(), time.Duration(restOptions.Timeout)*time.Second)
defer cancel()
}

return client.BFDSession().Create(ctx, bfdModel)
}
51 changes: 51 additions & 0 deletions pkg/api/bfd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* 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 api

type BFDSession struct {
CommonAPI
}

// HAStateGetEntry c i status get entry
//
// swagger:model CIStatusGetEntry
type BFDSessionGet struct {
BFDSessionAttr []BFDSessionInfo `json:"Attr"`
}

type BFDSessionInfo struct {
// Instance name
Instance string `json:"instance,omitempty"`

// RemoteIP - Remote IP for BFD session
RemoteIP string `json:"remoteIp,omitempty"`

// Interval - Tx Interval between BFD packets
SourceIP string `json:"sourceIp,omitempty"`

// Port - BFD session port
Port uint16 `json:"port,omitempty"`

// Interval - Tx Interval between BFD packets
Interval uint64 `json:"interval,omitempty"`

// RetryCount - Retry Count for detecting failure
RetryCount uint8 `json:"retryCount,omitempty"`

// Current BFD State
State string `json:"state,omitempty"`
}

14 changes: 14 additions & 0 deletions pkg/api/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ const (
loxiParamResource = "config/params"
loxiBGPNeighResource = "config/bgp/neigh"
loxiStatusResource = "status"
loxiBFDSessionResource = "config/bfd"
)

type LoxiClient struct {
Expand Down Expand Up @@ -305,3 +306,16 @@ func (l *LoxiClient) BGPNeighbor() *BGPNeighbor {
},
}
}

func (l *LoxiClient) BFDSession() *BFDSession {
return &BFDSession{
CommonAPI: CommonAPI{
restClient: &l.restClient,
requestInfo: RequestInfo{
provider: loxiProvider,
apiVersion: loxiApiVersion,
resource: loxiBFDSessionResource,
},
},
}
}

0 comments on commit b855588

Please sign in to comment.