1package 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 // If OnlyPassing is true then we will only include nodes with passing 38 // health checks (critical AND warning checks will cause a node to be 39 // discarded) 40 OnlyPassing bool 41 42 // Tags are a set of required and/or disallowed tags. If a tag is in 43 // this list it must be present. If the tag is preceded with "!" then 44 // it is disallowed. 45 Tags []string 46 47 // NodeMeta is a map of required node metadata fields. If a key/value 48 // pair is in this map it must be present on the node in order for the 49 // service entry to be returned. 50 NodeMeta map[string]string 51} 52 53// QueryTemplate carries the arguments for creating a templated query. 54type QueryTemplate struct { 55 // Type specifies the type of the query template. Currently only 56 // "name_prefix_match" is supported. This field is required. 57 Type string 58 59 // Regexp allows specifying a regex pattern to match against the name 60 // of the query being executed. 61 Regexp string 62} 63 64// PrepatedQueryDefinition defines a complete prepared query. 65type PreparedQueryDefinition struct { 66 // ID is this UUID-based ID for the query, always generated by Consul. 67 ID string 68 69 // Name is an optional friendly name for the query supplied by the 70 // user. NOTE - if this feature is used then it will reduce the security 71 // of any read ACL associated with this query/service since this name 72 // can be used to locate nodes with supplying any ACL. 73 Name string 74 75 // Session is an optional session to tie this query's lifetime to. If 76 // this is omitted then the query will not expire. 77 Session string 78 79 // Token is the ACL token used when the query was created, and it is 80 // used when a query is subsequently executed. This token, or a token 81 // with management privileges, must be used to change the query later. 82 Token string 83 84 // Service defines a service query (leaving things open for other types 85 // later). 86 Service ServiceQuery 87 88 // DNS has options that control how the results of this query are 89 // served over DNS. 90 DNS QueryDNSOptions 91 92 // Template is used to pass through the arguments for creating a 93 // prepared query with an attached template. If a template is given, 94 // interpolations are possible in other struct fields. 95 Template QueryTemplate 96} 97 98// PreparedQueryExecuteResponse has the results of executing a query. 99type PreparedQueryExecuteResponse struct { 100 // Service is the service that was queried. 101 Service string 102 103 // Nodes has the nodes that were output by the query. 104 Nodes []ServiceEntry 105 106 // DNS has the options for serving these results over DNS. 107 DNS QueryDNSOptions 108 109 // Datacenter is the datacenter that these results came from. 110 Datacenter string 111 112 // Failovers is a count of how many times we had to query a remote 113 // datacenter. 114 Failovers int 115} 116 117// PreparedQuery can be used to query the prepared query endpoints. 118type PreparedQuery struct { 119 c *Client 120} 121 122// PreparedQuery returns a handle to the prepared query endpoints. 123func (c *Client) PreparedQuery() *PreparedQuery { 124 return &PreparedQuery{c} 125} 126 127// Create makes a new prepared query. The ID of the new query is returned. 128func (c *PreparedQuery) Create(query *PreparedQueryDefinition, q *WriteOptions) (string, *WriteMeta, error) { 129 r := c.c.newRequest("POST", "/v1/query") 130 r.setWriteOptions(q) 131 r.obj = query 132 rtt, resp, err := requireOK(c.c.doRequest(r)) 133 if err != nil { 134 return "", nil, err 135 } 136 defer resp.Body.Close() 137 138 wm := &WriteMeta{} 139 wm.RequestTime = rtt 140 141 var out struct{ ID string } 142 if err := decodeBody(resp, &out); err != nil { 143 return "", nil, err 144 } 145 return out.ID, wm, nil 146} 147 148// Update makes updates to an existing prepared query. 149func (c *PreparedQuery) Update(query *PreparedQueryDefinition, q *WriteOptions) (*WriteMeta, error) { 150 return c.c.write("/v1/query/"+query.ID, query, nil, q) 151} 152 153// List is used to fetch all the prepared queries (always requires a management 154// token). 155func (c *PreparedQuery) List(q *QueryOptions) ([]*PreparedQueryDefinition, *QueryMeta, error) { 156 var out []*PreparedQueryDefinition 157 qm, err := c.c.query("/v1/query", &out, q) 158 if err != nil { 159 return nil, nil, err 160 } 161 return out, qm, nil 162} 163 164// Get is used to fetch a specific prepared query. 165func (c *PreparedQuery) Get(queryID string, q *QueryOptions) ([]*PreparedQueryDefinition, *QueryMeta, error) { 166 var out []*PreparedQueryDefinition 167 qm, err := c.c.query("/v1/query/"+queryID, &out, q) 168 if err != nil { 169 return nil, nil, err 170 } 171 return out, qm, nil 172} 173 174// Delete is used to delete a specific prepared query. 175func (c *PreparedQuery) Delete(queryID string, q *WriteOptions) (*WriteMeta, error) { 176 r := c.c.newRequest("DELETE", "/v1/query/"+queryID) 177 r.setWriteOptions(q) 178 rtt, resp, err := requireOK(c.c.doRequest(r)) 179 if err != nil { 180 return nil, err 181 } 182 defer resp.Body.Close() 183 184 wm := &WriteMeta{} 185 wm.RequestTime = rtt 186 return wm, nil 187} 188 189// Execute is used to execute a specific prepared query. You can execute using 190// a query ID or name. 191func (c *PreparedQuery) Execute(queryIDOrName string, q *QueryOptions) (*PreparedQueryExecuteResponse, *QueryMeta, error) { 192 var out *PreparedQueryExecuteResponse 193 qm, err := c.c.query("/v1/query/"+queryIDOrName+"/execute", &out, q) 194 if err != nil { 195 return nil, nil, err 196 } 197 return out, qm, nil 198} 199