# ![HAProxy](assets/images/haproxy-weblogo-210x49.png "HAProxy")

## HAProxy Native Golang Client

[![Contributors](https://img.shields.io/github/contributors/haproxytech/client-native?color=purple)](https://github.com/haproxy/haproxy/blob/master/CONTRIBUTING)
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE)

**HAProxy Native Client** is a client that exposes methods for reading and changing HAProxy configuration files, and executing commands and parsing the output of the HAProxy Runtime API (via unix socket, AKA stats socket in HAProxy).

## HAProxy Models

This project contains structs and validation methods that are autogenerated using [go-swagger](https://github.com/go-swagger/go-swagger) from the swagger specification found [here](https://github.com/haproxytech/client-native/blob/master/specification/build/haproxy_spec.yaml).These structs are also used in the [DataPlaneAPI](http://github.com/haproxytech/dataplaneapi)

### Requirements

[go-swagger v0.30.2](https://github.com/go-swagger/go-swagger/releases/tag/v0.30.2). Note that at the moment you need to use version 0.30.2

models can be generated with [make models](Makefile). It automatically combines specification parts into a single file, and then use that to generate models.

## Usage Example

```go
//import cfg_opt "github.com/haproxytech/client-native/v5/configuration/options"
confClient, err := configuration.New(context.Background(),
    cfg_opt.ConfigurationFile(haproxyOptions.ConfigFile),
    cfg_opt.HAProxyBin(haproxyOptions.HAProxy),
    cfg_opt.Backups(haproxyOptions.BackupsNumber),
    cfg_opt.UsePersistentTransactions,
    cfg_opt.TransactionsDir(haproxyOptions.TransactionDir),
    cfg_opt.MasterWorker,
    cfg_opt.UseMd5Hash,
)
if err != nil {
    return nil, fmt.Errorf("error setting up configuration client: %s", err.Error())
}

// runtime
// import runtime_options "github.com/haproxytech/client-native/v5/runtime/options"
nbproc := 8
ms := runtime_options.MasterSocket(masterSocket, nbproc)
runtimeClient, err = runtime_api.New(ctx, ms)
if err != nil {
    return nil, fmt.Errorf("error setting up runtime client: %s", err.Error())
}
// or if not using master-worker
socketList := map[int]string{
    1: "/var/run/haproxy.sock"
}
sockets := runtime_options.Sockets(socketList)
runtimeClient, err = runtime_api.New(ctx, mapsDir, sockets)
if err != nil {
    return nil, fmt.Errorf("error setting up runtime client: %s", err.Error())
}
// end runtime

// import "github.com/haproxytech/client-native/v5/options"
opt := []options.Option{
    options.Configuration(confClient),
    options.Runtime(runtimeClient),
}

// aditional options - not mandatory

//maps storage
mapStorage, err := storage.New(MapsDir, storage.MapsType)
if err != nil {
    log.Fatalf("error initializing map storage: %v", err)
}
opt = append(opt, options.MapStorage(mapStorage))

//ssl cert storage
sslCertStorage, err := storage.New(SSLCertsDir, storage.SSLType)
if err != nil {
    log.Fatalf("error initializing SSL certs storage: %v", err)
}
opt = append(opt, options.SSLCertStorage(sslCertStorage))

// general storage
generalStorage, err := storage.New(GeneralStorage, storage.GeneralType)
if err != nil {
    log.Fatalf("error initializing General storage: %v", err)
}
opt = append(opt, options.GeneralStorage(generalStorage))

//spoe
prms := spoe.Params{
    SpoeDir:        SpoeDir,
    TransactionDir: SpoeTransactionDir,
}
spoe, err := spoe.NewSpoe(prms)
if err != nil {
    log.Fatalf("error setting up spoe: %v", err)
}
opt = append(opt, options.Spoe(spoe))

// combine all together and create a client
client, err := client_native.New(cyx, opt...)
if err != nil {
    log.Fatalf("Error initializing configuration client: %v", err)
}

// fetch configuration handler
configuration, err := client.Configuration()
if err != nil {
    fmt.Println(err.Error())
}

//fetch all backends
bcks, err := configuration.GetBackends(t)
if err != nil {
    fmt.Println(err.Error())
}
//...

backendsJSON, err := bcks.MarshallBinary()

if err != nil {
    fmt.Println(err.Error())
}

fmt.Println(string(backendsJSON))
//...

```

## Contributing

For commit messages and general style please follow the haproxy project's [CONTRIBUTING guide](https://github.com/haproxy/haproxy/blob/master/CONTRIBUTING) and use that where applicable.
