Holger Hildebrandt | fa07499 | 2020-03-27 15:42:06 +0000 | [diff] [blame] | 1 | package api |
| 2 | |
| 3 | // QueryDatacenterOptions sets options about how we fail over if there are no |
| 4 | // healthy nodes in the local datacenter. |
| 5 | type 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. |
| 17 | type 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. |
| 24 | type 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 | // ServiceMeta is a map of required service metadata fields. If a key/value |
| 59 | // pair is in this map it must be present on the node in order for the |
| 60 | // service entry to be returned. |
| 61 | ServiceMeta map[string]string |
| 62 | |
| 63 | // Connect if true will filter the prepared query results to only |
| 64 | // include Connect-capable services. These include both native services |
| 65 | // and proxies for matching services. Note that if a proxy matches, |
| 66 | // the constraints in the query above (Near, OnlyPassing, etc.) apply |
| 67 | // to the _proxy_ and not the service being proxied. In practice, proxies |
| 68 | // should be directly next to their services so this isn't an issue. |
| 69 | Connect bool |
| 70 | } |
| 71 | |
| 72 | // QueryTemplate carries the arguments for creating a templated query. |
| 73 | type QueryTemplate struct { |
| 74 | // Type specifies the type of the query template. Currently only |
| 75 | // "name_prefix_match" is supported. This field is required. |
| 76 | Type string |
| 77 | |
| 78 | // Regexp allows specifying a regex pattern to match against the name |
| 79 | // of the query being executed. |
| 80 | Regexp string |
| 81 | } |
| 82 | |
| 83 | // PreparedQueryDefinition defines a complete prepared query. |
| 84 | type PreparedQueryDefinition struct { |
| 85 | // ID is this UUID-based ID for the query, always generated by Consul. |
| 86 | ID string |
| 87 | |
| 88 | // Name is an optional friendly name for the query supplied by the |
| 89 | // user. NOTE - if this feature is used then it will reduce the security |
| 90 | // of any read ACL associated with this query/service since this name |
| 91 | // can be used to locate nodes with supplying any ACL. |
| 92 | Name string |
| 93 | |
| 94 | // Session is an optional session to tie this query's lifetime to. If |
| 95 | // this is omitted then the query will not expire. |
| 96 | Session string |
| 97 | |
| 98 | // Token is the ACL token used when the query was created, and it is |
| 99 | // used when a query is subsequently executed. This token, or a token |
| 100 | // with management privileges, must be used to change the query later. |
| 101 | Token string |
| 102 | |
| 103 | // Service defines a service query (leaving things open for other types |
| 104 | // later). |
| 105 | Service ServiceQuery |
| 106 | |
| 107 | // DNS has options that control how the results of this query are |
| 108 | // served over DNS. |
| 109 | DNS QueryDNSOptions |
| 110 | |
| 111 | // Template is used to pass through the arguments for creating a |
| 112 | // prepared query with an attached template. If a template is given, |
| 113 | // interpolations are possible in other struct fields. |
| 114 | Template QueryTemplate |
| 115 | } |
| 116 | |
| 117 | // PreparedQueryExecuteResponse has the results of executing a query. |
| 118 | type PreparedQueryExecuteResponse struct { |
| 119 | // Service is the service that was queried. |
| 120 | Service string |
| 121 | |
| 122 | // Nodes has the nodes that were output by the query. |
| 123 | Nodes []ServiceEntry |
| 124 | |
| 125 | // DNS has the options for serving these results over DNS. |
| 126 | DNS QueryDNSOptions |
| 127 | |
| 128 | // Datacenter is the datacenter that these results came from. |
| 129 | Datacenter string |
| 130 | |
| 131 | // Failovers is a count of how many times we had to query a remote |
| 132 | // datacenter. |
| 133 | Failovers int |
| 134 | } |
| 135 | |
| 136 | // PreparedQuery can be used to query the prepared query endpoints. |
| 137 | type PreparedQuery struct { |
| 138 | c *Client |
| 139 | } |
| 140 | |
| 141 | // PreparedQuery returns a handle to the prepared query endpoints. |
| 142 | func (c *Client) PreparedQuery() *PreparedQuery { |
| 143 | return &PreparedQuery{c} |
| 144 | } |
| 145 | |
| 146 | // Create makes a new prepared query. The ID of the new query is returned. |
| 147 | func (c *PreparedQuery) Create(query *PreparedQueryDefinition, q *WriteOptions) (string, *WriteMeta, error) { |
| 148 | r := c.c.newRequest("POST", "/v1/query") |
| 149 | r.setWriteOptions(q) |
| 150 | r.obj = query |
| 151 | rtt, resp, err := requireOK(c.c.doRequest(r)) |
| 152 | if err != nil { |
| 153 | return "", nil, err |
| 154 | } |
| 155 | defer resp.Body.Close() |
| 156 | |
| 157 | wm := &WriteMeta{} |
| 158 | wm.RequestTime = rtt |
| 159 | |
| 160 | var out struct{ ID string } |
| 161 | if err := decodeBody(resp, &out); err != nil { |
| 162 | return "", nil, err |
| 163 | } |
| 164 | return out.ID, wm, nil |
| 165 | } |
| 166 | |
| 167 | // Update makes updates to an existing prepared query. |
| 168 | func (c *PreparedQuery) Update(query *PreparedQueryDefinition, q *WriteOptions) (*WriteMeta, error) { |
| 169 | return c.c.write("/v1/query/"+query.ID, query, nil, q) |
| 170 | } |
| 171 | |
| 172 | // List is used to fetch all the prepared queries (always requires a management |
| 173 | // token). |
| 174 | func (c *PreparedQuery) List(q *QueryOptions) ([]*PreparedQueryDefinition, *QueryMeta, error) { |
| 175 | var out []*PreparedQueryDefinition |
| 176 | qm, err := c.c.query("/v1/query", &out, q) |
| 177 | if err != nil { |
| 178 | return nil, nil, err |
| 179 | } |
| 180 | return out, qm, nil |
| 181 | } |
| 182 | |
| 183 | // Get is used to fetch a specific prepared query. |
| 184 | func (c *PreparedQuery) Get(queryID string, q *QueryOptions) ([]*PreparedQueryDefinition, *QueryMeta, error) { |
| 185 | var out []*PreparedQueryDefinition |
| 186 | qm, err := c.c.query("/v1/query/"+queryID, &out, q) |
| 187 | if err != nil { |
| 188 | return nil, nil, err |
| 189 | } |
| 190 | return out, qm, nil |
| 191 | } |
| 192 | |
| 193 | // Delete is used to delete a specific prepared query. |
| 194 | func (c *PreparedQuery) Delete(queryID string, q *WriteOptions) (*WriteMeta, error) { |
| 195 | r := c.c.newRequest("DELETE", "/v1/query/"+queryID) |
| 196 | r.setWriteOptions(q) |
| 197 | rtt, resp, err := requireOK(c.c.doRequest(r)) |
| 198 | if err != nil { |
| 199 | return nil, err |
| 200 | } |
| 201 | defer resp.Body.Close() |
| 202 | |
| 203 | wm := &WriteMeta{} |
| 204 | wm.RequestTime = rtt |
| 205 | return wm, nil |
| 206 | } |
| 207 | |
| 208 | // Execute is used to execute a specific prepared query. You can execute using |
| 209 | // a query ID or name. |
| 210 | func (c *PreparedQuery) Execute(queryIDOrName string, q *QueryOptions) (*PreparedQueryExecuteResponse, *QueryMeta, error) { |
| 211 | var out *PreparedQueryExecuteResponse |
| 212 | qm, err := c.c.query("/v1/query/"+queryIDOrName+"/execute", &out, q) |
| 213 | if err != nil { |
| 214 | return nil, nil, err |
| 215 | } |
| 216 | return out, qm, nil |
| 217 | } |