blob: 8bb1004eec761682f48a978d79f0df1bd90fa2be [file] [log] [blame]
khenaidooac637102019-01-14 15:44:34 -05001package api
2
3// QueryDatacenterOptions sets options about how we fail over if there are no
4// healthy nodes in the local datacenter.
5type QueryDatacenterOptions struct {
6 // NearestN is set to the number of remote datacenters to try, based on
7 // network coordinates.
8 NearestN int
9
10 // Datacenters is a fixed list of datacenters to try after NearestN. We
11 // never try a datacenter multiple times, so those are subtracted from
12 // this list before proceeding.
13 Datacenters []string
14}
15
16// QueryDNSOptions controls settings when query results are served over DNS.
17type QueryDNSOptions struct {
18 // TTL is the time to live for the served DNS results.
19 TTL string
20}
21
22// ServiceQuery is used to query for a set of healthy nodes offering a specific
23// service.
24type ServiceQuery struct {
25 // Service is the service to query.
26 Service string
27
28 // Near allows baking in the name of a node to automatically distance-
29 // sort from. The magic "_agent" value is supported, which sorts near
30 // the agent which initiated the request by default.
31 Near string
32
33 // Failover controls what we do if there are no healthy nodes in the
34 // local datacenter.
35 Failover QueryDatacenterOptions
36
37 // IgnoreCheckIDs is an optional list of health check IDs to ignore when
38 // considering which nodes are healthy. It is useful as an emergency measure
39 // to temporarily override some health check that is producing false negatives
40 // for example.
41 IgnoreCheckIDs []string
42
43 // If OnlyPassing is true then we will only include nodes with passing
44 // health checks (critical AND warning checks will cause a node to be
45 // discarded)
46 OnlyPassing bool
47
48 // Tags are a set of required and/or disallowed tags. If a tag is in
49 // this list it must be present. If the tag is preceded with "!" then
50 // it is disallowed.
51 Tags []string
52
53 // NodeMeta is a map of required node metadata fields. If a key/value
54 // pair is in this map it must be present on the node in order for the
55 // service entry to be returned.
56 NodeMeta map[string]string
57
58 // Connect if true will filter the prepared query results to only
59 // include Connect-capable services. These include both native services
60 // and proxies for matching services. Note that if a proxy matches,
61 // the constraints in the query above (Near, OnlyPassing, etc.) apply
62 // to the _proxy_ and not the service being proxied. In practice, proxies
63 // should be directly next to their services so this isn't an issue.
64 Connect bool
65}
66
67// QueryTemplate carries the arguments for creating a templated query.
68type QueryTemplate struct {
69 // Type specifies the type of the query template. Currently only
70 // "name_prefix_match" is supported. This field is required.
71 Type string
72
73 // Regexp allows specifying a regex pattern to match against the name
74 // of the query being executed.
75 Regexp string
76}
77
78// PreparedQueryDefinition defines a complete prepared query.
79type PreparedQueryDefinition struct {
80 // ID is this UUID-based ID for the query, always generated by Consul.
81 ID string
82
83 // Name is an optional friendly name for the query supplied by the
84 // user. NOTE - if this feature is used then it will reduce the security
85 // of any read ACL associated with this query/service since this name
86 // can be used to locate nodes with supplying any ACL.
87 Name string
88
89 // Session is an optional session to tie this query's lifetime to. If
90 // this is omitted then the query will not expire.
91 Session string
92
93 // Token is the ACL token used when the query was created, and it is
94 // used when a query is subsequently executed. This token, or a token
95 // with management privileges, must be used to change the query later.
96 Token string
97
98 // Service defines a service query (leaving things open for other types
99 // later).
100 Service ServiceQuery
101
102 // DNS has options that control how the results of this query are
103 // served over DNS.
104 DNS QueryDNSOptions
105
106 // Template is used to pass through the arguments for creating a
107 // prepared query with an attached template. If a template is given,
108 // interpolations are possible in other struct fields.
109 Template QueryTemplate
110}
111
112// PreparedQueryExecuteResponse has the results of executing a query.
113type PreparedQueryExecuteResponse struct {
114 // Service is the service that was queried.
115 Service string
116
117 // Nodes has the nodes that were output by the query.
118 Nodes []ServiceEntry
119
120 // DNS has the options for serving these results over DNS.
121 DNS QueryDNSOptions
122
123 // Datacenter is the datacenter that these results came from.
124 Datacenter string
125
126 // Failovers is a count of how many times we had to query a remote
127 // datacenter.
128 Failovers int
129}
130
131// PreparedQuery can be used to query the prepared query endpoints.
132type PreparedQuery struct {
133 c *Client
134}
135
136// PreparedQuery returns a handle to the prepared query endpoints.
137func (c *Client) PreparedQuery() *PreparedQuery {
138 return &PreparedQuery{c}
139}
140
141// Create makes a new prepared query. The ID of the new query is returned.
142func (c *PreparedQuery) Create(query *PreparedQueryDefinition, q *WriteOptions) (string, *WriteMeta, error) {
143 r := c.c.newRequest("POST", "/v1/query")
144 r.setWriteOptions(q)
145 r.obj = query
146 rtt, resp, err := requireOK(c.c.doRequest(r))
147 if err != nil {
148 return "", nil, err
149 }
150 defer resp.Body.Close()
151
152 wm := &WriteMeta{}
153 wm.RequestTime = rtt
154
155 var out struct{ ID string }
156 if err := decodeBody(resp, &out); err != nil {
157 return "", nil, err
158 }
159 return out.ID, wm, nil
160}
161
162// Update makes updates to an existing prepared query.
163func (c *PreparedQuery) Update(query *PreparedQueryDefinition, q *WriteOptions) (*WriteMeta, error) {
164 return c.c.write("/v1/query/"+query.ID, query, nil, q)
165}
166
167// List is used to fetch all the prepared queries (always requires a management
168// token).
169func (c *PreparedQuery) List(q *QueryOptions) ([]*PreparedQueryDefinition, *QueryMeta, error) {
170 var out []*PreparedQueryDefinition
171 qm, err := c.c.query("/v1/query", &out, q)
172 if err != nil {
173 return nil, nil, err
174 }
175 return out, qm, nil
176}
177
178// Get is used to fetch a specific prepared query.
179func (c *PreparedQuery) Get(queryID string, q *QueryOptions) ([]*PreparedQueryDefinition, *QueryMeta, error) {
180 var out []*PreparedQueryDefinition
181 qm, err := c.c.query("/v1/query/"+queryID, &out, q)
182 if err != nil {
183 return nil, nil, err
184 }
185 return out, qm, nil
186}
187
188// Delete is used to delete a specific prepared query.
189func (c *PreparedQuery) Delete(queryID string, q *WriteOptions) (*WriteMeta, error) {
190 r := c.c.newRequest("DELETE", "/v1/query/"+queryID)
191 r.setWriteOptions(q)
192 rtt, resp, err := requireOK(c.c.doRequest(r))
193 if err != nil {
194 return nil, err
195 }
196 defer resp.Body.Close()
197
198 wm := &WriteMeta{}
199 wm.RequestTime = rtt
200 return wm, nil
201}
202
203// Execute is used to execute a specific prepared query. You can execute using
204// a query ID or name.
205func (c *PreparedQuery) Execute(queryIDOrName string, q *QueryOptions) (*PreparedQueryExecuteResponse, *QueryMeta, error) {
206 var out *PreparedQueryExecuteResponse
207 qm, err := c.c.query("/v1/query/"+queryIDOrName+"/execute", &out, q)
208 if err != nil {
209 return nil, nil, err
210 }
211 return out, qm, nil
212}