You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
207 lines
6.3 KiB
207 lines
6.3 KiB
// 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 runtime
|
|
|
|
import (
|
|
"fmt"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/haproxytech/client-native/v6/errors"
|
|
"github.com/haproxytech/client-native/v6/misc"
|
|
"github.com/haproxytech/client-native/v6/models"
|
|
)
|
|
|
|
// AddServer adds a new server to a backend
|
|
func (s *SingleRuntime) AddServer(backend, name, attributes string) error {
|
|
cmd := fmt.Sprintf("add server %s/%s %s ssl verify required ca-file ca-certificates.crt sni req.hdr(Host)", backend, name, attributes)
|
|
return s.Execute(cmd)
|
|
}
|
|
|
|
// DeleteServer removes a server from a backend
|
|
func (s *SingleRuntime) DeleteServer(backend, name string) error {
|
|
cmd := fmt.Sprintf("del server %s/%s", backend, name)
|
|
return s.Execute(cmd)
|
|
}
|
|
|
|
// SetServerAddr set ip [port] for server
|
|
func (s *SingleRuntime) SetServerAddr(backend, server string, ip string, port int) error {
|
|
var cmd string
|
|
if port > 0 {
|
|
cmd = fmt.Sprintf("set server %s/%s addr %s port %d", backend, server, ip, port)
|
|
} else {
|
|
cmd = fmt.Sprintf("set server %s/%s addr %s", backend, server, ip)
|
|
}
|
|
return s.Execute(cmd)
|
|
}
|
|
|
|
// SetServerState set state for server
|
|
func (s *SingleRuntime) SetServerState(backend, server string, state string) error {
|
|
if !ServerStateValid(state) {
|
|
return fmt.Errorf("bad request")
|
|
}
|
|
cmd := fmt.Sprintf("set server %s/%s state %s", backend, server, state)
|
|
return s.Execute(cmd)
|
|
}
|
|
|
|
// SetServerWeight set weight for server
|
|
func (s *SingleRuntime) SetServerWeight(backend, server string, weight string) error {
|
|
if !ServerWeightValid(weight) {
|
|
return fmt.Errorf("bad request")
|
|
}
|
|
cmd := fmt.Sprintf("set server %s/%s weight %s", backend, server, weight)
|
|
return s.Execute(cmd)
|
|
}
|
|
|
|
// SetServerHealth set health for server
|
|
func (s *SingleRuntime) SetServerHealth(backend, server string, health string) error {
|
|
if !ServerHealthValid(health) {
|
|
return fmt.Errorf("bad request")
|
|
}
|
|
cmd := fmt.Sprintf("set server %s/%s health %s", backend, server, health)
|
|
return s.Execute(cmd)
|
|
}
|
|
|
|
// SetServerCheckPort set health heck port for server
|
|
func (s *SingleRuntime) SetServerCheckPort(backend, server string, port int) error {
|
|
if !(port > 0 && port <= 65535) {
|
|
return fmt.Errorf("bad request")
|
|
}
|
|
return s.Execute(fmt.Sprintf("set server %s/%s check-port %d", backend, server, port))
|
|
}
|
|
|
|
// EnableAgentCheck enable agent check for server
|
|
func (s *SingleRuntime) EnableAgentCheck(backend, server string) error {
|
|
cmd := fmt.Sprintf("enable agent %s/%s", backend, server)
|
|
return s.Execute(cmd)
|
|
}
|
|
|
|
// DisableAgentCheck disable agent check for server
|
|
func (s *SingleRuntime) DisableAgentCheck(backend, server string) error {
|
|
cmd := fmt.Sprintf("disable agent %s/%s", backend, server)
|
|
return s.Execute(cmd)
|
|
}
|
|
|
|
// EnableServer marks server as UP
|
|
func (s *SingleRuntime) EnableServer(backend, server string) error {
|
|
cmd := fmt.Sprintf("enable server %s/%s", backend, server)
|
|
return s.Execute(cmd)
|
|
}
|
|
|
|
// DisableServer marks server as DOWN for maintenance
|
|
func (s *SingleRuntime) DisableServer(backend, server string) error {
|
|
cmd := fmt.Sprintf("disable server %s/%s", backend, server)
|
|
return s.Execute(cmd)
|
|
}
|
|
|
|
// SetServerAgentAddr set agent-addr for server
|
|
func (s *SingleRuntime) SetServerAgentAddr(backend, server string, addr string) error {
|
|
cmd := fmt.Sprintf("set server %s/%s agent-addr %s", backend, server, addr)
|
|
return s.Execute(cmd)
|
|
}
|
|
|
|
// SetServerAgentSend set agent-send for server
|
|
func (s *SingleRuntime) SetServerAgentSend(backend, server string, send string) error {
|
|
cmd := fmt.Sprintf("set server %s/%s agent-send %s", backend, server, send)
|
|
return s.Execute(cmd)
|
|
}
|
|
|
|
// GetServersState returns servers runtime state
|
|
func (s *SingleRuntime) GetServersState(backend string) (models.RuntimeServers, error) {
|
|
cmd := fmt.Sprintf("show servers state %s", backend)
|
|
result, err := s.ExecuteWithResponse(cmd)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return parseRuntimeServers(result)
|
|
}
|
|
|
|
// GetServersState returns server runtime state
|
|
func (s *SingleRuntime) GetServerState(backend, server string) (*models.RuntimeServer, error) {
|
|
cmd := fmt.Sprintf("show servers state %s", backend)
|
|
result, err := s.ExecuteWithResponse(cmd)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
lines := strings.Split(result, "\n")
|
|
if strings.TrimSpace(lines[0]) != "1" {
|
|
return nil, fmt.Errorf("unsupported output format version, supporting format version 1")
|
|
}
|
|
|
|
for _, line := range lines {
|
|
if strings.TrimSpace(line) == "" || strings.HasPrefix(line, "#") || strings.TrimSpace(line) == "1" {
|
|
continue
|
|
}
|
|
fields := strings.Split(line, " ")
|
|
if fields[3] != server {
|
|
continue
|
|
}
|
|
return parseRuntimeServer(line), nil
|
|
}
|
|
return nil, fmt.Errorf("server state for %s/%s: %w", backend, server, errors.ErrNotFound)
|
|
}
|
|
|
|
func parseRuntimeServers(output string) (models.RuntimeServers, error) {
|
|
lines := strings.Split(output, "\n")
|
|
result := models.RuntimeServers{}
|
|
|
|
if strings.TrimSpace(lines[0]) != "1" {
|
|
return nil, fmt.Errorf("unsupported output format version, supporting format version 1")
|
|
}
|
|
for _, line := range lines[1:] {
|
|
if strings.TrimSpace(line) == "" || strings.HasPrefix(line, "#") || strings.TrimSpace(line) == "1" {
|
|
continue
|
|
}
|
|
result = append(result, parseRuntimeServer(line))
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
func parseRuntimeServer(line string) *models.RuntimeServer {
|
|
fields := strings.Split(line, " ")
|
|
|
|
if len(fields) < 19 {
|
|
return nil
|
|
}
|
|
|
|
p, err := strconv.ParseInt(fields[18], 10, 64)
|
|
var port *int64
|
|
if err == nil {
|
|
port = &p
|
|
}
|
|
|
|
admState, _ := misc.GetServerAdminState(fields[6])
|
|
|
|
var opState string
|
|
switch fields[5] {
|
|
case "0":
|
|
opState = "down"
|
|
case "3":
|
|
opState = "stopping"
|
|
case "1", "2":
|
|
opState = "up"
|
|
}
|
|
|
|
return &models.RuntimeServer{
|
|
Name: fields[3],
|
|
Address: fields[4],
|
|
Port: port,
|
|
ID: fields[2],
|
|
AdminState: admState,
|
|
OperationalState: opState,
|
|
}
|
|
}
|
|
|