basic-sync

command
v0.2.0-alpha.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 5, 2026 License: Apache-2.0 Imports: 7 Imported by: 0

README

Basic Sync Example

A runnable Go program that drives the pkg/dataplane Client end-to-end: connect, sync a small HAProxy config, inspect the structured result, and preview an additional change with DryRun.

The program lives in main.go and targets a stand-alone HAProxy + Dataplane API — no Kubernetes cluster required. Use it as a template when scripting one-off configuration pushes, or as a smoke test when investigating Dataplane API connectivity.

Prerequisites

  1. An HAProxy binary with a running Dataplane API. Inside the HAProxy config:

    program api
        command dataplaneapi -f /etc/haproxy/dataplaneapi.yml
    
  2. A dataplaneapi.yml that exposes the API on a port this program can reach:

    dataplaneapi:
      host: 0.0.0.0
      port: 5555
      user:
        - insecure: true
          password: admin
          name: admin
    

Configure and Run

The example reads three environment variables with sensible defaults; override them for your environment:

export HAPROXY_URL=http://localhost:5555/v3   # /v3 only — the library detects v3.0/v3.1/v3.2/v3.3 at startup. Trailing /v2 is silently rewritten to /v3 for the version-detection probe but no v2-only operations are supported.
export HAPROXY_USER=admin
export HAPROXY_PASS=admin

go run main.go

Expected Output

Creating dataplane client...
Connected to HAProxy at http://localhost:5555/v3

Syncing HAProxy configuration...

Sync completed successfully!
Duration: 1.234s
Operations applied: 5
Sync mode: reload
HAProxy reloaded: reload-123

Applied operations:
  1. [create] web-servers: Created backend
  2. [create] web-servers/web1: Created server
  3. [create] web-servers/web2: Created server
  4. [create] http-in: Created frontend
  5. [update] global: Updated global settings

--- Dry Run Example ---
Would apply 1 operations:
  1. [create] web-servers/web3: Would create server

Example completed successfully!

HAProxy reloaded only appears when the Dataplane API returns HTTP 202 (structural change requiring a reload); purely runtime-API updates (weight/address/port/maintenance) print "No HAProxy reload required".

What the Program Demonstrates

All four patterns below are exactly what pkg/dataplane exposes publicly — if you're writing code against the controller's sync library elsewhere, the snippets in main.go are good starting points.

1. Reusable client
client, err := dataplane.NewClient(ctx, &endpoint)
if err != nil {
    return err
}
defer client.Close()

r1, _ := client.Sync(ctx, config1, nil, nil)
r2, _ := client.Sync(ctx, config2, nil, nil)

NewClient takes a pointer (*Endpoint) and performs one round-trip to /v3/info to detect the Dataplane API version. Reuse the returned *Client for every subsequent call.

2. Structured errors
result, err := client.Sync(ctx, desired, nil, opts)
if err != nil {
    if syncErr, ok := errors.AsType[*dataplane.SyncError](err); ok {
        log.Printf("failed at %s: %s", syncErr.Stage, syncErr.Message)
        for _, hint := range syncErr.Hints {
            log.Printf("  hint: %s", hint)
        }
    }
    return err
}

errors.AsType[T] is the Go 1.26 generic helper used in main.go. The traditional var syncErr *T; errors.As(err, &syncErr) two-liner still works if you're targeting an older toolchain.

SyncError.Stage indicates where the failure occurred — connection setup (connect), config parsing (parse-current / parse-desired), structural comparison (compare, compare_ssl, compare_maps, …), the per-type pre-config aux upload (sync_ssl_pre, sync_maps_pre, …), the transactional apply / commit (apply, commit), reload verification (reload_verification), or the raw-config fallback (fallback). The full list lives on the SyncError.Stage godoc. Hints are actionable suggestions emitted by the library.

3. Inspecting the result
fmt.Printf("applied %d operations in %v\n", len(result.AppliedOperations), result.Duration)

if result.ReloadTriggered {
    fmt.Printf("reload: %s\n", result.ReloadID)
}
if result.SyncMode == dataplane.SyncModeRuntime {
    fmt.Println("applied via runtime API (no reload)")
}

for _, op := range result.AppliedOperations {
    fmt.Printf("[%s] %s: %s\n", op.Type, op.Resource, op.Description)
}
4. Dry run
diff, err := client.DryRun(ctx, candidateConfig)
if err != nil {
    return err
}
if diff.HasChanges {
    fmt.Printf("would apply %d operations\n", len(diff.PlannedOperations))
}

DryRun runs the full compare pipeline but skips the apply step; handy for CI preflight checks.

See Also

License

Apache-2.0 — see root LICENSE.

Documentation

Overview

Basic example demonstrating the dataplane Client API

This example shows how to:

  • Create a dataplane Client
  • Sync a simple HAProxy configuration
  • Handle errors properly
  • Inspect sync results

Prerequisites:

  • HAProxy running with Dataplane API enabled
  • Dataplane API accessible at the configured endpoint

Configuration:

Set these environment variables or modify the code:
- HAPROXY_URL: Dataplane API endpoint (default: http://localhost:5555/v3; /v2 still accepted)
- HAPROXY_USER: Basic auth username (default: admin)
- HAPROXY_PASS: Basic auth password (default: admin)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL