Documentation
¶
Overview ¶
Package client provides bindings for the etcd APIs.
Create a Config and exchange it for a Client:
import (
"net/http"
"context"
"github.com/coreos/etcd/client"
)
cfg := client.Config{
Endpoints: []string{"http://127.0.0.1:2379"},
Transport: DefaultTransport,
}
c, err := client.New(cfg)
if err != nil {
// handle error
}
Clients are safe for concurrent use by multiple goroutines.
Create a KeysAPI using the Client, then use it to interact with etcd:
kAPI := client.NewKeysAPI(c)
// create a new key /foo with the value "bar"
_, err = kAPI.Create(context.Background(), "/foo", "bar")
if err != nil {
// handle error
}
// delete the newly created key only if the value is still "bar"
_, err = kAPI.Delete(context.Background(), "/foo", &DeleteOptions{PrevValue: "bar"})
if err != nil {
// handle error
}
Use a custom context to set timeouts on your operations:
import "time"
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
// set a new key, ignoring its previous state
_, err := kAPI.Set(ctx, "/ping", "pong", nil)
if err != nil {
if err == context.DeadlineExceeded {
// request took longer than 5s
} else {
// handle error
}
}
Index ¶
- Constants
- Variables
- func DisablecURLDebug()
- func EnablecURLDebug()
- func IsKeyNotFound(err error) bool
- func IsRoleNotFound(err error) bool
- func IsUserNotFound(err error) bool
- type AuthAPI
- type AuthRoleAPI
- type AuthUserAPI
- type CancelableTransport
- type CheckRedirectFunc
- type Client
- type ClusterError
- type Config
- type CreateInOrderOptions
- type DeleteOptions
- type Discoverer
- type EndpointSelectionMode
- type Error
- type GetOptions
- type KeysAPI
- type Member
- type MembersAPI
- type Node
- type Nodes
- type PermissionType
- type Permissions
- type PrevExistType
- type Response
- type Role
- type SetOptions
- type User
- type UserRoles
- type Watcher
- type WatcherOptions
Examples ¶
Constants ¶
const ( ErrorCodeKeyNotFound = 100 ErrorCodeTestFailed = 101 ErrorCodeNotFile = 102 ErrorCodeNotDir = 104 ErrorCodeNodeExist = 105 ErrorCodeRootROnly = 107 ErrorCodeDirNotEmpty = 108 ErrorCodePrevValueRequired = 201 ErrorCodeTTLNaN = 202 ErrorCodeIndexNaN = 203 ErrorCodeInvalidField = 209 ErrorCodeInvalidForm = 210 ErrorCodeRaftInternal = 300 ErrorCodeLeaderElect = 301 ErrorCodeWatcherCleared = 400 ErrorCodeEventIndexCleared = 401 )
const ( PrevIgnore = PrevExistType("") PrevExist = PrevExistType("true") PrevNoExist = PrevExistType("false") )
Variables ¶
var ( ErrNoEndpoints = errors.New("client: no endpoints available") ErrTooManyRedirects = errors.New("client: too many redirects") ErrNoLeaderEndpoint = errors.New("client: no leader endpoint available") )
var ( ErrInvalidJSON = errors.New("client: response is invalid json. The endpoint is probably not valid etcd cluster endpoint.") ErrEmptyBody = errors.New("client: response body is empty") )
var DefaultRequestTimeout = 5 * time.Second
Functions ¶
func DisablecURLDebug ¶
func DisablecURLDebug()
func EnablecURLDebug ¶
func EnablecURLDebug()
func IsKeyNotFound ¶
IsKeyNotFound returns true if the error code is ErrorCodeKeyNotFound.
func IsRoleNotFound ¶
IsRoleNotFound returns true if the error means role not found of v2 API.
func IsUserNotFound ¶
IsUserNotFound returns true if the error means user not found of v2 API.
Types ¶
type AuthAPI ¶
type AuthAPI interface {
// Enable auth.
Enable(ctx context.Context) error
// Disable auth.
Disable(ctx context.Context) error
}
func NewAuthAPI ¶
NewAuthAPI constructs a new AuthAPI that uses HTTP to interact with etcd's general auth features.
type AuthRoleAPI ¶
type AuthRoleAPI interface {
// AddRole adds a role.
AddRole(ctx context.Context, role string) error
// RemoveRole removes a role.
RemoveRole(ctx context.Context, role string) error
// GetRole retrieves role details.
GetRole(ctx context.Context, role string) (*Role, error)
// GrantRoleKV grants a role some permission prefixes for the KV store.
GrantRoleKV(ctx context.Context, role string, prefixes []string, permType PermissionType) (*Role, error)
// RevokeRoleKV revokes some permission prefixes for a role on the KV store.
RevokeRoleKV(ctx context.Context, role string, prefixes []string, permType PermissionType) (*Role, error)
// ListRoles lists roles.
ListRoles(ctx context.Context) ([]string, error)
}
func NewAuthRoleAPI ¶
func NewAuthRoleAPI(c Client) AuthRoleAPI
NewAuthRoleAPI constructs a new AuthRoleAPI that uses HTTP to interact with etcd's role creation and modification features.
type AuthUserAPI ¶
type AuthUserAPI interface {
// AddUser adds a user.
AddUser(ctx context.Context, username string, password string) error
// RemoveUser removes a user.
RemoveUser(ctx context.Context, username string) error
// GetUser retrieves user details.
GetUser(ctx context.Context, username string) (*User, error)
// GrantUser grants a user some permission roles.
GrantUser(ctx context.Context, username string, roles []string) (*User, error)
// RevokeUser revokes some permission roles from a user.
RevokeUser(ctx context.Context, username string, roles []string) (*User, error)
// ChangePassword changes the user's password.
ChangePassword(ctx context.Context, username string, password string) (*User, error)
// ListUsers lists the users.
ListUsers(ctx context.Context) ([]string, error)
}
func NewAuthUserAPI ¶
func NewAuthUserAPI(c Client) AuthUserAPI
NewAuthUserAPI constructs a new AuthUserAPI that uses HTTP to interact with etcd's user creation and modification features.
type CancelableTransport ¶
type CancelableTransport interface {
http.RoundTripper
CancelRequest(req *http.Request)
}
CancelableTransport mimics net/http.Transport, but requires that the object also support request cancellation.
type CheckRedirectFunc ¶
var DefaultCheckRedirect CheckRedirectFunc = func(via int) error { if via > 10 { return ErrTooManyRedirects } return nil }
DefaultCheckRedirect follows up to 10 redirects, but no more.
type Client ¶
type Client interface {
// Sync updates the internal cache of the etcd cluster's membership.
Sync(context.Context) error
// AutoSync periodically calls Sync() every given interval.
// The recommended sync interval is 10 seconds to 1 minute, which does
// not bring too much overhead to server and makes client catch up the
// cluster change in time.
//
// The example to use it:
//
// for {
// err := client.AutoSync(ctx, 10*time.Second)
// if err == context.DeadlineExceeded || err == context.Canceled {
// break
// }
// log.Print(err)
// }
AutoSync(context.Context, time.Duration) error
// Endpoints returns a copy of the current set of API endpoints used
// by Client to resolve HTTP requests. If Sync has ever been called,
// this may differ from the initial Endpoints provided in the Config.
Endpoints() []string
// SetEndpoints sets the set of API endpoints used by Client to resolve
// HTTP requests. If the given endpoints are not valid, an error will be
// returned
SetEndpoints(eps []string) error
// GetVersion retrieves the current etcd server and cluster version
GetVersion(ctx context.Context) (*version.Versions, error)
// contains filtered or unexported methods
}
type ClusterError ¶
type ClusterError struct {
Errors []error
}
func (*ClusterError) Detail ¶
func (ce *ClusterError) Detail() string
func (*ClusterError) Error ¶
func (ce *ClusterError) Error() string
type Config ¶
type Config struct {
// Endpoints defines a set of URLs (schemes, hosts and ports only)
// that can be used to communicate with a logical etcd cluster. For
// example, a three-node cluster could be provided like so:
//
// Endpoints: []string{
// "http://node1.example.com:2379",
// "http://node2.example.com:2379",
// "http://node3.example.com:2379",
// }
//
// If multiple endpoints are provided, the Client will attempt to
// use them all in the event that one or more of them are unusable.
//
// If Client.Sync is ever called, the Client may cache an alternate
// set of endpoints to continue operation.
Endpoints []string
// Transport is used by the Client to drive HTTP requests. If not
// provided, DefaultTransport will be used.
Transport CancelableTransport
// CheckRedirect specifies the policy for handling HTTP redirects.
// If CheckRedirect is not nil, the Client calls it before
// following an HTTP redirect. The sole argument is the number of
// requests that have already been made. If CheckRedirect returns
// an error, Client.Do will not make any further requests and return
// the error back it to the caller.
//
// If CheckRedirect is nil, the Client uses its default policy,
// which is to stop after 10 consecutive requests.
CheckRedirect CheckRedirectFunc
// Username specifies the user credential to add as an authorization header
Username string
// Password is the password for the specified user to add as an authorization header
// to the request.
Password string
// HeaderTimeoutPerRequest specifies the time limit to wait for response
// header in a single request made by the Client. The timeout includes
// connection time, any redirects, and header wait time.
//
// For non-watch GET request, server returns the response body immediately.
// For PUT/POST/DELETE request, server will attempt to commit request
// before responding, which is expected to take `100ms + 2 * RTT`.
// For watch request, server returns the header immediately to notify Client
// watch start. But if server is behind some kind of proxy, the response
// header may be cached at proxy, and Client cannot rely on this behavior.
//
// Especially, wait request will ignore this timeout.
//
// One API call may send multiple requests to different etcd servers until it
// succeeds. Use context of the API to specify the overall timeout.
//
// A HeaderTimeoutPerRequest of zero means no timeout.
HeaderTimeoutPerRequest time.Duration
// SelectionMode is an EndpointSelectionMode enum that specifies the
// policy for choosing the etcd cluster node to which requests are sent.
SelectionMode EndpointSelectionMode
}
type CreateInOrderOptions ¶
type CreateInOrderOptions struct {
// TTL defines a period of time after-which the Node should
// expire and no longer exist. Values <= 0 are ignored. Given
// that the zero-value is ignored, TTL cannot be used to set
// a TTL of 0.
TTL time.Duration
}
func (*CreateInOrderOptions) CodecDecodeSelf ¶
func (x *CreateInOrderOptions) CodecDecodeSelf(d *codec1978.Decoder)
func (*CreateInOrderOptions) CodecEncodeSelf ¶
func (x *CreateInOrderOptions) CodecEncodeSelf(e *codec1978.Encoder)
type DeleteOptions ¶
type DeleteOptions struct {
// PrevValue specifies what the current value of the Node must
// be in order for the Delete operation to succeed.
//
// Leaving this field empty means that the caller wishes to
// ignore the current value of the Node. This cannot be used
// to compare the Node's current value to an empty string.
PrevValue string
// PrevIndex indicates what the current ModifiedIndex of the
// Node must be in order for the Delete operation to succeed.
//
// If PrevIndex is set to 0 (default), no comparison is made.
PrevIndex uint64
// Recursive defines whether or not all children of the Node
// should be deleted. If set to true, all children of the Node
// identified by the given key will be deleted. If left unset
// or explicitly set to false, only a single Node will be
// deleted.
Recursive bool
// Dir specifies whether or not this Node should be removed as a directory.
Dir bool
}
func (*DeleteOptions) CodecDecodeSelf ¶
func (x *DeleteOptions) CodecDecodeSelf(d *codec1978.Decoder)
func (*DeleteOptions) CodecEncodeSelf ¶
func (x *DeleteOptions) CodecEncodeSelf(e *codec1978.Encoder)
type Discoverer ¶
type Discoverer interface {
// Discover looks up the etcd servers for the domain.
Discover(domain string) ([]string, error)
}
Discoverer is an interface that wraps the Discover method.
func NewSRVDiscover ¶
func NewSRVDiscover() Discoverer
NewSRVDiscover constructs a new Discoverer that uses the stdlib to lookup SRV records.
type EndpointSelectionMode ¶
type EndpointSelectionMode int
const ( // EndpointSelectionRandom is the default value of the 'SelectionMode'. // As the name implies, the client object will pick a node from the members // of the cluster in a random fashion. If the cluster has three members, A, B, // and C, the client picks any node from its three members as its request // destination. EndpointSelectionRandom EndpointSelectionMode = iota // If 'SelectionMode' is set to 'EndpointSelectionPrioritizeLeader', // requests are sent directly to the cluster leader. This reduces // forwarding roundtrips compared to making requests to etcd followers // who then forward them to the cluster leader. In the event of a leader // failure, however, clients configured this way cannot prioritize among // the remaining etcd followers. Therefore, when a client sets 'SelectionMode' // to 'EndpointSelectionPrioritizeLeader', it must use 'client.AutoSync()' to // maintain its knowledge of current cluster state. // // This mode should be used with Client.AutoSync(). EndpointSelectionPrioritizeLeader )
type Error ¶
type Error struct {
Code int `json:"errorCode"`
Message string `json:"message"`
Cause string `json:"cause"`
Index uint64 `json:"index"`
}
func (*Error) CodecDecodeSelf ¶
func (*Error) CodecEncodeSelf ¶
type GetOptions ¶
type GetOptions struct {
// Recursive defines whether or not all children of the Node
// should be returned.
Recursive bool
// Sort instructs the server whether or not to sort the Nodes.
// If true, the Nodes are sorted alphabetically by key in
// ascending order (A to z). If false (default), the Nodes will
// not be sorted and the ordering used should not be considered
// predictable.
Sort bool
// Quorum specifies whether it gets the latest committed value that
// has been applied in quorum of members, which ensures external
// consistency (or linearizability).
Quorum bool
}
func (*GetOptions) CodecDecodeSelf ¶
func (x *GetOptions) CodecDecodeSelf(d *codec1978.Decoder)
func (*GetOptions) CodecEncodeSelf ¶
func (x *GetOptions) CodecEncodeSelf(e *codec1978.Encoder)
type KeysAPI ¶
type KeysAPI interface {
// Get retrieves a set of Nodes from etcd
Get(ctx context.Context, key string, opts *GetOptions) (*Response, error)
// Set assigns a new value to a Node identified by a given key. The caller
// may define a set of conditions in the SetOptions. If SetOptions.Dir=true
// then value is ignored.
Set(ctx context.Context, key, value string, opts *SetOptions) (*Response, error)
// Delete removes a Node identified by the given key, optionally destroying
// all of its children as well. The caller may define a set of required
// conditions in an DeleteOptions object.
Delete(ctx context.Context, key string, opts *DeleteOptions) (*Response, error)
// Create is an alias for Set w/ PrevExist=false
Create(ctx context.Context, key, value string) (*Response, error)
// CreateInOrder is used to atomically create in-order keys within the given directory.
CreateInOrder(ctx context.Context, dir, value string, opts *CreateInOrderOptions) (*Response, error)
// Update is an alias for Set w/ PrevExist=true
Update(ctx context.Context, key, value string) (*Response, error)
// Watcher builds a new Watcher targeted at a specific Node identified
// by the given key. The Watcher may be configured at creation time
// through a WatcherOptions object. The returned Watcher is designed
// to emit events that happen to a Node, and optionally to its children.
Watcher(key string, opts *WatcherOptions) Watcher
}
Example (Directory) ¶
c, err := client.New(client.Config{
Endpoints: exampleEndpoints,
Transport: exampleTransport,
})
if err != nil {
log.Fatal(err)
}
kapi := client.NewKeysAPI(c)
// Setting '/myNodes' to create a directory that will hold some keys.
o := client.SetOptions{Dir: true}
resp, err := kapi.Set(context.Background(), "/myNodes", "", &o)
if err != nil {
log.Fatal(err)
}
// Add keys to /myNodes directory.
resp, err = kapi.Set(context.Background(), "/myNodes/key1", "value1", nil)
if err != nil {
log.Fatal(err)
}
resp, err = kapi.Set(context.Background(), "/myNodes/key2", "value2", nil)
if err != nil {
log.Fatal(err)
}
// fetch directory
resp, err = kapi.Get(context.Background(), "/myNodes", nil)
if err != nil {
log.Fatal(err)
}
// print directory keys
sort.Sort(resp.Node.Nodes)
for _, n := range resp.Node.Nodes {
fmt.Printf("Key: %q, Value: %q\n", n.Key, n.Value)
}
Output: Key: "/myNodes/key1", Value: "value1" Key: "/myNodes/key2", Value: "value2"
Example (Setget) ¶
c, err := client.New(client.Config{
Endpoints: exampleEndpoints,
Transport: exampleTransport,
})
if err != nil {
log.Fatal(err)
}
kapi := client.NewKeysAPI(c)
// Set key "/foo" to value "bar".
resp, err := kapi.Set(context.Background(), "/foo", "bar", nil)
if err != nil {
log.Fatal(err)
}
// Get key "/foo"
resp, err = kapi.Get(context.Background(), "/foo", nil)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%q key has %q value\n", resp.Node.Key, resp.Node.Value)
Output: "/foo" key has "bar" value
func NewKeysAPI ¶
NewKeysAPI builds a KeysAPI that interacts with etcd's key-value API over HTTP.
func NewKeysAPIWithPrefix ¶
NewKeysAPIWithPrefix acts like NewKeysAPI, but allows the caller to provide a custom base URL path. This should only be used in very rare cases.
type Member ¶
type Member struct {
// ID is the unique identifier of this Member.
ID string `json:"id"`
// Name is a human-readable, non-unique identifier of this Member.
Name string `json:"name"`
// PeerURLs represents the HTTP(S) endpoints this Member uses to
// participate in etcd's consensus protocol.
PeerURLs []string `json:"peerURLs"`
// ClientURLs represents the HTTP(S) endpoints on which this Member
// serves its client-facing APIs.
ClientURLs []string `json:"clientURLs"`
}
type MembersAPI ¶
type MembersAPI interface {
// List enumerates the current cluster membership.
List(ctx context.Context) ([]Member, error)
// Add instructs etcd to accept a new Member into the cluster.
Add(ctx context.Context, peerURL string) (*Member, error)
// Remove demotes an existing Member out of the cluster.
Remove(ctx context.Context, mID string) error
// Update instructs etcd to update an existing Member in the cluster.
Update(ctx context.Context, mID string, peerURLs []string) error
// Leader gets current leader of the cluster
Leader(ctx context.Context) (*Member, error)
}
func NewMembersAPI ¶
func NewMembersAPI(c Client) MembersAPI
NewMembersAPI constructs a new MembersAPI that uses HTTP to interact with etcd's membership API.
type Node ¶
type Node struct {
// Key represents the unique location of this Node (e.g. "/foo/bar").
Key string `json:"key"`
// Dir reports whether node describes a directory.
Dir bool `json:"dir,omitempty"`
// Value is the current data stored on this Node. If this Node
// is a directory, Value will be empty.
Value string `json:"value"`
// Nodes holds the children of this Node, only if this Node is a directory.
// This slice of will be arbitrarily deep (children, grandchildren, great-
// grandchildren, etc.) if a recursive Get or Watch request were made.
Nodes Nodes `json:"nodes"`
// CreatedIndex is the etcd index at-which this Node was created.
CreatedIndex uint64 `json:"createdIndex"`
// ModifiedIndex is the etcd index at-which this Node was last modified.
ModifiedIndex uint64 `json:"modifiedIndex"`
// Expiration is the server side expiration time of the key.
Expiration *time.Time `json:"expiration,omitempty"`
// TTL is the time to live of the key in second.
TTL int64 `json:"ttl,omitempty"`
}
func (*Node) CodecDecodeSelf ¶
func (*Node) CodecEncodeSelf ¶
func (*Node) TTLDuration ¶
TTLDuration returns the Node's TTL as a time.Duration object
type PermissionType ¶
type PermissionType int
const ( ReadPermission PermissionType = iota WritePermission ReadWritePermission )
type Permissions ¶
type Permissions struct {
KV rwPermission `json:"kv"`
}
type PrevExistType ¶
type PrevExistType string
PrevExistType is used to define an existence condition when setting or deleting Nodes.
func (*PrevExistType) CodecDecodeSelf ¶
func (x *PrevExistType) CodecDecodeSelf(d *codec1978.Decoder)
func (PrevExistType) CodecEncodeSelf ¶
func (x PrevExistType) CodecEncodeSelf(e *codec1978.Encoder)
type Response ¶
type Response struct {
// Action is the name of the operation that occurred. Possible values
// include get, set, delete, update, create, compareAndSwap,
// compareAndDelete and expire.
Action string `json:"action"`
// Node represents the state of the relevant etcd Node.
Node *Node `json:"node"`
// PrevNode represents the previous state of the Node. PrevNode is non-nil
// only if the Node existed before the action occurred and the action
// caused a change to the Node.
PrevNode *Node `json:"prevNode"`
// Index holds the cluster-level index at the time the Response was generated.
// This index is not tied to the Node(s) contained in this Response.
Index uint64 `json:"-"`
// ClusterID holds the cluster-level ID reported by the server. This
// should be different for different etcd clusters.
ClusterID string `json:"-"`
}
func (*Response) CodecDecodeSelf ¶
func (*Response) CodecEncodeSelf ¶
type Role ¶
type Role struct {
Role string `json:"role"`
Permissions Permissions `json:"permissions"`
Grant *Permissions `json:"grant,omitempty"`
Revoke *Permissions `json:"revoke,omitempty"`
}
type SetOptions ¶
type SetOptions struct {
// PrevValue specifies what the current value of the Node must
// be in order for the Set operation to succeed.
//
// Leaving this field empty means that the caller wishes to
// ignore the current value of the Node. This cannot be used
// to compare the Node's current value to an empty string.
//
// PrevValue is ignored if Dir=true
PrevValue string
// PrevIndex indicates what the current ModifiedIndex of the
// Node must be in order for the Set operation to succeed.
//
// If PrevIndex is set to 0 (default), no comparison is made.
PrevIndex uint64
// PrevExist specifies whether the Node must currently exist
// (PrevExist) or not (PrevNoExist). If the caller does not
// care about existence, set PrevExist to PrevIgnore, or simply
// leave it unset.
PrevExist PrevExistType
// TTL defines a period of time after-which the Node should
// expire and no longer exist. Values <= 0 are ignored. Given
// that the zero-value is ignored, TTL cannot be used to set
// a TTL of 0.
TTL time.Duration
// Refresh set to true means a TTL value can be updated
// without firing a watch or changing the node value. A
// value must not be provided when refreshing a key.
Refresh bool
// Dir specifies whether or not this Node should be created as a directory.
Dir bool
// NoValueOnSuccess specifies whether the response contains the current value of the Node.
// If set, the response will only contain the current value when the request fails.
NoValueOnSuccess bool
}
func (*SetOptions) CodecDecodeSelf ¶
func (x *SetOptions) CodecDecodeSelf(d *codec1978.Decoder)
func (*SetOptions) CodecEncodeSelf ¶
func (x *SetOptions) CodecEncodeSelf(e *codec1978.Encoder)
type Watcher ¶
type Watcher interface {
// Next blocks until an etcd event occurs, then returns a Response
// representing that event. The behavior of Next depends on the
// WatcherOptions used to construct the Watcher. Next is designed to
// be called repeatedly, each time blocking until a subsequent event
// is available.
//
// If the provided context is cancelled, Next will return a non-nil
// error. Any other failures encountered while waiting for the next
// event (connection issues, deserialization failures, etc) will
// also result in a non-nil error.
Next(context.Context) (*Response, error)
}
type WatcherOptions ¶
type WatcherOptions struct {
// AfterIndex defines the index after-which the Watcher should
// start emitting events. For example, if a value of 5 is
// provided, the first event will have an index >= 6.
//
// Setting AfterIndex to 0 (default) means that the Watcher
// should start watching for events starting at the current
// index, whatever that may be.
AfterIndex uint64
// Recursive specifies whether or not the Watcher should emit
// events that occur in children of the given keyspace. If set
// to false (default), events will be limited to those that
// occur for the exact key.
Recursive bool
}
func (*WatcherOptions) CodecDecodeSelf ¶
func (x *WatcherOptions) CodecDecodeSelf(d *codec1978.Decoder)
func (*WatcherOptions) CodecEncodeSelf ¶
func (x *WatcherOptions) CodecEncodeSelf(e *codec1978.Encoder)
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package integration implements tests built upon embedded etcd, focusing on the correctness of the etcd v2 client.
|
Package integration implements tests built upon embedded etcd, focusing on the correctness of the etcd v2 client. |
