{"id":51777458,"url":"https://github.com/pgsty/go-patroni","last_synced_at":"2026-07-20T07:31:15.326Z","repository":{"id":371821776,"uuid":"1303466684","full_name":"pgsty/go-patroni","owner":"pgsty","description":"Golang SDK for Patroni API","archived":false,"fork":false,"pushed_at":"2026-07-17T04:32:12.000Z","size":390,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-17T06:15:38.217Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pgsty.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-07-17T02:31:33.000Z","updated_at":"2026-07-17T04:30:39.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/pgsty/go-patroni","commit_stats":null,"previous_names":["pgsty/go-patroni"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/pgsty/go-patroni","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pgsty%2Fgo-patroni","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pgsty%2Fgo-patroni/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pgsty%2Fgo-patroni/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pgsty%2Fgo-patroni/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pgsty","download_url":"https://codeload.github.com/pgsty/go-patroni/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pgsty%2Fgo-patroni/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35678463,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-07-20T02:08:10.276Z","status":"ssl_error","status_checked_at":"2026-07-20T02:08:09.736Z","response_time":111,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-07-20T07:31:14.776Z","updated_at":"2026-07-20T07:31:15.318Z","avatar_url":"https://github.com/pgsty.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# go-patroni\n\n`go-patroni` is an independent Go SDK for Patroni and a native Go replacement\nfor `patronictl`. It can be imported by BOAR, Pig, or any third-party Go\napplication; it has no dependency on BOAR.\n\nThe module provides two API levels:\n\n- a direct, typed REST client for every Patroni 4.1.4 HTTP method/path contract;\n- a higher-level `control.Service` and `runtime` that implement Patroni DCS,\n  PostgreSQL, Citus, safety, and `patronictl` orchestration semantics.\n\nPatroni `\u003e=3.0.0,\u003c5.0.0` is the audited compatibility range. Patroni 4.x is the\nprimary target; version-gated features are rejected before an unsupported write\nis sent. Embedding products may narrow this range per `control.Service` or\n`runtime.Environment` instance without changing package-global state.\n\n## Install\n\nThe SDK requires Go 1.25 or newer.\n\n```bash\ngo get github.com/pgsty/go-patroni@latest\n```\n\nInstall the command-line client independently:\n\n```bash\ngo install github.com/pgsty/go-patroni/cmd/patronictl@latest\npatronictl --help\n```\n\n## Documentation\n\n- [中文用户与 Agent 使用手册](docs/user-guide.zh-CN.md) covers direct REST,\n  Patroni YAML/runtime, CLI, and machine-output workflows.\n- [中文 SDK 指南与实现审计](docs/go-patroni-sdk.zh-CN.md) records API coverage,\n  version compatibility, design details, and review findings.\n- [Contract specifications](docs/spec/README.md) define the normative project\n  invariants and release evidence.\n\n## Direct REST API\n\nThe root package only needs a Patroni REST URL at runtime. It does not require\netcd, a Patroni YAML file, or PostgreSQL access.\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \"fmt\"\n    \"log\"\n    \"time\"\n\n    patroni \"github.com/pgsty/go-patroni\"\n)\n\nfunc main() {\n    client, err := patroni.NewClient(patroni.ClientOptions{\n        Timeout:    5 * time.Second,\n        Authorizer: patroni.NewBasicAuth(\"patroni\", \"secret\"),\n        UserAgent:  \"pig/1.0\",\n    })\n    if err != nil {\n        log.Fatal(err)\n    }\n\n    response, err := client.GetPatroni(context.Background(), \"https://db1:8008\")\n    if err != nil {\n        // A typed error describes request, authentication, transport, response,\n        // decode, and ambiguous-write delivery states. The response still\n        // retains status, headers, and the raw body when they were received.\n        log.Fatal(err)\n    }\n    fmt.Printf(\"%s %s %s\\n\", response.Data.Patroni.Name,\n        response.Data.Role, response.Data.Patroni.Version)\n}\n```\n\nFor TLS/mTLS and encrypted private keys, construct a transport with\n`patroni.NewHTTPTransport`. `Response[T]` always retains the status code,\nheaders, and raw response bytes, so newer upstream fields remain available even\nbefore a typed DTO is extended. `EndpointCatalog` exposes all 75 audited\nmethod/path rows and their risk classes.\n\n## High-level SDK\n\nThe high-level runtime reads a normal Patroni `patronictl.yaml`, connects to\netcd3, discovers member REST URLs, and assembles the REST, DCS, and PostgreSQL\nclients used by `control.Service`:\n\n```go\nenvironment, err := patroniruntime.NewEnvironment(ctx,\n    patroniruntime.EnvironmentOptions{\n        Load: config.LoadRequest{Path: \"/etc/patroni/patronictl.yaml\"},\n    })\nif err != nil {\n    return err\n}\n\nrt, err := environment.Open(ctx, patroniruntime.RuntimeOptions{\n    Context:       \"production\",\n    Operation:     config.OperationClusterRead,\n    ExplicitScope: \"postgres-ha\",\n})\nif err != nil {\n    return err\n}\ndefer rt.Close()\n\nresult := rt.Service.List(ctx, control.ListRequest{\n    Targets: []model.Target{rt.Target},\n})\nif result.Outcome != control.Succeeded {\n    return result.Error\n}\n```\n\nThe omitted imports in that fragment are:\n\n```go\nimport (\n    \"github.com/pgsty/go-patroni/config\"\n    \"github.com/pgsty/go-patroni/control\"\n    \"github.com/pgsty/go-patroni/model\"\n    patroniruntime \"github.com/pgsty/go-patroni/runtime\"\n)\n```\n\nThe high-level runtime currently implements Patroni's `etcd3` DCS backend. A\nconsumer using another DCS can implement the narrow interfaces in `dcs` and\nassemble `control.Service` directly.\n\n## Embed the command suite\n\nApplications that want the complete `patronictl` command surface can compose\nit through the public `cli` package. Product commands are registered as\nextensions; Patroni parsing, prompting, rendering, and exit behavior stay in\none SDK implementation:\n\n```go\nroot := cli.NewRootCommand(cli.Options{\n    Application: cli.Application{\n        Name: \"my-app\", Short: \"My Patroni control plane\", Version: buildVersion,\n        RequestIDPrefix: \"my-app-cli\",\n    },\n    Environment: patroniruntime.EnvironmentOptions{\n        Load: config.LoadRequest{Path: \"/infra/conf/patronictl.yml\"},\n        UserAgent: \"my-app/\" + buildVersion,\n    },\n    Extensions: []cli.Extension{newServeCommand},\n})\nif err := root.ExecuteContext(ctx); err != nil {\n    return err\n}\n```\n\nAn extension receives normalized root state through\n`ExtensionContext.Invocation`, so explicit `--config-file`, `--dcs-url`/`--dcs`,\n`--insecure`, `--context`, and `--output` values do not need to be reparsed.\nApplications such as Pig that already own a command framework can instead use\n`control` and `runtime` directly; importing `cli` is optional.\n\n## Configuration\n\nThe CLI accepts Patroni's standard `PATRONICTL_CONFIG_FILE`, `DCS_URL`, `-c`,\n`-d`/`--dcs-url`, and `-k` inputs. The optional `go_patroni` extension adds\nnamed contexts and network deadlines without changing Patroni's own fields:\n\n```yaml\nscope: postgres-ha\nnamespace: /service/\n\netcd3:\n  hosts: [10.10.10.10:2379, 10.10.10.11:2379]\n\nctl:\n  authentication:\n    username: patroni\n    password: secret\n\ngo_patroni:\n  default_context: production\n  contexts:\n    production: {}\n    staging:\n      scope: postgres-ha-staging\n      etcd3:\n        hosts: [10.20.20.10:2379]\n  network:\n    dns_timeout: 5s\n    dcs_dial_timeout: 5s\n    dcs_request_timeout: 10s\n    patroni_timeout: 10s\n    postgres_timeout: 30s\n    postgres_close_timeout: 5s\n```\n\nSelect a context with `--context` or `GO_PATRONI_CONTEXT`. The legacy `boar`\nextension and `BOAR_CONTEXT` are accepted for migration, but new consumers\nshould use the product-neutral names.\n\n## `patronictl` compatibility\n\nThe Go CLI implements all 19 commands in Patroni 4.1.4's `patronictl`:\n`dsn`, `query`, `remove`, `reload`, `restart`, `reinit`, `failover`,\n`switchover`, `list`, `topology`, `flush`, `pause`, `resume`, `edit-config`,\n`show-config`, `version`, `history`, `demote-cluster`, and `promote-cluster`.\n\nIt also adds `discover`, `inspect-config`, multi-cluster `--all`, and stable\nJSON/YAML envelopes through `-o`. Machine output uses the versioned\n`patroni.pgsty.com/v1alpha1` schema.\n\nThe source-pinned compatibility evidence is in [`compatibility`](compatibility),\nwith the detailed support matrix in\n[`docs/compatibility.md`](docs/compatibility.md). There are currently no\ndeclared CLI deviations from the pinned Patroni 4.1.4 command contract.\n\n## Package map\n\n| Package          | Purpose                                                                      |\n|------------------|------------------------------------------------------------------------------|\n| module root      | Complete Patroni REST API client, TLS, errors, endpoint and feature catalogs |\n| `config`         | Tolerant Patroni YAML loading, context overlays, secret-safe projection      |\n| `model`          | Stable Patroni cluster/member identities and domain objects                  |\n| `dcs`            | Capability-scoped Patroni DCS contracts and state decoding                   |\n| `dcs/etcd3`      | Native etcd3 implementation, transactions, discovery, and watches            |\n| `postgres`       | One-shot role-checked PostgreSQL query client                                |\n| `control`        | Adapter-neutral, `patronictl`-compatible control operations                  |\n| `runtime`        | Configuration-to-client assembly for applications and CLIs                   |\n| `cli`            | Public composition facade for the complete command suite and extensions      |\n| `cmd/patronictl` | Standalone native Go command-line client                                     |\n\n## Safety model\n\n- Every I/O operation takes a caller-owned `context.Context` and is bounded.\n- REST writes are never automatically retried.\n- Errors retain whether a write was not sent, may have been sent, or received a\n  response.\n- High-level writes separate preparation from execution, bind plans to the\n  service instance, use DCS compare-and-swap where applicable, and return\n  `UNKNOWN` rather than claiming a false failure after an ambiguous send.\n- Credentials are not accepted in endpoint URLs and are redacted from string\n  representations, configuration inspection, logs, and machine output.\n\n## Development\n\n```bash\ngo test -mod=readonly ./...\ngo vet ./...\ngo test -run '^$' -tags=integration ./test/integration\ngo run ./tools/machineschema -check\n```\n\nThe isolated live matrices are opt-in because they start real Patroni, etcd,\nand PostgreSQL instances. See `scripts/test-*-integration.sh`.\n\n## Releases\n\nStable releases follow Semantic Versioning and use `vMAJOR.MINOR.PATCH` tags.\nPushing such a tag runs the release workflow, which publishes `patronictl`\narchives for Linux and macOS on amd64 and arm64, plus SHA-256 checksums.\n\n## License\n\nApache License 2.0. See [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpgsty%2Fgo-patroni","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpgsty%2Fgo-patroni","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpgsty%2Fgo-patroni/lists"}