diff --git a/agent/structs/structs.go b/agent/structs/structs.go
index a699c9e4a3..e1d9c0cdf4 100644
--- a/agent/structs/structs.go
+++ b/agent/structs/structs.go
@@ -906,7 +906,7 @@ type HealthCheckDefinition struct {
func (d *HealthCheckDefinition) MarshalJSON() ([]byte, error) {
type Alias HealthCheckDefinition
- return json.Marshal(&struct {
+ exported := &struct {
Interval string
Timeout string
DeregisterCriticalServiceAfter string
@@ -916,7 +916,18 @@ func (d *HealthCheckDefinition) MarshalJSON() ([]byte, error) {
Timeout: d.Timeout.String(),
DeregisterCriticalServiceAfter: d.DeregisterCriticalServiceAfter.String(),
Alias: (*Alias)(d),
- })
+ }
+ if d.Interval == 0 {
+ exported.Interval = ""
+ }
+ if d.Timeout == 0 {
+ exported.Timeout = ""
+ }
+ if d.DeregisterCriticalServiceAfter == 0 {
+ exported.DeregisterCriticalServiceAfter = ""
+ }
+
+ return json.Marshal(exported)
}
func (d *HealthCheckDefinition) UnmarshalJSON(data []byte) error {
diff --git a/agent/structs/txn.go b/agent/structs/txn.go
index 5d136ccf71..87d247bd02 100644
--- a/agent/structs/txn.go
+++ b/agent/structs/txn.go
@@ -112,10 +112,10 @@ type TxnErrors []*TxnError
// TxnResult is used to define the result of a given operation inside a
// transaction. Only one of the types should be filled out per entry.
type TxnResult struct {
- KV TxnKVResult
- Node TxnNodeResult
- Service TxnServiceResult
- Check TxnCheckResult
+ KV TxnKVResult `json:",omitempty"`
+ Node TxnNodeResult `json:",omitempty"`
+ Service TxnServiceResult `json:",omitempty"`
+ Check TxnCheckResult `json:",omitempty"`
}
// TxnResults is a list of TxnResult entries.
diff --git a/agent/txn_endpoint.go b/agent/txn_endpoint.go
index 33f361a435..d11958ebd8 100644
--- a/agent/txn_endpoint.go
+++ b/agent/txn_endpoint.go
@@ -195,17 +195,17 @@ func (s *HTTPServer) convertOps(resp http.ResponseWriter, req *http.Request) (st
Verb: in.Service.Verb,
Node: in.Service.Node,
Service: structs.NodeService{
- ID: svc.ServiceID,
- Service: svc.ServiceName,
- Tags: svc.ServiceTags,
- Address: svc.ServiceAddress,
- Meta: svc.ServiceMeta,
- Port: svc.ServicePort,
+ ID: svc.ID,
+ Service: svc.Service,
+ Tags: svc.Tags,
+ Address: svc.Address,
+ Meta: svc.Meta,
+ Port: svc.Port,
Weights: &structs.Weights{
- Passing: svc.ServiceWeights.Passing,
- Warning: svc.ServiceWeights.Warning,
+ Passing: svc.Weights.Passing,
+ Warning: svc.Weights.Warning,
},
- EnableTagOverride: svc.ServiceEnableTagOverride,
+ EnableTagOverride: svc.EnableTagOverride,
RaftIndex: structs.RaftIndex{
ModifyIndex: svc.ModifyIndex,
},
diff --git a/api/txn.go b/api/txn.go
index 02ae66252f..65d7a16ea0 100644
--- a/api/txn.go
+++ b/api/txn.go
@@ -125,7 +125,7 @@ const (
type ServiceTxnOp struct {
Verb ServiceOp
Node string
- Service CatalogService
+ Service AgentService
}
// CheckOp constants give possible operations available in a transaction.
diff --git a/api/txn_test.go b/api/txn_test.go
index 74a9cfdf9a..c164ebe92b 100644
--- a/api/txn_test.go
+++ b/api/txn_test.go
@@ -84,7 +84,7 @@ func TestAPI_ClientTxn(t *testing.T) {
Service: &ServiceTxnOp{
Verb: ServiceGet,
Node: "foo",
- Service: CatalogService{ServiceID: "foo1"},
+ Service: AgentService{ID: "foo1"},
},
},
&TxnOp{
diff --git a/website/source/api/txn.html.md b/website/source/api/txn.html.md
index 17bce978f5..23e28b0d20 100644
--- a/website/source/api/txn.html.md
+++ b/website/source/api/txn.html.md
@@ -3,19 +3,18 @@ layout: api
page_title: Transaction - HTTP API
sidebar_current: api-txn
description: |-
- The /txn endpoints manage updates or fetches of multiple keys inside a single,
- atomic transaction.
+ The /txn endpoint manages multiple operations in Consul, including catalog updates and fetches of multiple KV entries inside a single, atomic transaction.
---
# Transactions HTTP API
-The `/txn` endpoints manage updates or fetches of multiple keys inside a single,
-atomic transaction. It is important to note that each datacenter has its own KV
-store, and there is no built-in replication between datacenters.
+The `/txn` endpoint manages multiple operations in Consul, including catalog
+updates and fetches of multiple KV entries inside a single, atomic
+transaction.
## Create Transaction
-This endpoint permits submitting a list of operations to apply to the KV store
+This endpoint permits submitting a list of operations to apply to Consul
inside of a transaction. If any operation fails, the transaction is rolled back
and none of the changes are applied.
@@ -43,7 +42,7 @@ The table below shows this endpoint's support for
| Blocking Queries | Consistency Modes | Agent Caching | ACL Required |
| ---------------- | ----------------- | ------------- | ------------ |
-| `NO` | `all`1 | `none` | `key:read,key:write`2 |
+| `NO` | `all`1 | `none` | `key:read,key:write`
`node:read,node:write`
`service:read,service:write`2
1 For read-only transactions
@@ -55,7 +54,7 @@ The table below shows this endpoint's support for
to the datacenter of the agent being queried. This is specified as part of the
URL as a query parameter.
-- `KV` is the only available operation type, though other types may be added in the future.
+- `KV` operations have the following fields:
- `Verb` `(string: )` - Specifies the type of operation to perform.
Please see the table below for available verbs.
@@ -74,7 +73,32 @@ The table below shows this endpoint's support for
- `Session` `(string: "")` - Specifies a session. See the table below for more
information.
+
+- `Node` operations have the following fields:
+ - `Verb` `(string: )` - Specifies the type of operation to perform.
+
+ - `Node` `(Node: )` - Specifies the node information to use
+ for the operation. See the [catalog endpoint](/api/catalog.html#parameters) for the fields in this object. Note the only the node can be specified here, not any services or checks - separate service or check operations must be used for those.
+
+- `Service` operations have the following fields:
+
+ - `Verb` `(string: )` - Specifies the type of operation to perform.
+
+ - `Node` `(string: )` = Specifies the name of the node to use for
+ this service operation.
+
+ - `Service` `(Service: )` - Specifies the service instance information to use
+ for the operation. See the [catalog endpoint](/api/catalog.html#parameters) for the fields in this object.
+
+- `Check` operations have the following fields:
+
+ - `Verb` `(string: )` - Specifies the type of operation to perform.
+
+ - `Service` `(Service: )` - Specifies the check to use
+ for the operation. See the [catalog endpoint](/api/catalog.html#parameters) for the fields in this object.
+
+ Please see the table below for available verbs.
### Sample Payload
The body of the request should be a list of operations to perform inside the
@@ -91,6 +115,48 @@ atomic transaction. Up to 64 operations may be present in a single transaction.
"Index": ,
"Session": ""
}
+ },
+ {
+ "Node": {
+ "Verb": "set",
+ "Node": {
+ "ID": "67539c9d-b948-ba67-edd4-d07a676d6673",
+ "Node": "bar",
+ "Address": "192.168.0.1",
+ "Datacenter": "dc1",
+ "Meta": {
+ "instance_type": "m2.large"
+ }
+ }
+ }
+ },
+ {
+ "Service": {
+ "Verb": "delete",
+ "Node": "foo",
+ "Service": {
+ "ID": "db1"
+ }
+ }
+ },
+ {
+ "Check": {
+ "Verb": "cas",
+ "Check": {
+ "Node": "bar",
+ "CheckID": "service:web1",
+ "Name": "Web HTTP Check",
+ "Status": "critical",
+ "ServiceID": "web1",
+ "ServiceName": "web",
+ "ServiceTags": null,
+ "Definition": {
+ "HTTP": "http://localhost:8080",
+ "Interval": "10s"
+ },
+ "ModifyIndex": 22
+ }
+ }
}
]
```
@@ -123,6 +189,39 @@ look like this:
"CreateIndex": ,
"ModifyIndex":
}
+ },
+ {
+ "Node": {
+ "ID": "67539c9d-b948-ba67-edd4-d07a676d6673",
+ "Node": "bar",
+ "Address": "192.168.0.1",
+ "Datacenter": "dc1",
+ "TaggedAddresses": null,
+ "Meta": {
+ "instance_type": "m2.large"
+ },
+ "CreateIndex": 32,
+ "ModifyIndex": 32
+ }
+ },
+ {
+ "Check": {
+ "Node": "bar",
+ "CheckID": "service:web1",
+ "Name": "Web HTTP Check",
+ "Status": "critical",
+ "Notes": "",
+ "Output": "",
+ "ServiceID": "web1",
+ "ServiceName": "web",
+ "ServiceTags": null,
+ "Definition": {
+ "HTTP": "http://localhost:8080",
+ "Interval": "10s"
+ },
+ "CreateIndex": 22,
+ "ModifyIndex": 35
+ }
}
],
"Errors": [
@@ -130,12 +229,13 @@ look like this:
"OpIndex": ,
"What": ""
},
+ ...
]
}
```
- `Results` has entries for some operations if the transaction was successful.
- To save space, the `Value` will be `null` for any `Verb` other than "get" or
+ To save space, the `Value` for KV results will be `null` for any `Verb` other than "get" or
"get-tree". Like the `/v1/kv/` endpoint, `Value` will be Base64-encoded
if it is present. Also, no result entries will be added for verbs that delete
keys.
@@ -145,10 +245,12 @@ look like this:
transaction, and `What` is a string with an error message about why that
operation failed.
-### Table of Operations
+### Tables of Operations
-The following table summarizes the available verbs and the fields that apply to
-that operation ("X" means a field is required and "O" means it is optional):
+#### KV Operations
+
+The following tables summarize the available verbs and the fields that apply to
+those operations ("X" means a field is required and "O" means it is optional):
| Verb | Operation | Key | Value | Flags | Index | Session |
| ------------------ | -------------------------------------------- | :--: | :---: | :---: | :---: | :-----: |
@@ -164,3 +266,42 @@ that operation ("X" means a field is required and "O" means it is optional):
| `delete` | Delete the key | `x` | | | | |
| `delete-tree` | Delete all keys with a prefix | `x` | | | | |
| `delete-cas` | Delete, but with CAS semantics | `x` | | | `x` | |
+
+#### Node Operations
+
+Node operations act on an individual node and require either a Node ID or name, giving precedence
+to the ID if both are set. Delete operations will not return a result on success.
+
+| Verb | Operation |
+| ------------------ | -------------------------------------------- |
+| `set` | Sets the node to the given state |
+| `cas` | Sets, but with CAS semantics using the given ModifyIndex |
+| `get` | Get the node, fails if it does not exist |
+| `delete` | Delete the node |
+| `delete-cas` | Delete, but with CAS semantics |
+
+#### Service Operations
+
+Service operations act on an individual service instance on the given node name. Both a node name
+and valid service name are required. Delete operations will not return a result on success.
+
+| Verb | Operation |
+| ------------------ | -------------------------------------------- |
+| `set` | Sets the service to the given state |
+| `cas` | Sets, but with CAS semantics using the given ModifyIndex |
+| `get` | Get the service, fails if it does not exist |
+| `delete` | Delete the service |
+| `delete-cas` | Delete, but with CAS semantics |
+
+#### Check Operations
+
+Check operations act on an individual health check instance on the given node name. Both a node name
+and valid check ID are required. Delete operations will not return a result on success.
+
+| Verb | Operation |
+| ------------------ | -------------------------------------------- |
+| `set` | Sets the health check to the given state |
+| `cas` | Sets, but with CAS semantics using the given ModifyIndex |
+| `get` | Get the check, fails if it does not exist |
+| `delete` | Delete the check |
+| `delete-cas` | Delete, but with CAS semantics |
\ No newline at end of file