Skip to content

Commit

Permalink
BUG/MAJOR: runtime admin state: correct returning state
Browse files Browse the repository at this point in the history
srv_admin_state is a mask and should be treated like that
maint has most prority, then drain, everything else is ready
  • Loading branch information
oktalz committed Dec 9, 2020
1 parent 63b2208 commit e9c72a8
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 9 deletions.
60 changes: 60 additions & 0 deletions misc/bits.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright 2019 HAProxy Technologies
//
// 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 misc

import (
"strconv"
)

type Bits uint64

const (
B0 Bits = 1 << iota
B1
B2
B3
B4
B5
B6
B7
)

func (b *Bits) Any(flags ...Bits) bool {
for _, flag := range flags {
if *b&flag != 0 {
return true
}
}
return false
}

// GetServerAdminState parses srv_admin_state, srv_admin_state is a mask
func GetServerAdminState(state string) (string, error) {
// 23 0100011 - mask for maint
// 18 0011000 - mask for drain
val, err := strconv.ParseUint(state, 16, 64)
if err != nil {
return "", err
}
mask := Bits(val)
if mask.Any(B0, B1, B5) {
return "maint", nil
}
if mask.Any(B3, B4) {
return "drain", nil
}
return "ready", nil
}
50 changes: 50 additions & 0 deletions misc/bits_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright 2019 HAProxy Technologies
//
// 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 misc

import "testing"

func TestGetServerAdminState(t *testing.T) {
tests := []struct {
args string
want string
wantErr bool
}{
{"", "", true},
{"-", "", true},
{"0", "ready", false},
{"1", "maint", false},
{"2", "maint", false},
{"4", "ready", false},
{"5", "maint", false},
{"8", "drain", false},
{"10", "drain", false},
{"20", "maint", false},
{"40", "ready", false},
}
for _, tt := range tests {
t.Run(tt.args, func(t *testing.T) {
got, err := GetServerAdminState(tt.args)
if (err != nil) != tt.wantErr {
t.Errorf("GetServerAdminState() error = %v, wantErr %v", err, tt.wantErr)
return
}
if got != tt.want {
t.Errorf("GetServerAdminState() = %v, want %v", got, tt.want)
}
})
}
}
11 changes: 2 additions & 9 deletions runtime/servers.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"strconv"
"strings"

"github.com/haproxytech/client-native/v2/misc"
"github.com/haproxytech/models/v2"
)

Expand Down Expand Up @@ -170,15 +171,7 @@ func parseRuntimeServer(line string) *models.RuntimeServer {
port = &p
}

var admState string
switch fields[6] {
case "0":
admState = "ready"
case "1", "2", "4", "20", "40":
admState = "maint"
case "8", "10":
admState = "drain"
}
admState, _ := misc.GetServerAdminState(fields[6])

var opState string
switch fields[5] {
Expand Down

0 comments on commit e9c72a8

Please sign in to comment.