haproxy dataplaneapi golang sdk 简单使用

前边有简单说过基于go-swagger 生成haproxy dataplaneapi api 以下一个简单说明

环境准备

  • docker-compose 文件
version: "3"
services:
    grafana:
     image: grafana/grafana
     ports:
     - "3000:3000"
    prometheus:
     image: prom/prometheus
     volumes:
     - "./prometheus.yml:/etc/prometheus/prometheus.yml"
     ports:
     - "9090:9090"
    haproxy:
     build: ./
     ports:
     - "80:80"
     - "5555:5555"
     - "8404:8404"
     - "8080:8080"
     - "9000:9000"
     - "9001:9001"
     - "9002:9002"
     - "1000-1005:1000-1005"
     - "10080:10080"
    nginx1:
     image: nginx
     ports:
     - "8090:80"
    nginx2:
     image: nginx
     ports:
     - "8091:80"
  • haproxy dockerfile
    基于haproxy 团队的docker镜像(内置了dataplaneapi)
 
FROM haproxytech/haproxy-debian:2.2.1
COPY haproxy.cfg /usr/local/etc/haproxy/haproxy.cfg
  • demo haproxy 配置
global 
  user root
  group root
  master-worker
  stats socket /run/haproxy.sock mode 600 level admin
  stats timeout 2m
  log stdout local0
  mworker-max-reloads 3
  set-dumpable
defaults 
  mode http
  log global
  option httplog
  option redispatch
  timeout connect 5s
  timeout client 5s
  timeout server 5s
userlist api 
  user admin insecure-password dalong
resolvers dns 
  hold nx 30s
  hold obsolete 30s
  hold other 30s
  hold refused 30s
  hold timeout 30s
  hold valid 10s
  timeout resolve 1s
  timeout retry 1s
  resolve_retries 3
  parse-resolv-conf
frontend stats 
  bind *:8404
  stats enable
  stats uri /stats
  stats refresh 10s
  http-request use-service prometheus-exporter if { path /metrics }
frontend test_frontend 
  mode http
  maxconn 2000
  bind *:10080 name http
  default_backend test_backend
backend be_503 
  errorfile 503 /usr/local/etc/haproxy/errors/503.http
backend test_backend 
  mode http
  balance roundrobin
  server server1 nginx1:80 check maxconn 30 weight 100
program dataplane-api 
  command /usr/bin/dataplaneapi --log-level=debug --host 0.0.0.0 --port 5555 --haproxy-bin /usr/sbin/haproxy --config-file /usr/local/etc/haproxy/haproxy.cfg --reload-cmd "kill -SIGUSR2 1" --restart-cmd="" --reload-delay 5 --userlist=api
  no option start-on-reload
  • 启动效果

会有一个示例demo,以下是stat 界面

代码集成

以下是一个简单的代码集成,具体操作处理流程我有写过,可以参考 https://www.cnblogs.com/rongfengliang/p/12914925.html

 
package main
import (
  "context"
  "log"
  httptransport "github.com/go-openapi/runtime/client"
  "github.com/go-openapi/strfmt"
  "github.com/rongfengliang/haproxy-golang/client"
  "github.com/rongfengliang/haproxy-golang/client/backend"
  "github.com/rongfengliang/haproxy-golang/client/bind"
  "github.com/rongfengliang/haproxy-golang/client/frontend"
  "github.com/rongfengliang/haproxy-golang/client/server"
  "github.com/rongfengliang/haproxy-golang/client/transactions"
  "github.com/rongfengliang/haproxy-golang/models"
)
// String point
func String(s string) *string {
  return &s
}
// Bool point
func Bool(s bool) *bool {
  return &s
}
// Int64 point
func Int64(s int64) *int64 {
  return &s
}
func main() {
  // context object for  control connet
  ctx := context.Background()
  // 1. first get  transaction version
  client := client.New(httptransport.New("localhost:5555", "/v2", []string{"http"}), strfmt.Default)
  // make the authenticated request to get all items
  basicAuth := httptransport.BasicAuth("admin", "dalong")
  frontends, err := client.Frontend.GetFrontends(nil, basicAuth)
  if err != nil {
    log.Panicln("some wrong:", err)
  }
  versionID := frontends.ConfigurationVersion
  log.Println(versionID)
  // for test print frontend info
  for _, frontend := range frontends.GetPayload().Data {
    log.Println("get frontend info :", frontend.Name, frontend.Mode, frontend.DefaultBackend)
  }
  // 2. create transaction for generate id
  commitTransaction, err := client.Transactions.StartTransaction(&transactions.StartTransactionParams{Version: versionID, Context: ctx}, basicAuth)
  if err != nil {
    log.Panicln("create transaction some wrong:", err.Error())
  }
  transactionID := commitTransaction.Payload.ID
  log.Println(transactionID)
  // 3. create backend object
  createBackendCreated, createBackendAccepted, err := client.Backend.CreateBackend(&backend.CreateBackendParams{
    Context: ctx,
    Data: &models.Backend{
      Name: "dalongrong",
      Mode: "http",
      Balance: &models.Balance{
        Algorithm: String("roundrobin"),
      },
      Httpchk: &models.Httpchk{
        Method:  "HEAD",
        URI:     "/",
        Version: "HTTP/1.1",
      },
    },
    TransactionID: &transactionID,
  }, basicAuth)
  if err != nil {
    log.Panicln("create backend some wrong:", err.Error())
  }
  if createBackendCreated == nil {
    log.Println(createBackendAccepted.GetPayload())
  }
  // 4. add backend server to backend use create server wrapper
  createServerCreated, createServerAccepted, err := client.Server.CreateServer(&server.CreateServerParams{
    TransactionID: &transactionID,
    Backend:       "dalongrong",
    Context:       ctx,
    Data: &models.Server{
      Name:    "server1",
      Address: "nginx2",
      Port:    Int64(80),
      Check:   "disabled",
      Maxconn: Int64(30),
      Weight:  Int64(100),
    },
  }, basicAuth)
  if err != nil {
    log.Panicln("add  backend server has some wrong:", err.Error())
  }
  if createServerCreated == nil {
    log.Println(createServerAccepted.GetPayload())
  }
  // 5. create frontend
  createFrontendCreated, createFrontendAccepted, err := client.Frontend.CreateFrontend(&frontend.CreateFrontendParams{
    TransactionID: &transactionID,
    Data: &models.Frontend{
      Name:           "dalongrong_frontend",
      Mode:           "http",
      DefaultBackend: "dalongrong",
      Maxconn:        Int64(1000),
    },
    Context: ctx,
  }, basicAuth)
  if err != nil {
    log.Panicln("create  frontend  has some wrong:", err.Error())
  }
  if createFrontendCreated == nil {
    log.Println(createFrontendAccepted.GetPayload())
  }
  // 6. create frontend && backend bind
  createBindCreated, createBindAccepted, err := client.Bind.CreateBind(&bind.CreateBindParams{
    TransactionID: &transactionID,
    Frontend:      "dalongrong_frontend",
    Data: &models.Bind{
      Name:    "httpdemo",
      Address: "*",
      Port:    Int64(9000),
    },
    Context: ctx,
  }, basicAuth)
  if err != nil {
    log.Panicln("create  bind  has some wrong:", err.Error())
  }
  if createBindCreated == nil {
    log.Println(createBindAccepted.GetPayload())
  }
  // 7. apply transaction && do commit
  commitTransactionOK, commitTransactionAccepted, err := client.Transactions.CommitTransaction(&transactions.CommitTransactionParams{
    ID:      transactionID,
    Context: ctx,
  }, basicAuth)
  if err != nil {
    log.Panicln("apply haproxy config   has some wrong:", err.Error())
  }
  if commitTransactionOK != nil {
    // apply config ok
    log.Println(commitTransactionOK.GetPayload())
  }
  if commitTransactionAccepted != nil {
    // accept but not apply success
    log.Println(commitTransactionAccepted.GetPayload())
  }
}
  • 运行
go run main.go
 
 
  • 效果

说明

以上是一个简单的使用说明,实际上我们基于swagger api 也可以提供其他语言的支持(nodejs,golang)同时也可以制作一个dashboard,当然新版本对于
haproxy 配置的更新处理使用了一个原子操作的 renameio,简化了以前配置reload 的处理

参考资料

https://hub.docker.com/r/haproxytech/haproxy-debian
https://github.com/rongfengliang/haproxy-dataplaneapi-golang
https://github.com/haproxytech/dataplaneapi
https://github.com/google/renameio

原文地址:https://www.cnblogs.com/rongfengliang/p/13394103.html