mirror of
https://github.com/fleetdm/fleet
synced 2026-04-21 13:37:30 +00:00
Introduce API version 2022-04, deprecate use of /global in paths (#4731)
This commit is contained in:
parent
57816592ba
commit
90b15071a4
66 changed files with 7411 additions and 1053 deletions
1
changes/issue-2603-deprecate-global-in-routes
Normal file
1
changes/issue-2603-deprecate-global-in-routes
Normal file
|
|
@ -0,0 +1 @@
|
|||
* Introduce new API version (`/api/2022-04/...`, aliased as `/api/latest/...`) to introduce breaking changes that remove `/global` sections from the paths (the deprecated API is still available under `/api/v1/...`)
|
||||
|
|
@ -492,7 +492,7 @@ the way that the Fleet server works.
|
|||
|
||||
defaultWritetimeout := 40 * time.Second
|
||||
writeTimeout := defaultWritetimeout
|
||||
// The "GET /api/v1/fleet/queries/run" API requires
|
||||
// The "GET /api/latest/fleet/queries/run" API requires
|
||||
// WriteTimeout to be higher than the live query rest period
|
||||
// (otherwise the response is not sent back to the client).
|
||||
//
|
||||
|
|
@ -680,6 +680,8 @@ func cronDB(ctx context.Context, ds fleet.Datastore, logger kitlog.Logger, ident
|
|||
sentry.CaptureException(err)
|
||||
}
|
||||
|
||||
// NOTE(mna): this is not a route from the fleet server (not in server/service/handler.go) so it
|
||||
// will not automatically support the /latest/ versioning. Leaving it as /v1/ for that reason.
|
||||
err = trySendStatistics(ctx, ds, fleet.StatisticsFrequency, "https://fleetdm.com/api/v1/webhooks/receive-usage-analytics", license)
|
||||
if err != nil {
|
||||
level.Error(logger).Log("err", "sending statistics", "details", err)
|
||||
|
|
|
|||
|
|
@ -269,7 +269,7 @@ spec:
|
|||
`)
|
||||
|
||||
runAppCheckErr(t, []string{"apply", "-f", name},
|
||||
"applying fleet config: PATCH /api/v1/fleet/config received status 400 Bad request: json: unknown field \"enabled_software_inventory\"",
|
||||
"applying fleet config: PATCH /api/latest/fleet/config received status 400 Bad request: json: unknown field \"enabled_software_inventory\"",
|
||||
)
|
||||
require.Nil(t, savedAppConfig)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -464,7 +464,7 @@ or provide an <address> argument to debug: fleetctl debug connection localhost:8
|
|||
}
|
||||
|
||||
// Check that the server responds with expected responses (by
|
||||
// making a POST to /api/v1/osquery/enroll with an invalid
|
||||
// making a POST to /api/osquery/enroll with an invalid
|
||||
// secret).
|
||||
if err := checkAPIEndpoint(c.Context, timeoutPerCheck, baseURL, cli); err != nil {
|
||||
return fmt.Errorf("Fail: agent API endpoint: %w", err)
|
||||
|
|
@ -681,7 +681,7 @@ func checkAPIEndpoint(ctx context.Context, timeout time.Duration, baseURL *url.U
|
|||
"Accept": "application/json",
|
||||
}
|
||||
|
||||
baseURL.Path = "/api/v1/osquery/enroll"
|
||||
baseURL.Path = "/api/osquery/enroll"
|
||||
req, err := http.NewRequestWithContext(
|
||||
ctx,
|
||||
"POST",
|
||||
|
|
|
|||
|
|
@ -279,7 +279,7 @@ func (a *agent) enroll(i int, onlyAlreadyEnrolled bool) error {
|
|||
req.Header.SetMethod("POST")
|
||||
req.Header.SetContentType("application/json")
|
||||
req.Header.Add("User-Agent", "osquery/4.6.0")
|
||||
req.SetRequestURI(a.serverAddress + "/api/v1/osquery/enroll")
|
||||
req.SetRequestURI(a.serverAddress + "/api/osquery/enroll")
|
||||
res := fasthttp.AcquireResponse()
|
||||
|
||||
a.waitingDo(req, res)
|
||||
|
|
@ -314,7 +314,7 @@ func (a *agent) config() {
|
|||
req.Header.SetMethod("POST")
|
||||
req.Header.SetContentType("application/json")
|
||||
req.Header.Add("User-Agent", "osquery/4.6.0")
|
||||
req.SetRequestURI(a.serverAddress + "/api/v1/osquery/config")
|
||||
req.SetRequestURI(a.serverAddress + "/api/osquery/config")
|
||||
res := fasthttp.AcquireResponse()
|
||||
|
||||
a.waitingDo(req, res)
|
||||
|
|
@ -435,7 +435,7 @@ func (a *agent) DistributedRead() (*distributedReadResponse, error) {
|
|||
req.Header.SetMethod("POST")
|
||||
req.Header.SetContentType("application/json")
|
||||
req.Header.Add("User-Agent", "osquery/4.6.0")
|
||||
req.SetRequestURI(a.serverAddress + "/api/v1/osquery/distributed/read")
|
||||
req.SetRequestURI(a.serverAddress + "/api/osquery/distributed/read")
|
||||
res := fasthttp.AcquireResponse()
|
||||
|
||||
a.waitingDo(req, res)
|
||||
|
|
@ -587,7 +587,7 @@ func (a *agent) DistributedWrite(queries map[string]string) {
|
|||
req.Header.SetMethod("POST")
|
||||
req.Header.SetContentType("application/json")
|
||||
req.Header.Add("User-Agent", "osquery/5.0.1")
|
||||
req.SetRequestURI(a.serverAddress + "/api/v1/osquery/distributed/write")
|
||||
req.SetRequestURI(a.serverAddress + "/api/osquery/distributed/write")
|
||||
res := fasthttp.AcquireResponse()
|
||||
|
||||
a.waitingDo(req, res)
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ services:
|
|||
image: fleetdm/docker-idp:latest
|
||||
environment:
|
||||
SIMPLESAMLPHP_SP_ENTITY_ID: "https://localhost:8080"
|
||||
SIMPLESAMLPHP_SP_ASSERTION_CONSUMER_SERVICE: "https://localhost:8080/api/v1/fleet/sso/callback"
|
||||
SIMPLESAMLPHP_SP_ASSERTION_CONSUMER_SERVICE: "https://localhost:8080/api/latest/fleet/sso/callback"
|
||||
volumes:
|
||||
- ./tools/saml/users.php:/var/www/simplesamlphp/config/authsources.php
|
||||
ports:
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ Unlike the [Fleet REST API documentation](../Using-Fleet/REST-API.md), the API r
|
|||
|
||||
Returns a list of all queries in the Fleet instance. Each item returned includes the name, description, and SQL of the query.
|
||||
|
||||
`GET /api/v1/fleet/spec/queries`
|
||||
`GET /api/latest/fleet/spec/queries`
|
||||
|
||||
#### Parameters
|
||||
|
||||
|
|
@ -35,7 +35,7 @@ None.
|
|||
|
||||
#### Example
|
||||
|
||||
`GET /api/v1/fleet/spec/queries`
|
||||
`GET /api/latest/fleet/spec/queries`
|
||||
|
||||
##### Default response
|
||||
|
||||
|
|
@ -62,7 +62,7 @@ None.
|
|||
|
||||
Returns the name, description, and SQL of the query specified by name.
|
||||
|
||||
`GET /api/v1/fleet/spec/queries/{name}`
|
||||
`GET /api/latest/fleet/spec/queries/{name}`
|
||||
|
||||
#### Parameters
|
||||
|
||||
|
|
@ -72,7 +72,7 @@ Returns the name, description, and SQL of the query specified by name.
|
|||
|
||||
#### Example
|
||||
|
||||
`GET /api/v1/fleet/spec/queries/query1`
|
||||
`GET /api/latest/fleet/spec/queries/query1`
|
||||
|
||||
##### Default response
|
||||
|
||||
|
|
@ -92,7 +92,7 @@ Returns the name, description, and SQL of the query specified by name.
|
|||
|
||||
Creates and/or modifies the queries included in the specs list. To modify an existing query, the name of the query included in `specs` must already be used by an existing query. If a query with the specified name doesn't exist in Fleet, a new query will be created.
|
||||
|
||||
`POST /api/v1/fleet/spec/queries`
|
||||
`POST /api/latest/fleet/spec/queries`
|
||||
|
||||
#### Parameters
|
||||
|
||||
|
|
@ -102,7 +102,7 @@ Creates and/or modifies the queries included in the specs list. To modify an exi
|
|||
|
||||
#### Example
|
||||
|
||||
`POST /api/v1/fleet/spec/queries`
|
||||
`POST /api/latest/fleet/spec/queries`
|
||||
|
||||
##### Request body
|
||||
|
||||
|
|
@ -131,11 +131,11 @@ Creates and/or modifies the queries included in the specs list. To modify an exi
|
|||
|
||||
Returns the specs for all packs in the Fleet instance.
|
||||
|
||||
`GET /api/v1/fleet/spec/packs`
|
||||
`GET /api/latest/fleet/spec/packs`
|
||||
|
||||
#### Example
|
||||
|
||||
`GET /api/v1/fleet/spec/packs`
|
||||
`GET /api/latest/fleet/spec/packs`
|
||||
|
||||
##### Default response
|
||||
|
||||
|
|
@ -247,7 +247,7 @@ Returns the specs for all packs in the Fleet instance.
|
|||
|
||||
Returns the specs for all packs in the Fleet instance.
|
||||
|
||||
`POST /api/v1/fleet/spec/packs`
|
||||
`POST /api/latest/fleet/spec/packs`
|
||||
|
||||
#### Parameters
|
||||
|
||||
|
|
@ -257,7 +257,7 @@ Returns the specs for all packs in the Fleet instance.
|
|||
|
||||
#### Example
|
||||
|
||||
`POST /api/v1/fleet/spec/packs`
|
||||
`POST /api/latest/fleet/spec/packs`
|
||||
|
||||
##### Request body
|
||||
|
||||
|
|
@ -356,7 +356,7 @@ Returns the specs for all packs in the Fleet instance.
|
|||
|
||||
Returns the spec for the specified pack by pack name.
|
||||
|
||||
`GET /api/v1/fleet/spec/packs/{name}`
|
||||
`GET /api/latest/fleet/spec/packs/{name}`
|
||||
|
||||
#### Parameters
|
||||
|
||||
|
|
@ -366,7 +366,7 @@ Returns the spec for the specified pack by pack name.
|
|||
|
||||
#### Example
|
||||
|
||||
`GET /api/v1/fleet/spec/packs/pack_1`
|
||||
`GET /api/latest/fleet/spec/packs/pack_1`
|
||||
|
||||
##### Default response
|
||||
|
||||
|
|
@ -447,19 +447,19 @@ If the `name` specified is associated with an existing team, this API route, com
|
|||
|
||||
If the `name` is not already associated with an existing team, this API route creates a new team with the specified `name`, `agent_options`, and `secrets`.
|
||||
|
||||
`POST /api/v1/fleet/spec/teams`
|
||||
`POST /api/latest/fleet/spec/teams`
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | In | Description |
|
||||
| ------------- | ------ | ---- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| name | string | body | **Required.** The team's name. |
|
||||
| agent_options | string | body | **Required.** The agent options spec that is applied to the hosts assigned to the specified to team. These agent agent options completely override the global agent options specified in the [`GET /api/v1/fleet/config API route`](#get-configuration) |
|
||||
| agent_options | string | body | **Required.** The agent options spec that is applied to the hosts assigned to the specified to team. These agent agent options completely override the global agent options specified in the [`GET /api/latest/fleet/config API route`](#get-configuration) |
|
||||
| secrets | list | body | **Required.** A list of plain text strings used as the enroll secrets. |
|
||||
|
||||
#### Example
|
||||
|
||||
`POST /api/v1/fleet/spec/teams`
|
||||
`POST /api/latest/fleet/spec/teams`
|
||||
|
||||
##### Request body
|
||||
|
||||
|
|
@ -477,7 +477,7 @@ If the `name` is not already associated with an existing team, this API route cr
|
|||
"logger_tls_period": 10,
|
||||
"distributed_plugin": "tls",
|
||||
"disable_distributed": false,
|
||||
"logger_tls_endpoint": "/api/v1/osquery/log",
|
||||
"logger_tls_endpoint": "/api/osquery/log",
|
||||
"distributed_interval": 10,
|
||||
"distributed_tls_max_attempts": 3
|
||||
},
|
||||
|
|
@ -516,7 +516,7 @@ If the `label_membership_type` is set to `dynamic`, the `query` property must al
|
|||
|
||||
If the `label_membership_type` is set to `manual`, the `hosts` property must also be specified with the value set to a list of hostnames.
|
||||
|
||||
`POST /api/v1/fleet/spec/labels`
|
||||
`POST /api/latest/fleet/spec/labels`
|
||||
|
||||
#### Parameters
|
||||
|
||||
|
|
@ -526,7 +526,7 @@ If the `label_membership_type` is set to `manual`, the `hosts` property must als
|
|||
|
||||
#### Example
|
||||
|
||||
`POST /api/v1/fleet/spec/labels`
|
||||
`POST /api/latest/fleet/spec/labels`
|
||||
|
||||
##### Request body
|
||||
|
||||
|
|
@ -555,7 +555,7 @@ If the `label_membership_type` is set to `manual`, the `hosts` property must als
|
|||
|
||||
### Get labels spec
|
||||
|
||||
`GET /api/v1/fleet/spec/labels`
|
||||
`GET /api/latest/fleet/spec/labels`
|
||||
|
||||
#### Parameters
|
||||
|
||||
|
|
@ -563,7 +563,7 @@ None.
|
|||
|
||||
#### Example
|
||||
|
||||
`GET /api/v1/fleet/spec/labels`
|
||||
`GET /api/latest/fleet/spec/labels`
|
||||
|
||||
##### Default response
|
||||
|
||||
|
|
@ -630,7 +630,7 @@ None.
|
|||
|
||||
Returns the spec for the label specified by name.
|
||||
|
||||
`GET /api/v1/fleet/spec/labels/{name}`
|
||||
`GET /api/latest/fleet/spec/labels/{name}`
|
||||
|
||||
#### Parameters
|
||||
|
||||
|
|
@ -638,7 +638,7 @@ None.
|
|||
|
||||
#### Example
|
||||
|
||||
`GET /api/v1/fleet/spec/labels/local_machine`
|
||||
`GET /api/latest/fleet/spec/labels/local_machine`
|
||||
|
||||
##### Default response
|
||||
|
||||
|
|
@ -660,7 +660,7 @@ None.
|
|||
|
||||
Returns the valid global enroll secrets.
|
||||
|
||||
`GET /api/v1/fleet/spec/enroll_secret`
|
||||
`GET /api/latest/fleet/spec/enroll_secret`
|
||||
|
||||
#### Parameters
|
||||
|
||||
|
|
@ -668,7 +668,7 @@ None.
|
|||
|
||||
#### Example
|
||||
|
||||
`GET /api/v1/fleet/spec/enroll_secret`
|
||||
`GET /api/latest/fleet/spec/enroll_secret`
|
||||
|
||||
##### Default response
|
||||
|
||||
|
|
@ -695,7 +695,7 @@ None.
|
|||
|
||||
Replaces the active global enroll secrets with the secrets specified.
|
||||
|
||||
`POST /api/v1/fleet/spec/enroll_secret`
|
||||
`POST /api/latest/fleet/spec/enroll_secret`
|
||||
|
||||
#### Parameters
|
||||
|
||||
|
|
@ -719,7 +719,7 @@ Replaces the active global enroll secrets with the secrets specified.
|
|||
}
|
||||
```
|
||||
|
||||
`POST /api/v1/fleet/spec/enroll_secret`
|
||||
`POST /api/latest/fleet/spec/enroll_secret`
|
||||
|
||||
##### Default response
|
||||
|
||||
|
|
@ -729,7 +729,7 @@ Replaces the active global enroll secrets with the secrets specified.
|
|||
|
||||
Checks the status of the Fleet's ability to run a live query. If an error is present in the response, Fleet won't be able to successfully run a live query. This endpoint is used by the Fleet UI to make sure that the Fleet instance is correctly configured to run live queries.
|
||||
|
||||
`GET /api/v1/fleet/status/live_query`
|
||||
`GET /api/latest/fleet/status/live_query`
|
||||
|
||||
#### Parameters
|
||||
|
||||
|
|
@ -737,7 +737,7 @@ None.
|
|||
|
||||
#### Example
|
||||
|
||||
`GET /api/v1/fleet/status/live_query`
|
||||
`GET /api/latest/fleet/status/live_query`
|
||||
|
||||
##### Default response
|
||||
|
||||
|
|
@ -747,7 +747,7 @@ None.
|
|||
|
||||
Checks the status of the Fleet's result store. If an error is present in the response, Fleet won't be able to successfully run a live query. This endpoint is used by the Fleet UI to make sure that the Fleet instance is correctly configured to run live queries.
|
||||
|
||||
`GET /api/v1/fleet/status/result_store`
|
||||
`GET /api/latest/fleet/status/result_store`
|
||||
|
||||
#### Parameters
|
||||
|
||||
|
|
@ -755,7 +755,7 @@ None.
|
|||
|
||||
#### Example
|
||||
|
||||
`GET /api/v1/fleet/status/result_store`
|
||||
`GET /api/latest/fleet/status/result_store`
|
||||
|
||||
##### Default response
|
||||
|
||||
|
|
@ -767,7 +767,7 @@ Runs the specified query as a live query on the specified hosts or group of host
|
|||
|
||||
After the query has been initiated, [get results via WebSocket](#retrieve-live-query-results-standard-websocket-api).
|
||||
|
||||
`POST /api/v1/fleet/queries/run`
|
||||
`POST /api/latest/fleet/queries/run`
|
||||
|
||||
#### Parameters
|
||||
|
||||
|
|
@ -781,7 +781,7 @@ One of `query` and `query_id` must be specified.
|
|||
|
||||
#### Example with one host targeted by ID
|
||||
|
||||
`POST /api/v1/fleet/queries/run`
|
||||
`POST /api/latest/fleet/queries/run`
|
||||
|
||||
##### Request body
|
||||
|
||||
|
|
@ -820,7 +820,7 @@ One of `query` and `query_id` must be specified.
|
|||
|
||||
#### Example with multiple hosts targeted by label ID
|
||||
|
||||
`POST /api/v1/fleet/queries/run`
|
||||
`POST /api/latest/fleet/queries/run`
|
||||
|
||||
##### Request body
|
||||
|
||||
|
|
@ -863,7 +863,7 @@ Runs the specified saved query as a live query on the specified targets. Returns
|
|||
|
||||
After the query has been initiated, [get results via WebSocket](#retrieve-live-query-results-standard-websocket-api).
|
||||
|
||||
`POST /api/v1/fleet/queries/run_by_names`
|
||||
`POST /api/latest/fleet/queries/run_by_names`
|
||||
|
||||
#### Parameters
|
||||
|
||||
|
|
@ -877,7 +877,7 @@ One of `query` and `query_id` must be specified.
|
|||
|
||||
#### Example with one host targeted by hostname
|
||||
|
||||
`POST /api/v1/fleet/queries/run_by_names`
|
||||
`POST /api/latest/fleet/queries/run_by_names`
|
||||
|
||||
##### Request body
|
||||
|
||||
|
|
@ -916,7 +916,7 @@ One of `query` and `query_id` must be specified.
|
|||
|
||||
#### Example with multiple hosts targeted by label name
|
||||
|
||||
`POST /api/v1/fleet/queries/run_by_names`
|
||||
`POST /api/latest/fleet/queries/run_by_names`
|
||||
|
||||
##### Request body
|
||||
|
||||
|
|
@ -1238,7 +1238,7 @@ Creates and/or modifies the policies included in the specs list. To modify an ex
|
|||
|
||||
NOTE: when updating a policy, team and platform will be ignored.
|
||||
|
||||
`POST /api/v1/fleet/spec/policies`
|
||||
`POST /api/latest/fleet/spec/policies`
|
||||
|
||||
#### Parameters
|
||||
|
||||
|
|
@ -1248,7 +1248,7 @@ NOTE: when updating a policy, team and platform will be ignored.
|
|||
|
||||
#### Example
|
||||
|
||||
`POST /api/v1/fleet/spec/policies`
|
||||
`POST /api/latest/fleet/spec/policies`
|
||||
|
||||
##### Request body
|
||||
|
||||
|
|
|
|||
|
|
@ -2299,10 +2299,10 @@ _**Note that the email being used in the SAML Assertion must match a user that a
|
|||
Setting up the service provider (Fleet) with an identity provider generally requires the following information:
|
||||
|
||||
- _Assertion Consumer Service_ - This is the call back URL that the identity provider
|
||||
will use to send security assertions to Fleet. In Okta, this field is called _Single sign on URL_. On Google it is "ACS URL". The value that you supply will be a fully qualified URL consisting of your Fleet web address and the callback path `/api/v1/fleet/sso/callback`. For example, if your Fleet web address is https://fleet.example.com, then the value you would use in the identity provider configuration would be:
|
||||
will use to send security assertions to Fleet. In Okta, this field is called _Single sign on URL_. On Google it is "ACS URL". The value that you supply will be a fully qualified URL consisting of your Fleet web address and the callback path `/api/latest/fleet/sso/callback`. For example, if your Fleet web address is https://fleet.example.com, then the value you would use in the identity provider configuration would be:
|
||||
|
||||
```
|
||||
https://fleet.example.com/api/v1/fleet/sso/callback
|
||||
https://fleet.example.com/api/latest/fleet/sso/callback
|
||||
```
|
||||
|
||||
- _Entity ID_ - This value is an identifier that you choose. It identifies your Fleet instance as the service provider that issues authorization requests. The value must exactly match the Entity ID that you define in the Fleet SSO configuration.
|
||||
|
|
@ -2390,7 +2390,7 @@ Follow these steps to configure Fleet SSO with Google Workspace. This will requi
|
|||
|
||||
5. In Google Workspace, configure the _Service provider details_.
|
||||
|
||||
- For _ACS URL_, use `https://<your_fleet_url>/api/v1/fleet/sso/callback` (eg. `https://fleet.example.com/api/v1/fleet/sso/callback`).
|
||||
- For _ACS URL_, use `https://<your_fleet_url>/api/latest/fleet/sso/callback` (eg. `https://fleet.example.com/api/latest/fleet/sso/callback`).
|
||||
- For Entity ID, use **the same unique identifier from step 4** (eg. `fleet.example.com`).
|
||||
- For _Name ID format_ choose `EMAIL`.
|
||||
- For _Name ID_ choose `Basic Information > Primary email`.
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ Osquery requires that all communication between the agent and Fleet are over a s
|
|||
- Try specifying the path to the full certificate chain used by the server using the `--tls_server_certs` flag in `osqueryd`. This is often unnecessary when using a certificate signed by an authority trusted by the system, but is mandatory when working with self-signed certificates. In all cases it can be a useful debugging step.
|
||||
- Ensure that the CNAME or one of the Subject Alternate Names (SANs) on the certificate matches the address at which the server is being accessed. If osquery connects via `https://localhost:443`, but the certificate is for `https://fleet.example.com`, the verification will fail.
|
||||
- Is Fleet behind a load-balancer? Ensure that if the load-balancer is terminating TLS, this is the certificate provided to osquery.
|
||||
- Does the certificate verify with `curl`? Try `curl -v -X POST https://fleetserver:port/api/v1/osquery/enroll`.
|
||||
- Does the certificate verify with `curl`? Try `curl -v -X POST https://fleetserver:port/api/osquery/enroll`.
|
||||
|
||||
## What do I need to do to change the Fleet server TLS certificate?
|
||||
|
||||
|
|
@ -237,7 +237,7 @@ Check out the [documentation on running database migrations](./Upgrading-Fleet.m
|
|||
|
||||
## What API endpoints should I expose to the public internet?
|
||||
|
||||
If you would like to manage hosts that can travel outside your VPN or intranet we recommend only exposing the "/api/v1/osquery" endpoint to the public internet.
|
||||
If you would like to manage hosts that can travel outside your VPN or intranet we recommend only exposing the "/api/osquery" endpoint to the public internet.
|
||||
|
||||
## What is the minimum version of MySQL required by Fleet?
|
||||
|
||||
|
|
|
|||
|
|
@ -225,18 +225,18 @@ sudo /usr/bin/osqueryd \
|
|||
--tls_server_certs=/var/osquery/server.pem \
|
||||
--tls_hostname=localhost:8080 \
|
||||
--host_identifier=instance \
|
||||
--enroll_tls_endpoint=/api/v1/osquery/enroll \
|
||||
--enroll_tls_endpoint=/api/osquery/enroll \
|
||||
--config_plugin=tls \
|
||||
--config_tls_endpoint=/api/v1/osquery/config \
|
||||
--config_tls_endpoint=/api/osquery/config \
|
||||
--config_refresh=10 \
|
||||
--disable_distributed=false \
|
||||
--distributed_plugin=tls \
|
||||
--distributed_interval=3 \
|
||||
--distributed_tls_max_attempts=3 \
|
||||
--distributed_tls_read_endpoint=/api/v1/osquery/distributed/read \
|
||||
--distributed_tls_write_endpoint=/api/v1/osquery/distributed/write \
|
||||
--distributed_tls_read_endpoint=/api/osquery/distributed/read \
|
||||
--distributed_tls_write_endpoint=/api/osquery/distributed/write \
|
||||
--logger_plugin=tls \
|
||||
--logger_tls_endpoint=/api/v1/osquery/log \
|
||||
--logger_tls_endpoint=/api/osquery/log \
|
||||
--logger_tls_period=10
|
||||
```
|
||||
|
||||
|
|
@ -398,18 +398,18 @@ sudo /usr/bin/osqueryd \
|
|||
--tls_server_certs=/var/osquery/server.pem \
|
||||
--tls_hostname=localhost:8080 \
|
||||
--host_identifier=instance \
|
||||
--enroll_tls_endpoint=/api/v1/osquery/enroll \
|
||||
--enroll_tls_endpoint=/api/osquery/enroll \
|
||||
--config_plugin=tls \
|
||||
--config_tls_endpoint=/api/v1/osquery/config \
|
||||
--config_tls_endpoint=/api/osquery/config \
|
||||
--config_refresh=10 \
|
||||
--disable_distributed=false \
|
||||
--distributed_plugin=tls \
|
||||
--distributed_interval=3 \
|
||||
--distributed_tls_max_attempts=3 \
|
||||
--distributed_tls_read_endpoint=/api/v1/osquery/distributed/read \
|
||||
--distributed_tls_write_endpoint=/api/v1/osquery/distributed/write \
|
||||
--distributed_tls_read_endpoint=/api/osquery/distributed/read \
|
||||
--distributed_tls_write_endpoint=/api/osquery/distributed/write \
|
||||
--logger_plugin=tls \
|
||||
--logger_tls_endpoint=/api/v1/osquery/log \
|
||||
--logger_tls_endpoint=/api/osquery/log \
|
||||
--logger_tls_period=10
|
||||
```
|
||||
|
||||
|
|
@ -601,4 +601,4 @@ Below are some projects created by Fleet community members. These projects provi
|
|||
|
||||
- [CptOfEvilMinions/FleetDM-Automation](https://github.com/CptOfEvilMinions/FleetDM-Automation) - Ansible and Docker code to set up Fleet
|
||||
|
||||
<meta name="pageOrderInSection" value="200">
|
||||
<meta name="pageOrderInSection" value="200">
|
||||
|
|
|
|||
|
|
@ -136,18 +136,18 @@ sudo osqueryd \
|
|||
--tls_server_certs=/etc/osquery/fleet.crt \
|
||||
--tls_hostname=fleet.example.com \
|
||||
--host_identifier=uuid \
|
||||
--enroll_tls_endpoint=/api/v1/osquery/enroll \
|
||||
--enroll_tls_endpoint=/api/osquery/enroll \
|
||||
--config_plugin=tls \
|
||||
--config_tls_endpoint=/api/v1/osquery/config \
|
||||
--config_tls_endpoint=/api/osquery/config \
|
||||
--config_refresh=10 \
|
||||
--disable_distributed=false \
|
||||
--distributed_plugin=tls \
|
||||
--distributed_interval=10 \
|
||||
--distributed_tls_max_attempts=3 \
|
||||
--distributed_tls_read_endpoint=/api/v1/osquery/distributed/read \
|
||||
--distributed_tls_write_endpoint=/api/v1/osquery/distributed/write \
|
||||
--distributed_tls_read_endpoint=/api/osquery/distributed/read \
|
||||
--distributed_tls_write_endpoint=/api/osquery/distributed/write \
|
||||
--logger_plugin=tls \
|
||||
--logger_tls_endpoint=/api/v1/osquery/log \
|
||||
--logger_tls_endpoint=/api/osquery/log \
|
||||
--logger_tls_period=10
|
||||
```
|
||||
|
||||
|
|
@ -206,4 +206,4 @@ installation should appear as the same host in the Fleet UI. If other settings a
|
|||
entries will appear in the Fleet UI. The older entries can be automatically cleaned up with the host
|
||||
expiration functionality configured in the application settings (UI or fleetctl).
|
||||
|
||||
<meta name="pageOrderInSection" value="500">
|
||||
<meta name="pageOrderInSection" value="500">
|
||||
|
|
|
|||
|
|
@ -126,17 +126,17 @@ Live query results are never logged to the filesystem of the Fleet server. See [
|
|||
|
||||
You cannot. Scheduled query results are logged to whatever logging plugin you have configured and are not stored in the Fleet DB.
|
||||
|
||||
However, the Fleet API exposes a significant amount of host information via the [`api/v1/fleet/hosts`](./REST-API.md#list-hosts) and the [`api/v1/fleet/hosts/{id}`](./REST-API.md#get-host) API endpoints. The `api/v1/fleet/hosts` [can even be configured to return additional host information](https://github.com/fleetdm/fleet/blob/9fb9da31f5462fa7dda4819a114bbdbc0252c347/docs/1-Using-Fleet/2-fleetctl-CLI.md#fleet-configuration-options).
|
||||
However, the Fleet API exposes a significant amount of host information via the [`api/latest/fleet/hosts`](./REST-API.md#list-hosts) and the [`api/latest/fleet/hosts/{id}`](./REST-API.md#get-host) API endpoints. The `api/latest/fleet/hosts` [can even be configured to return additional host information](https://github.com/fleetdm/fleet/blob/9fb9da31f5462fa7dda4819a114bbdbc0252c347/docs/1-Using-Fleet/2-fleetctl-CLI.md#fleet-configuration-options).
|
||||
|
||||
As an example, let's say you want to retrieve a host's OS version, installed software, and kernel version:
|
||||
|
||||
Each host’s OS version is available using the `api/v1/fleet/hosts` API endpoint. [Check out the API documentation for this endpoint](./REST-API.md#list-hosts).
|
||||
Each host’s OS version is available using the `api/latest/fleet/hosts` API endpoint. [Check out the API documentation for this endpoint](./REST-API.md#list-hosts).
|
||||
|
||||
The ability to view each host’s installed software was released behind a feature flag in Fleet 3.11.0 and called Software inventory. [Check out the feature flag documentation for instructions on turning on Software inventory in Fleet](../Deploying/Configuration.md#feature-flags).
|
||||
|
||||
Once the Software inventory feature is turned on, a list of a specific host’s installed software is available using the `api/v1/fleet/hosts/{id}` endpoint. [Check out the documentation for this endpoint](./REST-API.md#get-host).
|
||||
Once the Software inventory feature is turned on, a list of a specific host’s installed software is available using the `api/latest/fleet/hosts/{id}` endpoint. [Check out the documentation for this endpoint](./REST-API.md#get-host).
|
||||
|
||||
It’s possible in Fleet to retrieve each host’s kernel version, using the Fleet API, through `additional_queries`. The Fleet configuration options yaml file includes an `additional_queries` property that allows you to append custom query results to the host details returned by the `api/v1/fleet/hosts` endpoint. [Check out an example configuration file with the additional_queries field](./fleetctl-CLI.md#fleet-configuration-options).
|
||||
It’s possible in Fleet to retrieve each host’s kernel version, using the Fleet API, through `additional_queries`. The Fleet configuration options yaml file includes an `additional_queries` property that allows you to append custom query results to the host details returned by the `api/latest/fleet/hosts` endpoint. [Check out an example configuration file with the additional_queries field](./fleetctl-CLI.md#fleet-configuration-options).
|
||||
|
||||
## How do I automatically add hosts to packs when the hosts enroll to Fleet?
|
||||
|
||||
|
|
|
|||
6151
docs/Using-Fleet/REST-API-v1.md
Normal file
6151
docs/Using-Fleet/REST-API-v1.md
Normal file
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -19,8 +19,8 @@ to detect the CVEs that match the defined CPEs.
|
|||
|
||||
If matches are found, they are exposed on each host's
|
||||
**Host details** page and on the **Home** page in the Fleet UI. The CVEs are also exposed in the
|
||||
`fleetctl get software` command and the `GET api/v1/fleet/hosts/{id}` and `GET
|
||||
api/v1/fleet/software` API routes.
|
||||
`fleetctl get software` command and the `GET api/latest/fleet/hosts/{id}` and `GET
|
||||
api/latest/fleet/software` API routes.
|
||||
|
||||
Vulnerability processing happens on the Fleet instance and not on the host machine. Because of this,
|
||||
detected vulnerabilities cannot be used in the same way you would use an osquery query (e.g. you wouldn't
|
||||
|
|
|
|||
|
|
@ -191,7 +191,7 @@ spec:
|
|||
distributed_plugin: tls
|
||||
distributed_tls_max_attempts: 3
|
||||
logger_plugin: tls
|
||||
logger_tls_endpoint: /api/v1/osquery/log
|
||||
logger_tls_endpoint: /api/osquery/log
|
||||
logger_tls_period: 10
|
||||
pack_delimiter: /
|
||||
overrides: {}
|
||||
|
|
@ -218,10 +218,10 @@ spec:
|
|||
distributed_interval: 10
|
||||
distributed_plugin: tls
|
||||
distributed_tls_max_attempts: 3
|
||||
distributed_tls_read_endpoint: /api/v1/osquery/distributed/read
|
||||
distributed_tls_write_endpoint: /api/v1/osquery/distributed/write
|
||||
distributed_tls_read_endpoint: /api/osquery/distributed/read
|
||||
distributed_tls_write_endpoint: /api/osquery/distributed/write
|
||||
logger_plugin: tls
|
||||
logger_tls_endpoint: /api/v1/osquery/log
|
||||
logger_tls_endpoint: /api/osquery/log
|
||||
logger_tls_period: 10
|
||||
pack_delimiter: /
|
||||
overrides: {}
|
||||
|
|
@ -266,7 +266,7 @@ spec:
|
|||
failing_policies_webhook:
|
||||
enable_failing_policies_webhook: true
|
||||
destination_url": https://server.com
|
||||
policy_ids:
|
||||
policy_ids:
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
|
|
@ -304,7 +304,7 @@ spec:
|
|||
distributed_interval: 3
|
||||
distributed_tls_max_attempts: 3
|
||||
logger_plugin: tls
|
||||
logger_tls_endpoint: /api/v1/osquery/log
|
||||
logger_tls_endpoint: /api/osquery/log
|
||||
logger_tls_period: 10
|
||||
decorators:
|
||||
load:
|
||||
|
|
@ -327,7 +327,7 @@ spec:
|
|||
distributed_interval: 10
|
||||
distributed_tls_max_attempts: 10
|
||||
logger_plugin: tls
|
||||
logger_tls_endpoint: /api/v1/osquery/log
|
||||
logger_tls_endpoint: /api/osquery/log
|
||||
logger_tls_period: 300
|
||||
disable_tables: chrome_extensions
|
||||
docker_socket: /var/run/docker.sock
|
||||
|
|
@ -343,7 +343,7 @@ spec:
|
|||
distributed_interval: 10
|
||||
distributed_tls_max_attempts: 3
|
||||
logger_plugin: tls
|
||||
logger_tls_endpoint: /api/v1/osquery/log
|
||||
logger_tls_endpoint: /api/osquery/log
|
||||
logger_tls_period: 60
|
||||
schedule_timeout: 60
|
||||
docker_socket: /etc/run/docker.sock
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ spec:
|
|||
distributed_plugin: tls
|
||||
distributed_tls_max_attempts: 3
|
||||
logger_plugin: tls
|
||||
logger_tls_endpoint: /api/v1/osquery/log
|
||||
logger_tls_endpoint: /api/osquery/log
|
||||
logger_tls_period: 10
|
||||
pack_delimiter: /
|
||||
overrides: {}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ spec:
|
|||
distributed_plugin: tls
|
||||
distributed_tls_max_attempts: 3
|
||||
logger_plugin: tls
|
||||
logger_tls_endpoint: /api/v1/osquery/log
|
||||
logger_tls_endpoint: /api/osquery/log
|
||||
logger_tls_period: 10
|
||||
pack_delimiter: /
|
||||
overrides: {}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ spec:
|
|||
distributed_plugin: tls
|
||||
distributed_tls_max_attempts: 3
|
||||
logger_plugin: tls
|
||||
logger_tls_endpoint: /api/v1/osquery/log
|
||||
logger_tls_endpoint: /api/osquery/log
|
||||
logger_tls_period: 10
|
||||
pack_delimiter: /
|
||||
overrides: {}
|
||||
|
|
|
|||
|
|
@ -26,12 +26,12 @@ Fleetctl also provides a quick way to work with all the data exposed by Fleet wi
|
|||
|
||||
## Using fleetctl
|
||||
|
||||
You can use `fleetctl` to accomplish many tasks you would typically need to do through the UI(User Interface). You can even set up or apply configuration files to the Fleet server.
|
||||
You can use `fleetctl` to accomplish many tasks you would typically need to do through the UI(User Interface). You can even set up or apply configuration files to the Fleet server.
|
||||
|
||||
### Available commands
|
||||
|
||||
Much of the functionality available in the Fleet UI is also available in `fleetctl`. You can run queries, add and remove users, generate install packages to add new hosts, get information about existing hosts, and more! The following commands are available for use with `fleetctl`:
|
||||
|
||||
|
||||
| Command | Description |
|
||||
|:---------------------------|:-------------------------------------------------------------------|
|
||||
| apply | Apply files to declaratively manage osquery configurations |
|
||||
|
|
@ -208,7 +208,7 @@ Note the token can also be set with `fleetctl config set --token`, but this may
|
|||
|
||||
## Using fleetctl to configure Fleet
|
||||
|
||||
A Fleet configuration is defined using one or more declarative "messages" in yaml syntax.
|
||||
A Fleet configuration is defined using one or more declarative "messages" in yaml syntax.
|
||||
|
||||
Fleet configuration can be retrieved and applied using the `fleetctl` tool.
|
||||
|
||||
|
|
@ -271,7 +271,7 @@ fleetctl user create --name "API User" --email api@example.com --password temp!p
|
|||
|
||||
### Reset the password
|
||||
|
||||
When a new user is created, a password reset is needed before that user can perform queries. Since an API-only user cannot log in to the Fleet UI, this is done through the REST API. We'll be doing this through the terminal using `curl`.
|
||||
When a new user is created, a password reset is needed before that user can perform queries. Since an API-only user cannot log in to the Fleet UI, this is done through the REST API. We'll be doing this through the terminal using `curl`.
|
||||
|
||||
First, log in to the new user account using `fleetctl login`. Once you're logged in successfully to the API-only user, set up a variable to hold the user's token:
|
||||
|
||||
|
|
@ -313,7 +313,7 @@ unset token
|
|||
|
||||
### Use fleetctl as the new user
|
||||
|
||||
Now that the password is reset, you will need to log in again using the updated password with `fleetctl login`. You'll now be able to perform tasks using `fleetctl` as your new API-only user.
|
||||
Now that the password is reset, you will need to log in again using the updated password with `fleetctl login`. You'll now be able to perform tasks using `fleetctl` as your new API-only user.
|
||||
|
||||
### Switching users
|
||||
|
||||
|
|
@ -346,8 +346,8 @@ The user creation failed because the API-only user doesn't have the right permis
|
|||
|
||||
```
|
||||
$ fleetctl user create --email test@example.com --name "New User" --context admin
|
||||
Enter password for user:
|
||||
Enter password for user (confirm):
|
||||
Enter password for user:
|
||||
Enter password for user (confirm):
|
||||
```
|
||||
|
||||
## File carving
|
||||
|
|
@ -363,8 +363,8 @@ Given a working flagfile for connecting osquery agents to Fleet, add the followi
|
|||
```
|
||||
--disable_carver=false
|
||||
--carver_disable_function=false
|
||||
--carver_start_endpoint=/api/v1/osquery/carve/begin
|
||||
--carver_continue_endpoint=/api/v1/osquery/carve/block
|
||||
--carver_start_endpoint=/api/osquery/carve/begin
|
||||
--carver_continue_endpoint=/api/osquery/carve/block
|
||||
--carver_block_size=2097152
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -12,9 +12,9 @@ func FleetFlags(fleetURL *url.URL) []string {
|
|||
// Use uuid as the default identifier -- users can override this in their flagfile
|
||||
"--host_identifier=uuid",
|
||||
"--tls_hostname=" + hostname,
|
||||
"--enroll_tls_endpoint=" + path.Join(prefix, "/api/v1/osquery/enroll"),
|
||||
"--enroll_tls_endpoint=" + path.Join(prefix, "/api/osquery/enroll"),
|
||||
"--config_plugin=tls",
|
||||
"--config_tls_endpoint=" + path.Join(prefix, "/api/v1/osquery/config"),
|
||||
"--config_tls_endpoint=" + path.Join(prefix, "/api/osquery/config"),
|
||||
// Osquery defaults config_refresh to 0 which is probably not ideal for
|
||||
// a client connected to Fleet. Users can always override this in the
|
||||
// config they serve via Fleet.
|
||||
|
|
@ -22,16 +22,16 @@ func FleetFlags(fleetURL *url.URL) []string {
|
|||
"--disable_distributed=false",
|
||||
"--distributed_plugin=tls",
|
||||
"--distributed_tls_max_attempts=10",
|
||||
"--distributed_tls_read_endpoint=" + path.Join(prefix, "/api/v1/osquery/distributed/read"),
|
||||
"--distributed_tls_write_endpoint=" + path.Join(prefix, "/api/v1/osquery/distributed/write"),
|
||||
"--distributed_tls_read_endpoint=" + path.Join(prefix, "/api/osquery/distributed/read"),
|
||||
"--distributed_tls_write_endpoint=" + path.Join(prefix, "/api/osquery/distributed/write"),
|
||||
"--logger_plugin=tls,filesystem",
|
||||
"--logger_tls_endpoint=" + path.Join(prefix, "/api/v1/osquery/log"),
|
||||
"--logger_tls_endpoint=" + path.Join(prefix, "/api/osquery/log"),
|
||||
"--disable_carver=false",
|
||||
// carver_disable_function is separate from disable_carver as it controls the use of file
|
||||
// carving as a SQL function (eg. `SELECT carve(path) FROM processes`).
|
||||
"--carver_disable_function=false",
|
||||
"--carver_start_endpoint=" + path.Join(prefix, "/api/v1/osquery/carve/begin"),
|
||||
"--carver_continue_endpoint=" + path.Join(prefix, "/api/v1/osquery/carve/block"),
|
||||
"--carver_start_endpoint=" + path.Join(prefix, "/api/osquery/carve/begin"),
|
||||
"--carver_continue_endpoint=" + path.Join(prefix, "/api/osquery/carve/block"),
|
||||
"--carver_block_size=2000000",
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -260,7 +260,7 @@ func TestCachedTeamAgentOptions(t *testing.T) {
|
|||
"logger_tls_period": 10,
|
||||
"distributed_plugin": "tls",
|
||||
"disable_distributed": false,
|
||||
"logger_tls_endpoint": "/api/v1/osquery/log",
|
||||
"logger_tls_endpoint": "/api/osquery/log",
|
||||
"distributed_interval": 10,
|
||||
"distributed_tls_max_attempts": 3
|
||||
},
|
||||
|
|
|
|||
|
|
@ -0,0 +1,62 @@
|
|||
package tables
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func init() {
|
||||
MigrationClient.AddMigration(Up_20220404091216, Down_20220404091216)
|
||||
}
|
||||
|
||||
func Up_20220404091216(tx *sql.Tx) error {
|
||||
const selectStmt = `SELECT json_value FROM app_config_json LIMIT 1`
|
||||
|
||||
var raw json.RawMessage
|
||||
var config map[string]*json.RawMessage
|
||||
|
||||
row := tx.QueryRow(selectStmt)
|
||||
if err := row.Scan(&raw); err != nil {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return nil
|
||||
}
|
||||
return errors.Wrap(err, "select app_config_json")
|
||||
}
|
||||
if err := json.Unmarshal(raw, &config); err != nil {
|
||||
return errors.Wrap(err, "unmarshal appconfig")
|
||||
}
|
||||
|
||||
var (
|
||||
oldPath = []byte(`"/api/v1/osquery/log"`)
|
||||
newPath = []byte(`"/api/osquery/log"`)
|
||||
updated = false
|
||||
)
|
||||
if opts := config["agent_options"]; opts != nil {
|
||||
oldOpts := []byte(*opts)
|
||||
newOpts := json.RawMessage(bytes.ReplaceAll(oldOpts, oldPath, newPath))
|
||||
config["agent_options"] = &newOpts
|
||||
updated = !bytes.Equal(oldOpts, newOpts)
|
||||
}
|
||||
if !updated {
|
||||
return nil
|
||||
}
|
||||
|
||||
b, err := json.Marshal(config)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "marshal updated appconfig")
|
||||
}
|
||||
|
||||
const updateStmt = `UPDATE app_config_json SET json_value = ? WHERE id = 1`
|
||||
if _, err := tx.Exec(updateStmt, b); err != nil {
|
||||
return errors.Wrap(err, "update app_config_json")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func Down_20220404091216(tx *sql.Tx) error {
|
||||
return nil
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
package tables
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestUp_20220404091216(t *testing.T) {
|
||||
db := applyUpToPrev(t) // must be done in top-level test as the migration comes from the test name
|
||||
t.Run("no entry", func(t *testing.T) {
|
||||
_, err := db.Exec(`DELETE FROM app_config_json`)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Apply current migration.
|
||||
applyNext(t, db)
|
||||
|
||||
var count int
|
||||
err = db.Get(&count, `SELECT 1 FROM app_config_json`)
|
||||
require.Error(t, err)
|
||||
require.ErrorIs(t, err, sql.ErrNoRows)
|
||||
})
|
||||
|
||||
db = applyUpToPrev(t)
|
||||
t.Run("required update", func(t *testing.T) {
|
||||
var raw string
|
||||
err := db.Get(&raw, `SELECT json_value FROM app_config_json`)
|
||||
require.NoError(t, err)
|
||||
require.Contains(t, raw, "/api/v1/osquery/log")
|
||||
require.NotContains(t, raw, "/api/osquery/log")
|
||||
oriLen := len(raw)
|
||||
|
||||
// Apply current migration.
|
||||
applyNext(t, db)
|
||||
|
||||
err = db.Get(&raw, `SELECT json_value FROM app_config_json`)
|
||||
require.NoError(t, err)
|
||||
require.NotContains(t, raw, "/api/v1/osquery/log")
|
||||
require.Contains(t, raw, "/api/osquery/log")
|
||||
require.Len(t, raw, oriLen-3) // ensure all the rest is left as-is, only "/v1" is removed
|
||||
})
|
||||
|
||||
db = applyUpToPrev(t)
|
||||
t.Run("no update required", func(t *testing.T) {
|
||||
var raw string
|
||||
err := db.Get(&raw, `SELECT json_value FROM app_config_json`)
|
||||
require.NoError(t, err)
|
||||
oriLen := len(raw)
|
||||
raw = strings.ReplaceAll(raw, "/api/v1/osquery/log", "/api/v2/osquery/log")
|
||||
_, err = db.Exec(`UPDATE app_config_json SET json_value = ? WHERE id = 1`, raw)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Apply current migration.
|
||||
applyNext(t, db)
|
||||
|
||||
err = db.Get(&raw, `SELECT json_value FROM app_config_json`)
|
||||
require.NoError(t, err)
|
||||
require.NotContains(t, raw, "/api/osquery/log")
|
||||
require.Contains(t, raw, "/api/v2/osquery/log")
|
||||
require.Len(t, raw, oriLen) // left untouched
|
||||
})
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -123,7 +123,7 @@ type AppConfig struct {
|
|||
|
||||
// EnrichedAppConfig contains the AppConfig along with additional fleet
|
||||
// instance configuration settings as returned by the
|
||||
// "GET /api/v1/fleet/config" API endpoint (and fleetctl get config).
|
||||
// "GET /api/latest/fleet/config" API endpoint (and fleetctl get config).
|
||||
type EnrichedAppConfig struct {
|
||||
AppConfig
|
||||
|
||||
|
|
@ -235,7 +235,7 @@ func (c *AppConfig) ApplyDefaultsForNewInstalls() {
|
|||
c.SMTPSettings.SMTPVerifySSLCerts = true
|
||||
c.SMTPSettings.SMTPEnableTLS = true
|
||||
|
||||
agentOptions := json.RawMessage(`{"config": {"options": {"logger_plugin": "tls", "pack_delimiter": "/", "logger_tls_period": 10, "distributed_plugin": "tls", "disable_distributed": false, "logger_tls_endpoint": "/api/v1/osquery/log", "distributed_interval": 10, "distributed_tls_max_attempts": 3}, "decorators": {"load": ["SELECT uuid AS host_uuid FROM system_info;", "SELECT hostname AS hostname FROM system_info;"]}}, "overrides": {}}`)
|
||||
agentOptions := json.RawMessage(`{"config": {"options": {"logger_plugin": "tls", "pack_delimiter": "/", "logger_tls_period": 10, "distributed_plugin": "tls", "disable_distributed": false, "logger_tls_endpoint": "/api/osquery/log", "distributed_interval": 10, "distributed_tls_max_attempts": 3}, "decorators": {"load": ["SELECT uuid AS host_uuid FROM system_info;", "SELECT hostname AS hostname FROM system_info;"]}}, "overrides": {}}`)
|
||||
c.AgentOptions = &agentOptions
|
||||
|
||||
c.HostSettings.EnableSoftwareInventory = true
|
||||
|
|
|
|||
|
|
@ -7,14 +7,14 @@ import (
|
|||
|
||||
// ApplyAppConfig sends the application config to be applied to the Fleet instance.
|
||||
func (c *Client) ApplyAppConfig(payload interface{}) error {
|
||||
verb, path := "PATCH", "/api/v1/fleet/config"
|
||||
verb, path := "PATCH", "/api/latest/fleet/config"
|
||||
var responseBody appConfigResponse
|
||||
return c.authenticatedRequest(payload, verb, path, &responseBody)
|
||||
}
|
||||
|
||||
// GetAppConfig fetches the application config from the server API
|
||||
func (c *Client) GetAppConfig() (*fleet.EnrichedAppConfig, error) {
|
||||
verb, path := "GET", "/api/v1/fleet/config"
|
||||
verb, path := "GET", "/api/latest/fleet/config"
|
||||
var responseBody fleet.EnrichedAppConfig
|
||||
err := c.authenticatedRequest(nil, verb, path, &responseBody)
|
||||
return &responseBody, err
|
||||
|
|
@ -22,7 +22,7 @@ func (c *Client) GetAppConfig() (*fleet.EnrichedAppConfig, error) {
|
|||
|
||||
// GetEnrollSecretSpec fetches the enroll secrets stored on the server
|
||||
func (c *Client) GetEnrollSecretSpec() (*fleet.EnrollSecretSpec, error) {
|
||||
verb, path := "GET", "/api/v1/fleet/spec/enroll_secret"
|
||||
verb, path := "GET", "/api/latest/fleet/spec/enroll_secret"
|
||||
var responseBody getEnrollSecretSpecResponse
|
||||
err := c.authenticatedRequest(nil, verb, path, &responseBody)
|
||||
return responseBody.Spec, err
|
||||
|
|
@ -31,13 +31,13 @@ func (c *Client) GetEnrollSecretSpec() (*fleet.EnrollSecretSpec, error) {
|
|||
// ApplyEnrollSecretSpec applies the enroll secrets.
|
||||
func (c *Client) ApplyEnrollSecretSpec(spec *fleet.EnrollSecretSpec) error {
|
||||
req := applyEnrollSecretSpecRequest{Spec: spec}
|
||||
verb, path := "POST", "/api/v1/fleet/spec/enroll_secret"
|
||||
verb, path := "POST", "/api/latest/fleet/spec/enroll_secret"
|
||||
var responseBody applyEnrollSecretSpecResponse
|
||||
return c.authenticatedRequest(req, verb, path, &responseBody)
|
||||
}
|
||||
|
||||
func (c *Client) Version() (*version.Info, error) {
|
||||
verb, path := "GET", "/api/v1/fleet/version"
|
||||
verb, path := "GET", "/api/latest/fleet/version"
|
||||
var responseBody versionResponse
|
||||
err := c.authenticatedRequest(nil, verb, path, &responseBody)
|
||||
return responseBody.Info, err
|
||||
|
|
|
|||
|
|
@ -11,14 +11,14 @@ import (
|
|||
|
||||
// ListCarves lists the file carving sessions
|
||||
func (c *Client) ListCarves(opt fleet.CarveListOptions) ([]*fleet.CarveMetadata, error) {
|
||||
endpoint := "/api/v1/fleet/carves"
|
||||
endpoint := "/api/latest/fleet/carves"
|
||||
rawQuery := ""
|
||||
if opt.Expired {
|
||||
rawQuery = "expired=1"
|
||||
}
|
||||
response, err := c.AuthenticatedDo("GET", endpoint, rawQuery, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GET /api/v1/fleet/carves: %w", err)
|
||||
return nil, fmt.Errorf("GET /api/latest/fleet/carves: %w", err)
|
||||
}
|
||||
defer response.Body.Close()
|
||||
|
||||
|
|
@ -49,7 +49,7 @@ func (c *Client) ListCarves(opt fleet.CarveListOptions) ([]*fleet.CarveMetadata,
|
|||
}
|
||||
|
||||
func (c *Client) GetCarve(carveId int64) (*fleet.CarveMetadata, error) {
|
||||
endpoint := fmt.Sprintf("/api/v1/fleet/carves/%d", carveId)
|
||||
endpoint := fmt.Sprintf("/api/latest/fleet/carves/%d", carveId)
|
||||
response, err := c.AuthenticatedDo("GET", endpoint, "", nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GET "+endpoint+": %w", err)
|
||||
|
|
@ -77,7 +77,7 @@ func (c *Client) GetCarve(carveId int64) (*fleet.CarveMetadata, error) {
|
|||
|
||||
func (c *Client) getCarveBlock(carveId, blockId int64) ([]byte, error) {
|
||||
path := fmt.Sprintf(
|
||||
"/api/v1/fleet/carves/%d/block/%d",
|
||||
"/api/latest/fleet/carves/%d/block/%d",
|
||||
carveId,
|
||||
blockId,
|
||||
)
|
||||
|
|
@ -160,7 +160,7 @@ func (r *carveReader) Read(p []byte) (n int, err error) {
|
|||
|
||||
// DownloadCarve creates a Reader downloading a carve (by ID)
|
||||
func (c *Client) DownloadCarve(id int64) (io.Reader, error) {
|
||||
path := fmt.Sprintf("/api/v1/fleet/carves/%d", id)
|
||||
path := fmt.Sprintf("/api/latest/fleet/carves/%d", id)
|
||||
response, err := c.AuthenticatedDo("GET", path, "", nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GET %s: %w", path, err)
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import (
|
|||
|
||||
// GetHosts retrieves the list of all Hosts
|
||||
func (c *Client) GetHosts(query string) ([]HostResponse, error) {
|
||||
verb, path := "GET", "/api/v1/fleet/hosts"
|
||||
verb, path := "GET", "/api/latest/fleet/hosts"
|
||||
var responseBody listHostsResponse
|
||||
err := c.authenticatedRequestWithQuery(nil, verb, path, &responseBody, query)
|
||||
return responseBody.Hosts, err
|
||||
|
|
@ -16,14 +16,14 @@ func (c *Client) GetHosts(query string) ([]HostResponse, error) {
|
|||
// HostByIdentifier retrieves a host by the uuid, osquery_host_id, hostname, or
|
||||
// node_key.
|
||||
func (c *Client) HostByIdentifier(identifier string) (*HostDetailResponse, error) {
|
||||
verb, path := "GET", "/api/v1/fleet/hosts/identifier/"+identifier
|
||||
verb, path := "GET", "/api/latest/fleet/hosts/identifier/"+identifier
|
||||
var responseBody getHostResponse
|
||||
err := c.authenticatedRequest(nil, verb, path, &responseBody)
|
||||
return responseBody.Host, err
|
||||
}
|
||||
|
||||
func (c *Client) translateTransferHostsToIDs(hosts []string, label string, team string) ([]uint, uint, uint, error) {
|
||||
verb, path := "POST", "/api/v1/fleet/translate"
|
||||
verb, path := "POST", "/api/latest/fleet/translate"
|
||||
var responseBody translatorResponse
|
||||
|
||||
var translatePayloads []fleet.TranslatePayload
|
||||
|
|
@ -88,7 +88,7 @@ func (c *Client) TransferHosts(hosts []string, label string, status, searchQuery
|
|||
}
|
||||
|
||||
if len(hosts) != 0 {
|
||||
verb, path := "POST", "/api/v1/fleet/hosts/transfer"
|
||||
verb, path := "POST", "/api/latest/fleet/hosts/transfer"
|
||||
var responseBody addHostsToTeamResponse
|
||||
params := addHostsToTeamRequest{TeamID: ptr.Uint(teamID), HostIDs: hostIDs}
|
||||
return c.authenticatedRequest(params, verb, path, &responseBody)
|
||||
|
|
@ -99,7 +99,7 @@ func (c *Client) TransferHosts(hosts []string, label string, status, searchQuery
|
|||
labelIDPtr = &labelID
|
||||
}
|
||||
|
||||
verb, path := "POST", "/api/v1/fleet/hosts/transfer/filter"
|
||||
verb, path := "POST", "/api/latest/fleet/hosts/transfer/filter"
|
||||
var responseBody addHostsToTeamByFilterResponse
|
||||
params := addHostsToTeamByFilterRequest{TeamID: ptr.Uint(teamID), Filters: struct {
|
||||
MatchQuery string `json:"query"`
|
||||
|
|
|
|||
|
|
@ -10,14 +10,14 @@ import (
|
|||
// Fleet instance.
|
||||
func (c *Client) ApplyLabels(specs []*fleet.LabelSpec) error {
|
||||
req := applyLabelSpecsRequest{Specs: specs}
|
||||
verb, path := "POST", "/api/v1/fleet/spec/labels"
|
||||
verb, path := "POST", "/api/latest/fleet/spec/labels"
|
||||
var responseBody applyLabelSpecsResponse
|
||||
return c.authenticatedRequest(req, verb, path, &responseBody)
|
||||
}
|
||||
|
||||
// GetLabel retrieves information about a label by name
|
||||
func (c *Client) GetLabel(name string) (*fleet.LabelSpec, error) {
|
||||
verb, path := "GET", "/api/v1/fleet/spec/labels/"+url.PathEscape(name)
|
||||
verb, path := "GET", "/api/latest/fleet/spec/labels/"+url.PathEscape(name)
|
||||
var responseBody getLabelSpecResponse
|
||||
err := c.authenticatedRequest(nil, verb, path, &responseBody)
|
||||
return responseBody.Spec, err
|
||||
|
|
@ -25,7 +25,7 @@ func (c *Client) GetLabel(name string) (*fleet.LabelSpec, error) {
|
|||
|
||||
// GetLabels retrieves the list of all Labels.
|
||||
func (c *Client) GetLabels() ([]*fleet.LabelSpec, error) {
|
||||
verb, path := "GET", "/api/v1/fleet/spec/labels"
|
||||
verb, path := "GET", "/api/latest/fleet/spec/labels"
|
||||
var responseBody getLabelSpecsResponse
|
||||
err := c.authenticatedRequest(nil, verb, path, &responseBody)
|
||||
return responseBody.Specs, err
|
||||
|
|
@ -33,7 +33,7 @@ func (c *Client) GetLabels() ([]*fleet.LabelSpec, error) {
|
|||
|
||||
// DeleteLabel deletes the label with the matching name.
|
||||
func (c *Client) DeleteLabel(name string) error {
|
||||
verb, path := "DELETE", "/api/v1/fleet/labels/"+url.PathEscape(name)
|
||||
verb, path := "DELETE", "/api/latest/fleet/labels/"+url.PathEscape(name)
|
||||
var responseBody deleteLabelResponse
|
||||
return c.authenticatedRequest(nil, verb, path, &responseBody)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ func (c *Client) LiveQueryWithContext(ctx context.Context, query string, labels
|
|||
QuerySQL: query,
|
||||
Selected: distributedQueryCampaignTargetsByNames{Labels: labels, Hosts: hosts},
|
||||
}
|
||||
verb, path := "POST", "/api/v1/fleet/queries/run_by_names"
|
||||
verb, path := "POST", "/api/latest/fleet/queries/run_by_names"
|
||||
var responseBody createDistributedQueryCampaignResponse
|
||||
err := c.authenticatedRequest(req, verb, path, &responseBody)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ func TestLiveQueryWithContext(t *testing.T) {
|
|||
upgrader := websocket.Upgrader{}
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.URL.Path {
|
||||
case "/api/v1/fleet/queries/run_by_names":
|
||||
case "/api/latest/fleet/queries/run_by_names":
|
||||
resp := createDistributedQueryCampaignResponse{
|
||||
Campaign: &fleet.DistributedQueryCampaign{
|
||||
UpdateCreateTimestamps: fleet.UpdateCreateTimestamps{
|
||||
|
|
|
|||
|
|
@ -10,14 +10,14 @@ import (
|
|||
// Fleet instance.
|
||||
func (c *Client) ApplyPacks(specs []*fleet.PackSpec) error {
|
||||
req := applyPackSpecsRequest{Specs: specs}
|
||||
verb, path := "POST", "/api/v1/fleet/spec/packs"
|
||||
verb, path := "POST", "/api/latest/fleet/spec/packs"
|
||||
var responseBody applyPackSpecsResponse
|
||||
return c.authenticatedRequest(req, verb, path, &responseBody)
|
||||
}
|
||||
|
||||
// GetPack retrieves information about a pack
|
||||
func (c *Client) GetPack(name string) (*fleet.PackSpec, error) {
|
||||
verb, path := "GET", "/api/v1/fleet/spec/packs/"+url.PathEscape(name)
|
||||
verb, path := "GET", "/api/latest/fleet/spec/packs/"+url.PathEscape(name)
|
||||
var responseBody getPackSpecResponse
|
||||
err := c.authenticatedRequest(nil, verb, path, &responseBody)
|
||||
return responseBody.Spec, err
|
||||
|
|
@ -25,7 +25,7 @@ func (c *Client) GetPack(name string) (*fleet.PackSpec, error) {
|
|||
|
||||
// GetPacks retrieves the list of all Packs.
|
||||
func (c *Client) GetPacks() ([]*fleet.PackSpec, error) {
|
||||
verb, path := "GET", "/api/v1/fleet/spec/packs"
|
||||
verb, path := "GET", "/api/latest/fleet/spec/packs"
|
||||
var responseBody getPackSpecsResponse
|
||||
err := c.authenticatedRequest(nil, verb, path, &responseBody)
|
||||
return responseBody.Specs, err
|
||||
|
|
@ -33,7 +33,7 @@ func (c *Client) GetPacks() ([]*fleet.PackSpec, error) {
|
|||
|
||||
// DeletePack deletes the pack with the matching name.
|
||||
func (c *Client) DeletePack(name string) error {
|
||||
verb, path := "DELETE", "/api/v1/fleet/packs/"+url.PathEscape(name)
|
||||
verb, path := "DELETE", "/api/latest/fleet/packs/"+url.PathEscape(name)
|
||||
var responseBody deletePackResponse
|
||||
return c.authenticatedRequest(nil, verb, path, &responseBody)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ func (c *Client) CreateGlobalPolicy(name, query, description, resolution, platfo
|
|||
Resolution: resolution,
|
||||
Platform: platform,
|
||||
}
|
||||
verb, path := "POST", "/api/v1/fleet/global/policies"
|
||||
verb, path := "POST", "/api/latest/fleet/global/policies"
|
||||
var responseBody globalPolicyResponse
|
||||
return c.authenticatedRequest(req, verb, path, &responseBody)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,14 +10,14 @@ import (
|
|||
// Fleet instance.
|
||||
func (c *Client) ApplyQueries(specs []*fleet.QuerySpec) error {
|
||||
req := applyQuerySpecsRequest{Specs: specs}
|
||||
verb, path := "POST", "/api/v1/fleet/spec/queries"
|
||||
verb, path := "POST", "/api/latest/fleet/spec/queries"
|
||||
var responseBody applyQuerySpecsResponse
|
||||
return c.authenticatedRequest(req, verb, path, &responseBody)
|
||||
}
|
||||
|
||||
// GetQuery retrieves the list of all Queries.
|
||||
func (c *Client) GetQuery(name string) (*fleet.QuerySpec, error) {
|
||||
verb, path := "GET", "/api/v1/fleet/spec/queries/"+url.PathEscape(name)
|
||||
verb, path := "GET", "/api/latest/fleet/spec/queries/"+url.PathEscape(name)
|
||||
var responseBody getQuerySpecResponse
|
||||
err := c.authenticatedRequest(nil, verb, path, &responseBody)
|
||||
return responseBody.Spec, err
|
||||
|
|
@ -25,7 +25,7 @@ func (c *Client) GetQuery(name string) (*fleet.QuerySpec, error) {
|
|||
|
||||
// GetQueries retrieves the list of all Queries.
|
||||
func (c *Client) GetQueries() ([]*fleet.QuerySpec, error) {
|
||||
verb, path := "GET", "/api/v1/fleet/spec/queries"
|
||||
verb, path := "GET", "/api/latest/fleet/spec/queries"
|
||||
var responseBody getQuerySpecsResponse
|
||||
err := c.authenticatedRequest(nil, verb, path, &responseBody)
|
||||
return responseBody.Specs, err
|
||||
|
|
@ -33,7 +33,7 @@ func (c *Client) GetQueries() ([]*fleet.QuerySpec, error) {
|
|||
|
||||
// DeleteQuery deletes the query with the matching name.
|
||||
func (c *Client) DeleteQuery(name string) error {
|
||||
verb, path := "DELETE", "/api/v1/fleet/queries/"+url.PathEscape(name)
|
||||
verb, path := "DELETE", "/api/latest/fleet/queries/"+url.PathEscape(name)
|
||||
var responseBody deleteQueryResponse
|
||||
return c.authenticatedRequest(nil, verb, path, &responseBody)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,9 +14,9 @@ func (c *Client) Login(email, password string) (string, error) {
|
|||
Password: password,
|
||||
}
|
||||
|
||||
response, err := c.Do("POST", "/api/v1/fleet/login", "", params)
|
||||
response, err := c.Do("POST", "/api/latest/fleet/login", "", params)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("POST /api/v1/fleet/login: %w", err)
|
||||
return "", fmt.Errorf("POST /api/latest/fleet/login: %w", err)
|
||||
}
|
||||
defer response.Body.Close()
|
||||
|
||||
|
|
@ -47,7 +47,7 @@ func (c *Client) Login(email, password string) (string, error) {
|
|||
|
||||
// Logout attempts to logout to the current Fleet instance.
|
||||
func (c *Client) Logout() error {
|
||||
verb, path := "POST", "/api/v1/fleet/logout"
|
||||
verb, path := "POST", "/api/latest/fleet/logout"
|
||||
var responseBody logoutResponse
|
||||
return c.authenticatedRequest(nil, verb, path, &responseBody)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import (
|
|||
|
||||
// ListSoftware retrieves the software running across hosts.
|
||||
func (c *Client) ListSoftware(teamID *uint) ([]fleet.Software, error) {
|
||||
verb, path := "GET", "/api/v1/fleet/software"
|
||||
verb, path := "GET", "/api/latest/fleet/software"
|
||||
query := ""
|
||||
if teamID != nil {
|
||||
query = fmt.Sprintf("team_id=%d", *teamID)
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ func (c *Client) SearchTargets(query string, hostIDs, labelIDs []uint) (*fleet.T
|
|||
// TODO handle TeamIDs
|
||||
},
|
||||
}
|
||||
verb, path := "POST", "/api/v1/fleet/targets"
|
||||
verb, path := "POST", "/api/latest/fleet/targets"
|
||||
var responseBody searchTargetsResponse
|
||||
err := c.authenticatedRequest(req, verb, path, &responseBody)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import (
|
|||
|
||||
// ListTeams retrieves the list of teams.
|
||||
func (c *Client) ListTeams(query string) ([]fleet.Team, error) {
|
||||
verb, path := "GET", "/api/v1/fleet/teams"
|
||||
verb, path := "GET", "/api/latest/fleet/teams"
|
||||
var responseBody listTeamsResponse
|
||||
err := c.authenticatedRequestWithQuery(nil, verb, path, &responseBody, query)
|
||||
if err != nil {
|
||||
|
|
@ -19,7 +19,7 @@ func (c *Client) ListTeams(query string) ([]fleet.Team, error) {
|
|||
// Fleet instance.
|
||||
func (c *Client) ApplyTeams(specs []*fleet.TeamSpec) error {
|
||||
req := applyTeamSpecsRequest{Specs: specs}
|
||||
verb, path := "POST", "/api/v1/fleet/spec/teams"
|
||||
verb, path := "POST", "/api/latest/fleet/spec/teams"
|
||||
var responseBody applyTeamSpecsResponse
|
||||
return c.authenticatedRequest(req, verb, path, &responseBody)
|
||||
}
|
||||
|
|
@ -28,7 +28,7 @@ func (c *Client) ApplyTeams(specs []*fleet.TeamSpec) error {
|
|||
// Fleet instance.
|
||||
func (c *Client) ApplyPolicies(specs []*fleet.PolicySpec) error {
|
||||
req := applyPolicySpecsRequest{Specs: specs}
|
||||
verb, path := "POST", "/api/v1/fleet/spec/policies"
|
||||
verb, path := "POST", "/api/latest/fleet/spec/policies"
|
||||
var responseBody applyPolicySpecsResponse
|
||||
return c.authenticatedRequest(req, verb, path, &responseBody)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import (
|
|||
|
||||
// CreateUser creates a new user, skipping the invitation process.
|
||||
func (c *Client) CreateUser(p fleet.UserPayload) error {
|
||||
verb, path := "POST", "/api/v1/fleet/users/admin"
|
||||
verb, path := "POST", "/api/latest/fleet/users/admin"
|
||||
var responseBody createUserResponse
|
||||
|
||||
return c.authenticatedRequest(p, verb, path, &responseBody)
|
||||
|
|
@ -17,7 +17,7 @@ func (c *Client) CreateUser(p fleet.UserPayload) error {
|
|||
|
||||
// ListUsers retrieves the list of users.
|
||||
func (c *Client) ListUsers() ([]fleet.User, error) {
|
||||
verb, path := "GET", "/api/v1/fleet/users"
|
||||
verb, path := "GET", "/api/latest/fleet/users"
|
||||
var responseBody listUsersResponse
|
||||
|
||||
err := c.authenticatedRequest(nil, verb, path, &responseBody)
|
||||
|
|
@ -30,13 +30,13 @@ func (c *Client) ListUsers() ([]fleet.User, error) {
|
|||
// ApplyUsersRoleSecretSpec applies the global and team roles for users.
|
||||
func (c *Client) ApplyUsersRoleSecretSpec(spec *fleet.UsersRoleSpec) error {
|
||||
req := applyUserRoleSpecsRequest{Spec: spec}
|
||||
verb, path := "POST", "/api/v1/fleet/users/roles/spec"
|
||||
verb, path := "POST", "/api/latest/fleet/users/roles/spec"
|
||||
var responseBody applyUserRoleSpecsResponse
|
||||
return c.authenticatedRequest(req, verb, path, &responseBody)
|
||||
}
|
||||
|
||||
func (c *Client) userIdFromEmail(email string) (uint, error) {
|
||||
verb, path := "POST", "/api/v1/fleet/translate"
|
||||
verb, path := "POST", "/api/latest/fleet/translate"
|
||||
var responseBody translatorResponse
|
||||
|
||||
params := translatorRequest{List: []fleet.TranslatePayload{
|
||||
|
|
@ -63,7 +63,7 @@ func (c *Client) DeleteUser(email string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
verb, path := "DELETE", fmt.Sprintf("/api/v1/fleet/users/%d", userID)
|
||||
verb, path := "DELETE", fmt.Sprintf("/api/latest/fleet/users/%d", userID)
|
||||
var responseBody deleteUserResponse
|
||||
return c.authenticatedRequest(nil, verb, path, &responseBody)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -102,6 +102,7 @@ func MakeHandler(svc fleet.Service, config config.FleetConfig, logger kitlog.Log
|
|||
attachFleetAPIRoutes(r, svc, config, logger, limitStore, fleetAPIOptions)
|
||||
|
||||
// Results endpoint is handled different due to websockets use
|
||||
|
||||
// TODO: this would not work once v1 is deprecated - note that the handler too uses the /v1/ path
|
||||
// and this routes on path prefix, not exact path (unlike the authendpointer struct).
|
||||
r.PathPrefix("/api/v1/fleet/results/").
|
||||
|
|
@ -212,8 +213,11 @@ var (
|
|||
func attachFleetAPIRoutes(r *mux.Router, svc fleet.Service, config config.FleetConfig,
|
||||
logger kitlog.Logger, limitStore throttled.GCRAStore, opts []kithttp.ServerOption,
|
||||
) {
|
||||
|
||||
apiVersions := []string{"v1", "2022-04"}
|
||||
|
||||
// user-authenticated endpoints
|
||||
ue := newUserAuthenticatedEndpointer(svc, opts, r, "v1")
|
||||
ue := newUserAuthenticatedEndpointer(svc, opts, r, apiVersions...)
|
||||
|
||||
ue.GET("/api/_version_/fleet/me", meEndpoint, nil)
|
||||
ue.GET("/api/_version_/fleet/sessions/{id:[0-9]+}", getInfoAboutSessionEndpoint, getInfoAboutSessionRequest{})
|
||||
|
|
@ -241,12 +245,6 @@ func attachFleetAPIRoutes(r *mux.Router, svc fleet.Service, config config.FleetC
|
|||
ue.DELETE("/api/_version_/fleet/teams/{id:[0-9]+}/users", deleteTeamUsersEndpoint, modifyTeamUsersRequest{})
|
||||
ue.GET("/api/_version_/fleet/teams/{id:[0-9]+}/secrets", teamEnrollSecretsEndpoint, teamEnrollSecretsRequest{})
|
||||
|
||||
// Alias /api/_version_/fleet/team/ -> /api/_version_/fleet/teams/
|
||||
ue.WithAltPaths("/api/_version_/fleet/team/{team_id}/schedule").GET("/api/_version_/fleet/teams/{team_id}/schedule", getTeamScheduleEndpoint, getTeamScheduleRequest{})
|
||||
ue.WithAltPaths("/api/_version_/fleet/team/{team_id}/schedule").POST("/api/_version_/fleet/teams/{team_id}/schedule", teamScheduleQueryEndpoint, teamScheduleQueryRequest{})
|
||||
ue.WithAltPaths("/api/_version_/fleet/team/{team_id}/schedule/{scheduled_query_id}").PATCH("/api/_version_/fleet/teams/{team_id}/schedule/{scheduled_query_id}", modifyTeamScheduleEndpoint, modifyTeamScheduleRequest{})
|
||||
ue.WithAltPaths("/api/_version_/fleet/team/{team_id}/schedule/{scheduled_query_id}").DELETE("/api/_version_/fleet/teams/{team_id}/schedule/{scheduled_query_id}", deleteTeamScheduleEndpoint, deleteTeamScheduleRequest{})
|
||||
|
||||
ue.GET("/api/_version_/fleet/users", listUsersEndpoint, listUsersRequest{})
|
||||
ue.POST("/api/_version_/fleet/users/admin", createUserEndpoint, createUserRequest{})
|
||||
ue.GET("/api/_version_/fleet/users/{id:[0-9]+}", getUserEndpoint, getUserRequest{})
|
||||
|
|
@ -265,17 +263,26 @@ func attachFleetAPIRoutes(r *mux.Router, svc fleet.Service, config config.FleetC
|
|||
ue.DELETE("/api/_version_/fleet/invites/{id:[0-9]+}", deleteInviteEndpoint, deleteInviteRequest{})
|
||||
ue.PATCH("/api/_version_/fleet/invites/{id:[0-9]+}", updateInviteEndpoint, updateInviteRequest{})
|
||||
|
||||
ue.POST("/api/_version_/fleet/global/policies", globalPolicyEndpoint, globalPolicyRequest{})
|
||||
ue.GET("/api/_version_/fleet/global/policies", listGlobalPoliciesEndpoint, nil)
|
||||
ue.GET("/api/_version_/fleet/global/policies/{policy_id}", getPolicyByIDEndpoint, getPolicyByIDRequest{})
|
||||
ue.POST("/api/_version_/fleet/global/policies/delete", deleteGlobalPoliciesEndpoint, deleteGlobalPoliciesRequest{})
|
||||
ue.PATCH("/api/_version_/fleet/global/policies/{policy_id}", modifyGlobalPolicyEndpoint, modifyGlobalPolicyRequest{})
|
||||
ue.EndingAtVersion("v1").POST("/api/_version_/fleet/global/policies", globalPolicyEndpoint, globalPolicyRequest{})
|
||||
ue.StartingAtVersion("2022-04").POST("/api/_version_/fleet/policies", globalPolicyEndpoint, globalPolicyRequest{})
|
||||
ue.EndingAtVersion("v1").GET("/api/_version_/fleet/global/policies", listGlobalPoliciesEndpoint, nil)
|
||||
ue.StartingAtVersion("2022-04").GET("/api/_version_/fleet/policies", listGlobalPoliciesEndpoint, nil)
|
||||
ue.EndingAtVersion("v1").GET("/api/_version_/fleet/global/policies/{policy_id}", getPolicyByIDEndpoint, getPolicyByIDRequest{})
|
||||
ue.StartingAtVersion("2022-04").GET("/api/_version_/fleet/policies/{policy_id}", getPolicyByIDEndpoint, getPolicyByIDRequest{})
|
||||
ue.EndingAtVersion("v1").POST("/api/_version_/fleet/global/policies/delete", deleteGlobalPoliciesEndpoint, deleteGlobalPoliciesRequest{})
|
||||
ue.StartingAtVersion("2022-04").POST("/api/_version_/fleet/policies/delete", deleteGlobalPoliciesEndpoint, deleteGlobalPoliciesRequest{})
|
||||
ue.EndingAtVersion("v1").PATCH("/api/_version_/fleet/global/policies/{policy_id}", modifyGlobalPolicyEndpoint, modifyGlobalPolicyRequest{})
|
||||
ue.StartingAtVersion("2022-04").PATCH("/api/_version_/fleet/policies/{policy_id}", modifyGlobalPolicyEndpoint, modifyGlobalPolicyRequest{})
|
||||
|
||||
// Alias /api/_version_/fleet/team/ -> /api/_version_/fleet/teams/
|
||||
ue.WithAltPaths("/api/_version_/fleet/team/{team_id}/policies").POST("/api/_version_/fleet/teams/{team_id}/policies", teamPolicyEndpoint, teamPolicyRequest{})
|
||||
ue.WithAltPaths("/api/_version_/fleet/team/{team_id}/policies").GET("/api/_version_/fleet/teams/{team_id}/policies", listTeamPoliciesEndpoint, listTeamPoliciesRequest{})
|
||||
ue.WithAltPaths("/api/_version_/fleet/team/{team_id}/policies/{policy_id}").GET("/api/_version_/fleet/teams/{team_id}/policies/{policy_id}", getTeamPolicyByIDEndpoint, getTeamPolicyByIDRequest{})
|
||||
ue.WithAltPaths("/api/_version_/fleet/team/{team_id}/policies/delete").POST("/api/_version_/fleet/teams/{team_id}/policies/delete", deleteTeamPoliciesEndpoint, deleteTeamPoliciesRequest{})
|
||||
ue.WithAltPaths("/api/_version_/fleet/team/{team_id}/policies").
|
||||
POST("/api/_version_/fleet/teams/{team_id}/policies", teamPolicyEndpoint, teamPolicyRequest{})
|
||||
ue.WithAltPaths("/api/_version_/fleet/team/{team_id}/policies").
|
||||
GET("/api/_version_/fleet/teams/{team_id}/policies", listTeamPoliciesEndpoint, listTeamPoliciesRequest{})
|
||||
ue.WithAltPaths("/api/_version_/fleet/team/{team_id}/policies/{policy_id}").
|
||||
GET("/api/_version_/fleet/teams/{team_id}/policies/{policy_id}", getTeamPolicyByIDEndpoint, getTeamPolicyByIDRequest{})
|
||||
ue.WithAltPaths("/api/_version_/fleet/team/{team_id}/policies/delete").
|
||||
POST("/api/_version_/fleet/teams/{team_id}/policies/delete", deleteTeamPoliciesEndpoint, deleteTeamPoliciesRequest{})
|
||||
ue.PATCH("/api/_version_/fleet/teams/{team_id}/policies/{policy_id}", modifyTeamPolicyEndpoint, modifyTeamPolicyRequest{})
|
||||
ue.POST("/api/_version_/fleet/spec/policies", applyPolicySpecsEndpoint, applyPolicySpecsRequest{})
|
||||
|
||||
|
|
@ -290,12 +297,6 @@ func attachFleetAPIRoutes(r *mux.Router, svc fleet.Service, config config.FleetC
|
|||
ue.GET("/api/_version_/fleet/spec/queries", getQuerySpecsEndpoint, nil)
|
||||
ue.GET("/api/_version_/fleet/spec/queries/{name}", getQuerySpecEndpoint, getGenericSpecRequest{})
|
||||
|
||||
ue.GET("/api/_version_/fleet/packs/{id:[0-9]+}/scheduled", getScheduledQueriesInPackEndpoint, getScheduledQueriesInPackRequest{})
|
||||
ue.POST("/api/_version_/fleet/schedule", scheduleQueryEndpoint, scheduleQueryRequest{})
|
||||
ue.GET("/api/_version_/fleet/schedule/{id:[0-9]+}", getScheduledQueryEndpoint, getScheduledQueryRequest{})
|
||||
ue.PATCH("/api/_version_/fleet/schedule/{id:[0-9]+}", modifyScheduledQueryEndpoint, modifyScheduledQueryRequest{})
|
||||
ue.DELETE("/api/_version_/fleet/schedule/{id:[0-9]+}", deleteScheduledQueryEndpoint, deleteScheduledQueryRequest{})
|
||||
|
||||
ue.GET("/api/_version_/fleet/packs/{id:[0-9]+}", getPackEndpoint, getPackRequest{})
|
||||
ue.POST("/api/_version_/fleet/packs", createPackEndpoint, createPackRequest{})
|
||||
ue.PATCH("/api/_version_/fleet/packs/{id:[0-9]+}", modifyPackEndpoint, modifyPackRequest{})
|
||||
|
|
@ -340,10 +341,33 @@ func attachFleetAPIRoutes(r *mux.Router, svc fleet.Service, config config.FleetC
|
|||
|
||||
ue.GET("/api/_version_/fleet/activities", listActivitiesEndpoint, listActivitiesRequest{})
|
||||
|
||||
ue.GET("/api/_version_/fleet/global/schedule", getGlobalScheduleEndpoint, getGlobalScheduleRequest{})
|
||||
ue.POST("/api/_version_/fleet/global/schedule", globalScheduleQueryEndpoint, globalScheduleQueryRequest{})
|
||||
ue.PATCH("/api/_version_/fleet/global/schedule/{id:[0-9]+}", modifyGlobalScheduleEndpoint, modifyGlobalScheduleRequest{})
|
||||
ue.DELETE("/api/_version_/fleet/global/schedule/{id:[0-9]+}", deleteGlobalScheduleEndpoint, deleteGlobalScheduleRequest{})
|
||||
ue.GET("/api/_version_/fleet/packs/{id:[0-9]+}/scheduled", getScheduledQueriesInPackEndpoint, getScheduledQueriesInPackRequest{})
|
||||
ue.EndingAtVersion("v1").POST("/api/_version_/fleet/schedule", scheduleQueryEndpoint, scheduleQueryRequest{})
|
||||
ue.StartingAtVersion("2022-04").POST("/api/_version_/fleet/packs/schedule", scheduleQueryEndpoint, scheduleQueryRequest{})
|
||||
ue.GET("/api/_version_/fleet/schedule/{id:[0-9]+}", getScheduledQueryEndpoint, getScheduledQueryRequest{})
|
||||
ue.EndingAtVersion("v1").PATCH("/api/_version_/fleet/schedule/{id:[0-9]+}", modifyScheduledQueryEndpoint, modifyScheduledQueryRequest{})
|
||||
ue.StartingAtVersion("2022-04").PATCH("/api/_version_/fleet/packs/schedule/{id:[0-9]+}", modifyScheduledQueryEndpoint, modifyScheduledQueryRequest{})
|
||||
ue.EndingAtVersion("v1").DELETE("/api/_version_/fleet/schedule/{id:[0-9]+}", deleteScheduledQueryEndpoint, deleteScheduledQueryRequest{})
|
||||
ue.StartingAtVersion("2022-04").DELETE("/api/_version_/fleet/packs/schedule/{id:[0-9]+}", deleteScheduledQueryEndpoint, deleteScheduledQueryRequest{})
|
||||
|
||||
ue.EndingAtVersion("v1").GET("/api/_version_/fleet/global/schedule", getGlobalScheduleEndpoint, getGlobalScheduleRequest{})
|
||||
ue.StartingAtVersion("2022-04").GET("/api/_version_/fleet/schedule", getGlobalScheduleEndpoint, getGlobalScheduleRequest{})
|
||||
ue.EndingAtVersion("v1").POST("/api/_version_/fleet/global/schedule", globalScheduleQueryEndpoint, globalScheduleQueryRequest{})
|
||||
ue.StartingAtVersion("2022-04").POST("/api/_version_/fleet/schedule", globalScheduleQueryEndpoint, globalScheduleQueryRequest{})
|
||||
ue.EndingAtVersion("v1").PATCH("/api/_version_/fleet/global/schedule/{id:[0-9]+}", modifyGlobalScheduleEndpoint, modifyGlobalScheduleRequest{})
|
||||
ue.StartingAtVersion("2022-04").PATCH("/api/_version_/fleet/schedule/{id:[0-9]+}", modifyGlobalScheduleEndpoint, modifyGlobalScheduleRequest{})
|
||||
ue.EndingAtVersion("v1").DELETE("/api/_version_/fleet/global/schedule/{id:[0-9]+}", deleteGlobalScheduleEndpoint, deleteGlobalScheduleRequest{})
|
||||
ue.StartingAtVersion("2022-04").DELETE("/api/_version_/fleet/schedule/{id:[0-9]+}", deleteGlobalScheduleEndpoint, deleteGlobalScheduleRequest{})
|
||||
|
||||
// Alias /api/_version_/fleet/team/ -> /api/_version_/fleet/teams/
|
||||
ue.WithAltPaths("/api/_version_/fleet/team/{team_id}/schedule").
|
||||
GET("/api/_version_/fleet/teams/{team_id}/schedule", getTeamScheduleEndpoint, getTeamScheduleRequest{})
|
||||
ue.WithAltPaths("/api/_version_/fleet/team/{team_id}/schedule").
|
||||
POST("/api/_version_/fleet/teams/{team_id}/schedule", teamScheduleQueryEndpoint, teamScheduleQueryRequest{})
|
||||
ue.WithAltPaths("/api/_version_/fleet/team/{team_id}/schedule/{scheduled_query_id}").
|
||||
PATCH("/api/_version_/fleet/teams/{team_id}/schedule/{scheduled_query_id}", modifyTeamScheduleEndpoint, modifyTeamScheduleRequest{})
|
||||
ue.WithAltPaths("/api/_version_/fleet/team/{team_id}/schedule/{scheduled_query_id}").
|
||||
DELETE("/api/_version_/fleet/teams/{team_id}/schedule/{scheduled_query_id}", deleteTeamScheduleEndpoint, deleteTeamScheduleRequest{})
|
||||
|
||||
ue.GET("/api/_version_/fleet/carves", listCarvesEndpoint, listCarvesRequest{})
|
||||
ue.GET("/api/_version_/fleet/carves/{id:[0-9]+}", getCarveEndpoint, getCarveRequest{})
|
||||
|
|
@ -356,30 +380,45 @@ func attachFleetAPIRoutes(r *mux.Router, svc fleet.Service, config config.FleetC
|
|||
ue.GET("/api/_version_/fleet/status/live_query", statusLiveQueryEndpoint, nil)
|
||||
|
||||
// device-authenticated endpoints
|
||||
de := newDeviceAuthenticatedEndpointer(svc, logger, opts, r, "v1")
|
||||
de := newDeviceAuthenticatedEndpointer(svc, logger, opts, r, apiVersions...)
|
||||
de.GET("/api/_version_/fleet/device/{token}", getDeviceHostEndpoint, getDeviceHostRequest{})
|
||||
de.POST("/api/_version_/fleet/device/{token}/refetch", refetchDeviceHostEndpoint, refetchDeviceHostRequest{})
|
||||
de.GET("/api/_version_/fleet/device/{token}/device_mapping", listDeviceHostDeviceMappingEndpoint, listDeviceHostDeviceMappingRequest{})
|
||||
de.GET("/api/_version_/fleet/device/{token}/macadmins", getDeviceMacadminsDataEndpoint, getDeviceMacadminsDataRequest{})
|
||||
|
||||
// host-authenticated endpoints
|
||||
he := newHostAuthenticatedEndpointer(svc, logger, opts, r, "v1")
|
||||
he.POST("/api/_version_/osquery/config", getClientConfigEndpoint, getClientConfigRequest{})
|
||||
he.POST("/api/_version_/osquery/distributed/read", getDistributedQueriesEndpoint, getDistributedQueriesRequest{})
|
||||
he.POST("/api/_version_/osquery/distributed/write", submitDistributedQueryResultsEndpoint, submitDistributedQueryResultsRequestShim{})
|
||||
he.POST("/api/_version_/osquery/carve/begin", carveBeginEndpoint, carveBeginRequest{})
|
||||
he.POST("/api/_version_/osquery/log", submitLogsEndpoint, submitLogsRequest{})
|
||||
he := newHostAuthenticatedEndpointer(svc, logger, opts, r, apiVersions...)
|
||||
|
||||
// Note that the /osquery/ endpoints are *not* versioned, i.e. there is no
|
||||
// `_version_` placeholder in the path. This is deliberate, see
|
||||
// https://github.com/fleetdm/fleet/pull/4731#discussion_r838931732 For now
|
||||
// we add an alias to `/api/v1/osquery` so that it is backwards compatible,
|
||||
// but even that `v1` is *not* part of the standard versioning, it will still
|
||||
// work even after we remove support for the `v1` version for the rest of the
|
||||
// API. This allows us to deprecate osquery endpoints separately.
|
||||
he.WithAltPaths("/api/v1/osquery/config").
|
||||
POST("/api/osquery/config", getClientConfigEndpoint, getClientConfigRequest{})
|
||||
he.WithAltPaths("/api/v1/osquery/distributed/read").
|
||||
POST("/api/osquery/distributed/read", getDistributedQueriesEndpoint, getDistributedQueriesRequest{})
|
||||
he.WithAltPaths("/api/v1/osquery/distributed/write").
|
||||
POST("/api/osquery/distributed/write", submitDistributedQueryResultsEndpoint, submitDistributedQueryResultsRequestShim{})
|
||||
he.WithAltPaths("/api/v1/osquery/carve/begin").
|
||||
POST("/api/osquery/carve/begin", carveBeginEndpoint, carveBeginRequest{})
|
||||
he.WithAltPaths("/api/v1/osquery/log").
|
||||
POST("/api/osquery/log", submitLogsEndpoint, submitLogsRequest{})
|
||||
|
||||
// unauthenticated endpoints - most of those are either login-related,
|
||||
// invite-related or host-enrolling. So they typically do some kind of
|
||||
// one-time authentication by verifying that a valid secret token is provided
|
||||
// with the request.
|
||||
ne := newNoAuthEndpointer(svc, opts, r, "v1")
|
||||
ne.POST("/api/_version_/osquery/enroll", enrollAgentEndpoint, enrollAgentRequest{})
|
||||
ne := newNoAuthEndpointer(svc, opts, r, apiVersions...)
|
||||
ne.WithAltPaths("/api/v1/osquery/enroll").
|
||||
POST("/api/osquery/enroll", enrollAgentEndpoint, enrollAgentRequest{})
|
||||
|
||||
// For some reason osquery does not provide a node key with the block data.
|
||||
// Instead the carve session ID should be verified in the service method.
|
||||
ne.POST("/api/_version_/osquery/carve/block", carveBlockEndpoint, carveBlockRequest{})
|
||||
// For some reason osquery does not provide a node key with the block data.
|
||||
// Instead the carve session ID should be verified in the service method.
|
||||
ne.WithAltPaths("/api/v1/osquery/carve/block").
|
||||
POST("/api/osquery/carve/block", carveBlockEndpoint, carveBlockRequest{})
|
||||
|
||||
ne.POST("/api/_version_/fleet/perform_required_password_reset", performRequiredPasswordResetEndpoint, performRequiredPasswordResetRequest{})
|
||||
ne.POST("/api/_version_/fleet/users", createUserFromInviteEndpoint, createUserRequest{})
|
||||
|
|
|
|||
|
|
@ -43,21 +43,10 @@ func TestAPIRoutesConflicts(t *testing.T) {
|
|||
// is used to name the sub-test for that route.
|
||||
status := 200
|
||||
err := router.Walk(func(route *mux.Route, router *mux.Router, ancestores []*mux.Route) error {
|
||||
routeStatus := status
|
||||
_, path, err := mockRouteHandler(route, status)
|
||||
if path == "" || err != nil { // failure or no method set
|
||||
return err
|
||||
}
|
||||
path = reSimpleVar.ReplaceAllString(path, "$1")
|
||||
// for now at least, the only times we use regexp-constrained vars is
|
||||
// for numeric arguments.
|
||||
path = reNumVar.ReplaceAllStringFunc(path, func(s string) string {
|
||||
if strings.Index(s, "fleetversion") != -1 {
|
||||
parts := strings.Split(strings.TrimPrefix(s, "{fleetversion:(?:"), "|")
|
||||
return strings.TrimSuffix(parts[0], ")}")
|
||||
}
|
||||
return "1"
|
||||
})
|
||||
|
||||
meths, _ := route.GetMethods()
|
||||
for _, meth := range meths {
|
||||
|
|
@ -65,7 +54,7 @@ func TestAPIRoutesConflicts(t *testing.T) {
|
|||
name: route.GetName(),
|
||||
path: path,
|
||||
verb: meth,
|
||||
want: routeStatus,
|
||||
want: status,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -312,11 +301,13 @@ func mockRouteHandler(route *mux.Route, status int) (verb, path string, err erro
|
|||
|
||||
path = reSimpleVar.ReplaceAllString(path, "$1")
|
||||
// for now at least, the only times we use regexp-constrained vars is
|
||||
// for numeric arguments.
|
||||
// for numeric arguments or the fleetversion specifier.
|
||||
path = reNumVar.ReplaceAllStringFunc(path, func(s string) string {
|
||||
if strings.Index(s, "fleetversion") != -1 {
|
||||
if strings.Contains(s, "fleetversion") {
|
||||
parts := strings.Split(strings.TrimPrefix(s, "{fleetversion:(?:"), "|")
|
||||
return strings.TrimSuffix(parts[0], ")}")
|
||||
// test with "latest" if not deprecated, or last supported version for that route
|
||||
// (for either case, this will be in the last part)
|
||||
return strings.TrimSuffix(parts[len(parts)-1], ")}")
|
||||
}
|
||||
return "1"
|
||||
})
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ func TestLogin(t *testing.T) {
|
|||
assert.Nil(t, err)
|
||||
|
||||
requestBody := io.NopCloser(bytes.NewBuffer(j))
|
||||
resp, err := http.Post(server.URL+"/api/v1/fleet/login", "application/json", requestBody)
|
||||
resp, err := http.Post(server.URL+"/api/latest/fleet/login", "application/json", requestBody)
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, tt.status, resp.StatusCode)
|
||||
|
||||
|
|
@ -92,7 +92,7 @@ func TestLogin(t *testing.T) {
|
|||
assert.NotEqual(t, "", sessions[0].Key)
|
||||
|
||||
// test logout
|
||||
req, _ := http.NewRequest("POST", server.URL+"/api/v1/fleet/logout", nil)
|
||||
req, _ := http.NewRequest("POST", server.URL+"/api/latest/fleet/logout", nil)
|
||||
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", jsn.Token))
|
||||
client := fleethttp.NewClient()
|
||||
resp, err = client.Do(req)
|
||||
|
|
@ -186,7 +186,7 @@ func getTestAdminToken(t *testing.T, server *httptest.Server) string {
|
|||
assert.Nil(t, err)
|
||||
|
||||
requestBody := io.NopCloser(bytes.NewBuffer(j))
|
||||
resp, err := http.Post(server.URL+"/api/v1/fleet/login", "application/json", requestBody)
|
||||
resp, err := http.Post(server.URL+"/api/latest/fleet/login", "application/json", requestBody)
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
|
||||
|
|
@ -204,7 +204,7 @@ func getTestAdminToken(t *testing.T, server *httptest.Server) string {
|
|||
func TestNoHeaderErrorsDifferently(t *testing.T) {
|
||||
_, _, server := setupAuthTest(t)
|
||||
|
||||
req, _ := http.NewRequest("GET", server.URL+"/api/v1/fleet/users", nil)
|
||||
req, _ := http.NewRequest("GET", server.URL+"/api/latest/fleet/users", nil)
|
||||
client := fleethttp.NewClient()
|
||||
resp, err := client.Do(req)
|
||||
require.Nil(t, err)
|
||||
|
|
@ -223,7 +223,7 @@ func TestNoHeaderErrorsDifferently(t *testing.T) {
|
|||
}
|
||||
`, string(bodyBytes))
|
||||
|
||||
req, _ = http.NewRequest("GET", server.URL+"/api/v1/fleet/users", nil)
|
||||
req, _ = http.NewRequest("GET", server.URL+"/api/latest/fleet/users", nil)
|
||||
req.Header.Add("Authorization", "Bearer AAAA")
|
||||
resp, err = client.Do(req)
|
||||
require.Nil(t, err)
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -50,7 +50,7 @@ func (s *integrationDSTestSuite) TestLicenseExpiration() {
|
|||
ts.s = &s.Suite
|
||||
ts.token = ts.getTestAdminToken()
|
||||
|
||||
resp := ts.Do("GET", "/api/v1/fleet/config", nil, http.StatusOK)
|
||||
resp := ts.Do("GET", "/api/latest/fleet/config", nil, http.StatusOK)
|
||||
if tt.shouldHaveHeader {
|
||||
require.Equal(t, fleet.HeaderLicenseValueExpired, resp.Header.Get(fleet.HeaderLicenseKey))
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -47,12 +47,12 @@ func (s *integrationEnterpriseTestSuite) TestTeamSpecs() {
|
|||
Description: "desc team1",
|
||||
}
|
||||
|
||||
s.Do("POST", "/api/v1/fleet/teams", team, http.StatusOK)
|
||||
s.Do("POST", "/api/latest/fleet/teams", team, http.StatusOK)
|
||||
|
||||
// updates a team
|
||||
agentOpts := json.RawMessage(`{"config": {"foo": "bar"}, "overrides": {"platforms": {"darwin": {"foo": "override"}}}}`)
|
||||
teamSpecs := applyTeamSpecsRequest{Specs: []*fleet.TeamSpec{{Name: teamName, AgentOptions: &agentOpts}}}
|
||||
s.Do("POST", "/api/v1/fleet/spec/teams", teamSpecs, http.StatusOK)
|
||||
s.Do("POST", "/api/latest/fleet/spec/teams", teamSpecs, http.StatusOK)
|
||||
|
||||
team, err := s.ds.TeamByName(context.Background(), teamName)
|
||||
require.NoError(t, err)
|
||||
|
|
@ -69,7 +69,7 @@ func (s *integrationEnterpriseTestSuite) TestTeamSpecs() {
|
|||
require.True(t, len(teams) >= 1)
|
||||
|
||||
teamSpecs = applyTeamSpecsRequest{Specs: []*fleet.TeamSpec{{Name: "team2"}}}
|
||||
s.Do("POST", "/api/v1/fleet/spec/teams", teamSpecs, http.StatusOK)
|
||||
s.Do("POST", "/api/latest/fleet/spec/teams", teamSpecs, http.StatusOK)
|
||||
|
||||
teams, err = s.ds.ListTeams(context.Background(), fleet.TeamFilter{User: user}, fleet.ListOptions{})
|
||||
require.NoError(t, err)
|
||||
|
|
@ -78,14 +78,14 @@ func (s *integrationEnterpriseTestSuite) TestTeamSpecs() {
|
|||
team, err = s.ds.TeamByName(context.Background(), "team2")
|
||||
require.NoError(t, err)
|
||||
|
||||
defaultOpts := `{"config": {"options": {"logger_plugin": "tls", "pack_delimiter": "/", "logger_tls_period": 10, "distributed_plugin": "tls", "disable_distributed": false, "logger_tls_endpoint": "/api/v1/osquery/log", "distributed_interval": 10, "distributed_tls_max_attempts": 3}, "decorators": {"load": ["SELECT uuid AS host_uuid FROM system_info;", "SELECT hostname AS hostname FROM system_info;"]}}, "overrides": {}}`
|
||||
defaultOpts := `{"config": {"options": {"logger_plugin": "tls", "pack_delimiter": "/", "logger_tls_period": 10, "distributed_plugin": "tls", "disable_distributed": false, "logger_tls_endpoint": "/api/osquery/log", "distributed_interval": 10, "distributed_tls_max_attempts": 3}, "decorators": {"load": ["SELECT uuid AS host_uuid FROM system_info;", "SELECT hostname AS hostname FROM system_info;"]}}, "overrides": {}}`
|
||||
assert.Len(t, team.Secrets, 0)
|
||||
require.NotNil(t, team.Config.AgentOptions)
|
||||
require.JSONEq(t, defaultOpts, string(*team.Config.AgentOptions))
|
||||
|
||||
// updates secrets
|
||||
teamSpecs = applyTeamSpecsRequest{Specs: []*fleet.TeamSpec{{Name: "team2", Secrets: []fleet.EnrollSecret{{Secret: "ABC"}}}}}
|
||||
s.Do("POST", "/api/v1/fleet/spec/teams", teamSpecs, http.StatusOK)
|
||||
s.Do("POST", "/api/latest/fleet/spec/teams", teamSpecs, http.StatusOK)
|
||||
|
||||
team, err = s.ds.TeamByName(context.Background(), "team2")
|
||||
require.NoError(t, err)
|
||||
|
|
@ -105,7 +105,7 @@ func (s *integrationEnterpriseTestSuite) TestTeamSchedule() {
|
|||
require.NoError(t, err)
|
||||
|
||||
ts := getTeamScheduleResponse{}
|
||||
s.DoJSON("GET", fmt.Sprintf("/api/v1/fleet/teams/%d/schedule", team1.ID), nil, http.StatusOK, &ts)
|
||||
s.DoJSON("GET", fmt.Sprintf("/api/latest/fleet/teams/%d/schedule", team1.ID), nil, http.StatusOK, &ts)
|
||||
require.Len(t, ts.Scheduled, 0)
|
||||
|
||||
qr, err := s.ds.NewQuery(
|
||||
|
|
@ -116,10 +116,10 @@ func (s *integrationEnterpriseTestSuite) TestTeamSchedule() {
|
|||
|
||||
gsParams := teamScheduleQueryRequest{ScheduledQueryPayload: fleet.ScheduledQueryPayload{QueryID: &qr.ID, Interval: ptr.Uint(42)}}
|
||||
r := teamScheduleQueryResponse{}
|
||||
s.DoJSON("POST", fmt.Sprintf("/api/v1/fleet/teams/%d/schedule", team1.ID), gsParams, http.StatusOK, &r)
|
||||
s.DoJSON("POST", fmt.Sprintf("/api/latest/fleet/teams/%d/schedule", team1.ID), gsParams, http.StatusOK, &r)
|
||||
|
||||
ts = getTeamScheduleResponse{}
|
||||
s.DoJSON("GET", fmt.Sprintf("/api/v1/fleet/teams/%d/schedule", team1.ID), nil, http.StatusOK, &ts)
|
||||
s.DoJSON("GET", fmt.Sprintf("/api/latest/fleet/teams/%d/schedule", team1.ID), nil, http.StatusOK, &ts)
|
||||
require.Len(t, ts.Scheduled, 1)
|
||||
assert.Equal(t, uint(42), ts.Scheduled[0].Interval)
|
||||
assert.Equal(t, "TestQueryTeamPolicy", ts.Scheduled[0].Name)
|
||||
|
|
@ -128,21 +128,21 @@ func (s *integrationEnterpriseTestSuite) TestTeamSchedule() {
|
|||
|
||||
modifyResp := modifyTeamScheduleResponse{}
|
||||
modifyParams := modifyTeamScheduleRequest{ScheduledQueryPayload: fleet.ScheduledQueryPayload{Interval: ptr.Uint(55)}}
|
||||
s.DoJSON("PATCH", fmt.Sprintf("/api/v1/fleet/teams/%d/schedule/%d", team1.ID, id), modifyParams, http.StatusOK, &modifyResp)
|
||||
s.DoJSON("PATCH", fmt.Sprintf("/api/latest/fleet/teams/%d/schedule/%d", team1.ID, id), modifyParams, http.StatusOK, &modifyResp)
|
||||
|
||||
// just to satisfy my paranoia, wanted to make sure the contents of the json would work
|
||||
s.DoRaw("PATCH", fmt.Sprintf("/api/v1/fleet/teams/%d/schedule/%d", team1.ID, id), []byte(`{"interval": 77}`), http.StatusOK)
|
||||
s.DoRaw("PATCH", fmt.Sprintf("/api/latest/fleet/teams/%d/schedule/%d", team1.ID, id), []byte(`{"interval": 77}`), http.StatusOK)
|
||||
|
||||
ts = getTeamScheduleResponse{}
|
||||
s.DoJSON("GET", fmt.Sprintf("/api/v1/fleet/teams/%d/schedule", team1.ID), nil, http.StatusOK, &ts)
|
||||
s.DoJSON("GET", fmt.Sprintf("/api/latest/fleet/teams/%d/schedule", team1.ID), nil, http.StatusOK, &ts)
|
||||
require.Len(t, ts.Scheduled, 1)
|
||||
assert.Equal(t, uint(77), ts.Scheduled[0].Interval)
|
||||
|
||||
deleteResp := deleteTeamScheduleResponse{}
|
||||
s.DoJSON("DELETE", fmt.Sprintf("/api/v1/fleet/teams/%d/schedule/%d", team1.ID, id), nil, http.StatusOK, &deleteResp)
|
||||
s.DoJSON("DELETE", fmt.Sprintf("/api/latest/fleet/teams/%d/schedule/%d", team1.ID, id), nil, http.StatusOK, &deleteResp)
|
||||
|
||||
ts = getTeamScheduleResponse{}
|
||||
s.DoJSON("GET", fmt.Sprintf("/api/v1/fleet/teams/%d/schedule", team1.ID), nil, http.StatusOK, &ts)
|
||||
s.DoJSON("GET", fmt.Sprintf("/api/latest/fleet/teams/%d/schedule", team1.ID), nil, http.StatusOK, &ts)
|
||||
require.Len(t, ts.Scheduled, 0)
|
||||
}
|
||||
|
||||
|
|
@ -182,7 +182,7 @@ func (s *integrationEnterpriseTestSuite) TestTeamPolicies() {
|
|||
s.token = s.getTestToken(email, password)
|
||||
|
||||
ts := listTeamPoliciesResponse{}
|
||||
s.DoJSON("GET", fmt.Sprintf("/api/v1/fleet/teams/%d/policies", team1.ID), nil, http.StatusOK, &ts)
|
||||
s.DoJSON("GET", fmt.Sprintf("/api/latest/fleet/teams/%d/policies", team1.ID), nil, http.StatusOK, &ts)
|
||||
require.Len(t, ts.Policies, 0)
|
||||
|
||||
qr, err := s.ds.NewQuery(context.Background(), &fleet.Query{Name: "TestQuery2", Description: "Some description", Query: "select * from osquery;", ObserverCanRun: true})
|
||||
|
|
@ -193,10 +193,10 @@ func (s *integrationEnterpriseTestSuite) TestTeamPolicies() {
|
|||
Resolution: "some team resolution",
|
||||
}
|
||||
r := teamPolicyResponse{}
|
||||
s.DoJSON("POST", fmt.Sprintf("/api/v1/fleet/teams/%d/policies", team1.ID), tpParams, http.StatusOK, &r)
|
||||
s.DoJSON("POST", fmt.Sprintf("/api/latest/fleet/teams/%d/policies", team1.ID), tpParams, http.StatusOK, &r)
|
||||
|
||||
ts = listTeamPoliciesResponse{}
|
||||
s.DoJSON("GET", fmt.Sprintf("/api/v1/fleet/teams/%d/policies", team1.ID), nil, http.StatusOK, &ts)
|
||||
s.DoJSON("GET", fmt.Sprintf("/api/latest/fleet/teams/%d/policies", team1.ID), nil, http.StatusOK, &ts)
|
||||
require.Len(t, ts.Policies, 1)
|
||||
assert.Equal(t, "TestQuery2", ts.Policies[0].Name)
|
||||
assert.Equal(t, "select * from osquery;", ts.Policies[0].Query)
|
||||
|
|
@ -206,10 +206,10 @@ func (s *integrationEnterpriseTestSuite) TestTeamPolicies() {
|
|||
|
||||
deletePolicyParams := deleteTeamPoliciesRequest{IDs: []uint{ts.Policies[0].ID}}
|
||||
deletePolicyResp := deleteTeamPoliciesResponse{}
|
||||
s.DoJSON("POST", fmt.Sprintf("/api/v1/fleet/teams/%d/policies/delete", team1.ID), deletePolicyParams, http.StatusOK, &deletePolicyResp)
|
||||
s.DoJSON("POST", fmt.Sprintf("/api/latest/fleet/teams/%d/policies/delete", team1.ID), deletePolicyParams, http.StatusOK, &deletePolicyResp)
|
||||
|
||||
ts = listTeamPoliciesResponse{}
|
||||
s.DoJSON("GET", fmt.Sprintf("/api/v1/fleet/teams/%d/policies", team1.ID), nil, http.StatusOK, &ts)
|
||||
s.DoJSON("GET", fmt.Sprintf("/api/latest/fleet/teams/%d/policies", team1.ID), nil, http.StatusOK, &ts)
|
||||
require.Len(t, ts.Policies, 0)
|
||||
}
|
||||
|
||||
|
|
@ -224,7 +224,7 @@ func (s *integrationEnterpriseTestSuite) TestModifyTeamEnrollSecrets() {
|
|||
Secrets: []*fleet.EnrollSecret{{Secret: "initialSecret"}},
|
||||
}
|
||||
|
||||
s.Do("POST", "/api/v1/fleet/teams", team, http.StatusOK)
|
||||
s.Do("POST", "/api/latest/fleet/teams", team, http.StatusOK)
|
||||
|
||||
team, err := s.ds.TeamByName(context.Background(), teamName)
|
||||
require.NoError(t, err)
|
||||
|
|
@ -234,7 +234,7 @@ func (s *integrationEnterpriseTestSuite) TestModifyTeamEnrollSecrets() {
|
|||
req := json.RawMessage(`{"secrets": [{"secret": "testSecret1"},{"secret": "testSecret2"}]}`)
|
||||
var resp teamEnrollSecretsResponse
|
||||
|
||||
s.DoJSON("PATCH", fmt.Sprintf("/api/v1/fleet/teams/%d/secrets", team.ID), req, http.StatusOK, &resp)
|
||||
s.DoJSON("PATCH", fmt.Sprintf("/api/latest/fleet/teams/%d/secrets", team.ID), req, http.StatusOK, &resp)
|
||||
require.Len(t, resp.Secrets, 2)
|
||||
|
||||
team, err = s.ds.TeamByName(context.Background(), teamName)
|
||||
|
|
@ -243,12 +243,12 @@ func (s *integrationEnterpriseTestSuite) TestModifyTeamEnrollSecrets() {
|
|||
assert.Equal(t, "testSecret2", team.Secrets[1].Secret)
|
||||
|
||||
// Test delete all enroll secrets
|
||||
s.DoJSON("PATCH", fmt.Sprintf("/api/v1/fleet/teams/%d/secrets", team.ID), json.RawMessage(`{"secrets": []}`), http.StatusOK, &resp)
|
||||
s.DoJSON("PATCH", fmt.Sprintf("/api/latest/fleet/teams/%d/secrets", team.ID), json.RawMessage(`{"secrets": []}`), http.StatusOK, &resp)
|
||||
require.Len(t, resp.Secrets, 0)
|
||||
|
||||
// Test bad requests
|
||||
s.DoJSON("PATCH", fmt.Sprintf("/api/v1/fleet/teams/%d/secrets", team.ID), json.RawMessage(`{"foo": [{"secret": "testSecret3"}]}`), http.StatusUnprocessableEntity, &resp)
|
||||
s.DoJSON("PATCH", fmt.Sprintf("/api/v1/fleet/teams/%d/secrets", team.ID), json.RawMessage(`{}`), http.StatusUnprocessableEntity, &resp)
|
||||
s.DoJSON("PATCH", fmt.Sprintf("/api/latest/fleet/teams/%d/secrets", team.ID), json.RawMessage(`{"foo": [{"secret": "testSecret3"}]}`), http.StatusUnprocessableEntity, &resp)
|
||||
s.DoJSON("PATCH", fmt.Sprintf("/api/latest/fleet/teams/%d/secrets", team.ID), json.RawMessage(`{}`), http.StatusUnprocessableEntity, &resp)
|
||||
}
|
||||
|
||||
func (s *integrationEnterpriseTestSuite) TestAvailableTeams() {
|
||||
|
|
@ -260,7 +260,7 @@ func (s *integrationEnterpriseTestSuite) TestAvailableTeams() {
|
|||
Description: "Available Team description",
|
||||
}
|
||||
|
||||
s.Do("POST", "/api/v1/fleet/teams", team, http.StatusOK)
|
||||
s.Do("POST", "/api/latest/fleet/teams", team, http.StatusOK)
|
||||
|
||||
team, err := s.ds.TeamByName(context.Background(), "Available Team")
|
||||
require.NoError(t, err)
|
||||
|
|
@ -278,7 +278,7 @@ func (s *integrationEnterpriseTestSuite) TestAvailableTeams() {
|
|||
|
||||
// test available teams for user assigned to global role
|
||||
var getResp getUserResponse
|
||||
s.DoJSON("GET", fmt.Sprintf("/api/v1/fleet/users/%d", user.ID), nil, http.StatusOK, &getResp)
|
||||
s.DoJSON("GET", fmt.Sprintf("/api/latest/fleet/users/%d", user.ID), nil, http.StatusOK, &getResp)
|
||||
assert.Equal(t, user.ID, getResp.User.ID)
|
||||
assert.Equal(t, ptr.String("observer"), getResp.User.GlobalRole)
|
||||
assert.Len(t, getResp.User.Teams, 0) // teams is empty if user has a global role
|
||||
|
|
@ -292,7 +292,7 @@ func (s *integrationEnterpriseTestSuite) TestAvailableTeams() {
|
|||
require.NoError(t, err)
|
||||
|
||||
// test available teams for user assigned to team role
|
||||
s.DoJSON("GET", fmt.Sprintf("/api/v1/fleet/users/%d", user.ID), nil, http.StatusOK, &getResp)
|
||||
s.DoJSON("GET", fmt.Sprintf("/api/latest/fleet/users/%d", user.ID), nil, http.StatusOK, &getResp)
|
||||
assert.Equal(t, user.ID, getResp.User.ID)
|
||||
assert.Nil(t, getResp.User.GlobalRole)
|
||||
assert.Len(t, getResp.User.Teams, 1)
|
||||
|
|
@ -305,7 +305,7 @@ func (s *integrationEnterpriseTestSuite) TestAvailableTeams() {
|
|||
sessionKey := base64.StdEncoding.EncodeToString(key)
|
||||
_, err = s.ds.NewSession(context.Background(), user.ID, sessionKey)
|
||||
require.NoError(t, err)
|
||||
resp := s.DoRawWithHeaders("GET", "/api/v1/fleet/me", []byte(""), http.StatusOK, map[string]string{
|
||||
resp := s.DoRawWithHeaders("GET", "/api/latest/fleet/me", []byte(""), http.StatusOK, map[string]string{
|
||||
"Authorization": fmt.Sprintf("Bearer %s", sessionKey),
|
||||
})
|
||||
err = json.NewDecoder(resp.Body).Decode(&getResp)
|
||||
|
|
@ -330,7 +330,7 @@ func (s *integrationEnterpriseTestSuite) TestTeamEndpoints() {
|
|||
}
|
||||
|
||||
var tmResp teamResponse
|
||||
s.DoJSON("POST", "/api/v1/fleet/teams", team, http.StatusOK, &tmResp)
|
||||
s.DoJSON("POST", "/api/latest/fleet/teams", team, http.StatusOK, &tmResp)
|
||||
assert.Equal(t, team.Name, tmResp.Team.Name)
|
||||
require.Len(t, tmResp.Team.Secrets, 1)
|
||||
assert.Equal(t, "DEF", tmResp.Team.Secrets[0].Secret)
|
||||
|
|
@ -342,38 +342,38 @@ func (s *integrationEnterpriseTestSuite) TestTeamEndpoints() {
|
|||
Secrets: []*fleet.EnrollSecret{{Secret: "GHI"}},
|
||||
}
|
||||
tmResp.Team = nil
|
||||
s.DoJSON("POST", "/api/v1/fleet/teams", team2, http.StatusConflict, &tmResp)
|
||||
s.DoJSON("POST", "/api/latest/fleet/teams", team2, http.StatusConflict, &tmResp)
|
||||
|
||||
// list teams
|
||||
var listResp listTeamsResponse
|
||||
s.DoJSON("GET", "/api/v1/fleet/teams", nil, http.StatusOK, &listResp, "query", name, "per_page", "2")
|
||||
s.DoJSON("GET", "/api/latest/fleet/teams", nil, http.StatusOK, &listResp, "query", name, "per_page", "2")
|
||||
require.Len(t, listResp.Teams, 1)
|
||||
assert.Equal(t, team.Name, listResp.Teams[0].Name)
|
||||
tm1ID := listResp.Teams[0].ID
|
||||
|
||||
// get team
|
||||
var getResp getTeamResponse
|
||||
s.DoJSON("GET", fmt.Sprintf("/api/v1/fleet/teams/%d", tm1ID), nil, http.StatusOK, &getResp)
|
||||
s.DoJSON("GET", fmt.Sprintf("/api/latest/fleet/teams/%d", tm1ID), nil, http.StatusOK, &getResp)
|
||||
assert.Equal(t, team.Name, getResp.Team.Name)
|
||||
|
||||
// modify team
|
||||
team.Description = "Alt " + team.Description
|
||||
tmResp.Team = nil
|
||||
s.DoJSON("PATCH", fmt.Sprintf("/api/v1/fleet/teams/%d", tm1ID), team, http.StatusOK, &tmResp)
|
||||
s.DoJSON("PATCH", fmt.Sprintf("/api/latest/fleet/teams/%d", tm1ID), team, http.StatusOK, &tmResp)
|
||||
assert.Contains(t, tmResp.Team.Description, "Alt ")
|
||||
|
||||
// modify non-existing team
|
||||
tmResp.Team = nil
|
||||
s.DoJSON("PATCH", fmt.Sprintf("/api/v1/fleet/teams/%d", tm1ID+1), team, http.StatusNotFound, &tmResp)
|
||||
s.DoJSON("PATCH", fmt.Sprintf("/api/latest/fleet/teams/%d", tm1ID+1), team, http.StatusNotFound, &tmResp)
|
||||
|
||||
// list team users
|
||||
var usersResp listUsersResponse
|
||||
s.DoJSON("GET", fmt.Sprintf("/api/v1/fleet/teams/%d/users", tm1ID), nil, http.StatusOK, &usersResp)
|
||||
s.DoJSON("GET", fmt.Sprintf("/api/latest/fleet/teams/%d/users", tm1ID), nil, http.StatusOK, &usersResp)
|
||||
assert.Len(t, usersResp.Users, 0)
|
||||
|
||||
// list team users - non-existing team
|
||||
usersResp.Users = nil
|
||||
s.DoJSON("GET", fmt.Sprintf("/api/v1/fleet/teams/%d/users", tm1ID+1), nil, http.StatusNotFound, &usersResp)
|
||||
s.DoJSON("GET", fmt.Sprintf("/api/latest/fleet/teams/%d/users", tm1ID+1), nil, http.StatusNotFound, &usersResp)
|
||||
|
||||
// create a new user
|
||||
user := &fleet.User{
|
||||
|
|
@ -387,71 +387,71 @@ func (s *integrationEnterpriseTestSuite) TestTeamEndpoints() {
|
|||
|
||||
// add a team user
|
||||
tmResp.Team = nil
|
||||
s.DoJSON("PATCH", fmt.Sprintf("/api/v1/fleet/teams/%d/users", tm1ID), modifyTeamUsersRequest{Users: []fleet.TeamUser{{User: *user, Role: fleet.RoleObserver}}}, http.StatusOK, &tmResp)
|
||||
s.DoJSON("PATCH", fmt.Sprintf("/api/latest/fleet/teams/%d/users", tm1ID), modifyTeamUsersRequest{Users: []fleet.TeamUser{{User: *user, Role: fleet.RoleObserver}}}, http.StatusOK, &tmResp)
|
||||
require.Len(t, tmResp.Team.Users, 1)
|
||||
assert.Equal(t, user.ID, tmResp.Team.Users[0].ID)
|
||||
|
||||
// add a team user - non-existing team
|
||||
tmResp.Team = nil
|
||||
s.DoJSON("PATCH", fmt.Sprintf("/api/v1/fleet/teams/%d/users", tm1ID+1), modifyTeamUsersRequest{Users: []fleet.TeamUser{{User: *user, Role: fleet.RoleObserver}}}, http.StatusNotFound, &tmResp)
|
||||
s.DoJSON("PATCH", fmt.Sprintf("/api/latest/fleet/teams/%d/users", tm1ID+1), modifyTeamUsersRequest{Users: []fleet.TeamUser{{User: *user, Role: fleet.RoleObserver}}}, http.StatusNotFound, &tmResp)
|
||||
|
||||
// add a team user - invalid user role
|
||||
tmResp.Team = nil
|
||||
s.DoJSON("PATCH", fmt.Sprintf("/api/v1/fleet/teams/%d/users", tm1ID), modifyTeamUsersRequest{Users: []fleet.TeamUser{{User: *user, Role: "foobar"}}}, http.StatusUnprocessableEntity, &tmResp)
|
||||
s.DoJSON("PATCH", fmt.Sprintf("/api/latest/fleet/teams/%d/users", tm1ID), modifyTeamUsersRequest{Users: []fleet.TeamUser{{User: *user, Role: "foobar"}}}, http.StatusUnprocessableEntity, &tmResp)
|
||||
|
||||
// search for that user
|
||||
usersResp.Users = nil
|
||||
s.DoJSON("GET", fmt.Sprintf("/api/v1/fleet/teams/%d/users", tm1ID), nil, http.StatusOK, &usersResp, "query", "user")
|
||||
s.DoJSON("GET", fmt.Sprintf("/api/latest/fleet/teams/%d/users", tm1ID), nil, http.StatusOK, &usersResp, "query", "user")
|
||||
require.Len(t, usersResp.Users, 1)
|
||||
assert.Equal(t, user.ID, usersResp.Users[0].ID)
|
||||
|
||||
// search for unknown user
|
||||
usersResp.Users = nil
|
||||
s.DoJSON("GET", fmt.Sprintf("/api/v1/fleet/teams/%d/users", tm1ID), nil, http.StatusOK, &usersResp, "query", "notauser")
|
||||
s.DoJSON("GET", fmt.Sprintf("/api/latest/fleet/teams/%d/users", tm1ID), nil, http.StatusOK, &usersResp, "query", "notauser")
|
||||
require.Len(t, usersResp.Users, 0)
|
||||
|
||||
// delete team user
|
||||
tmResp.Team = nil
|
||||
s.DoJSON("DELETE", fmt.Sprintf("/api/v1/fleet/teams/%d/users", tm1ID), modifyTeamUsersRequest{Users: []fleet.TeamUser{{User: fleet.User{ID: user.ID}}}}, http.StatusOK, &tmResp)
|
||||
s.DoJSON("DELETE", fmt.Sprintf("/api/latest/fleet/teams/%d/users", tm1ID), modifyTeamUsersRequest{Users: []fleet.TeamUser{{User: fleet.User{ID: user.ID}}}}, http.StatusOK, &tmResp)
|
||||
require.Len(t, tmResp.Team.Users, 0)
|
||||
|
||||
// delete team user - unknown user
|
||||
tmResp.Team = nil
|
||||
s.DoJSON("DELETE", fmt.Sprintf("/api/v1/fleet/teams/%d/users", tm1ID), modifyTeamUsersRequest{Users: []fleet.TeamUser{{User: fleet.User{ID: user.ID + 1}}}}, http.StatusOK, &tmResp)
|
||||
s.DoJSON("DELETE", fmt.Sprintf("/api/latest/fleet/teams/%d/users", tm1ID), modifyTeamUsersRequest{Users: []fleet.TeamUser{{User: fleet.User{ID: user.ID + 1}}}}, http.StatusOK, &tmResp)
|
||||
require.Len(t, tmResp.Team.Users, 0)
|
||||
|
||||
// delete team user - unknown team
|
||||
tmResp.Team = nil
|
||||
s.DoJSON("DELETE", fmt.Sprintf("/api/v1/fleet/teams/%d/users", tm1ID+1), modifyTeamUsersRequest{Users: []fleet.TeamUser{{User: fleet.User{ID: user.ID}}}}, http.StatusNotFound, &tmResp)
|
||||
s.DoJSON("DELETE", fmt.Sprintf("/api/latest/fleet/teams/%d/users", tm1ID+1), modifyTeamUsersRequest{Users: []fleet.TeamUser{{User: fleet.User{ID: user.ID}}}}, http.StatusNotFound, &tmResp)
|
||||
|
||||
// modify team agent options (options for orbit/osquery)
|
||||
tmResp.Team = nil
|
||||
opts := map[string]string{"x": "y"}
|
||||
s.DoJSON("POST", fmt.Sprintf("/api/v1/fleet/teams/%d/agent_options", tm1ID), opts, http.StatusOK, &tmResp)
|
||||
s.DoJSON("POST", fmt.Sprintf("/api/latest/fleet/teams/%d/agent_options", tm1ID), opts, http.StatusOK, &tmResp)
|
||||
var m map[string]string
|
||||
require.NoError(t, json.Unmarshal(*tmResp.Team.Config.AgentOptions, &m))
|
||||
assert.Equal(t, opts, m)
|
||||
|
||||
// modify team agent options - unknown team
|
||||
tmResp.Team = nil
|
||||
s.DoJSON("POST", fmt.Sprintf("/api/v1/fleet/teams/%d/agent_options", tm1ID+1), opts, http.StatusNotFound, &tmResp)
|
||||
s.DoJSON("POST", fmt.Sprintf("/api/latest/fleet/teams/%d/agent_options", tm1ID+1), opts, http.StatusNotFound, &tmResp)
|
||||
|
||||
// get team enroll secrets
|
||||
var secResp teamEnrollSecretsResponse
|
||||
s.DoJSON("GET", fmt.Sprintf("/api/v1/fleet/teams/%d/secrets", tm1ID), nil, http.StatusOK, &secResp)
|
||||
s.DoJSON("GET", fmt.Sprintf("/api/latest/fleet/teams/%d/secrets", tm1ID), nil, http.StatusOK, &secResp)
|
||||
require.Len(t, secResp.Secrets, 1)
|
||||
assert.Equal(t, team.Secrets[0].Secret, secResp.Secrets[0].Secret)
|
||||
|
||||
// get team enroll secrets- unknown team: does not return 404 because reads directly
|
||||
// the secrets table, does not load the team first (which would be unnecessary except
|
||||
// for checking that it exists)
|
||||
s.DoJSON("GET", fmt.Sprintf("/api/v1/fleet/teams/%d/secrets", tm1ID+1), nil, http.StatusOK, &secResp)
|
||||
s.DoJSON("GET", fmt.Sprintf("/api/latest/fleet/teams/%d/secrets", tm1ID+1), nil, http.StatusOK, &secResp)
|
||||
assert.Len(t, secResp.Secrets, 0)
|
||||
|
||||
// delete team
|
||||
var delResp deleteTeamResponse
|
||||
s.DoJSON("DELETE", fmt.Sprintf("/api/v1/fleet/teams/%d", tm1ID), nil, http.StatusOK, &delResp)
|
||||
s.DoJSON("DELETE", fmt.Sprintf("/api/latest/fleet/teams/%d", tm1ID), nil, http.StatusOK, &delResp)
|
||||
|
||||
// delete team again, now an unknown team
|
||||
s.DoJSON("DELETE", fmt.Sprintf("/api/v1/fleet/teams/%d", tm1ID), nil, http.StatusNotFound, &delResp)
|
||||
s.DoJSON("DELETE", fmt.Sprintf("/api/latest/fleet/teams/%d", tm1ID), nil, http.StatusNotFound, &delResp)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ func (s *liveQueriesTestSuite) TestLiveQueriesRestOneHostOneQuery() {
|
|||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
s.DoJSON("GET", "/api/v1/fleet/queries/run", liveQueryRequest, http.StatusOK, &liveQueryResp)
|
||||
s.DoJSON("GET", "/api/latest/fleet/queries/run", liveQueryRequest, http.StatusOK, &liveQueryResp)
|
||||
}()
|
||||
|
||||
// Give the above call a couple of seconds to create the campaign
|
||||
|
|
@ -118,7 +118,7 @@ func (s *liveQueriesTestSuite) TestLiveQueriesRestOneHostOneQuery() {
|
|||
},
|
||||
}
|
||||
distributedResp := submitDistributedQueryResultsResponse{}
|
||||
s.DoJSON("POST", "/api/v1/osquery/distributed/write", distributedReq, http.StatusOK, &distributedResp)
|
||||
s.DoJSON("POST", "/api/osquery/distributed/write", distributedReq, http.StatusOK, &distributedResp)
|
||||
|
||||
wg.Wait()
|
||||
|
||||
|
|
@ -160,7 +160,7 @@ func (s *liveQueriesTestSuite) TestLiveQueriesRestOneHostMultipleQuery() {
|
|||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
s.DoJSON("GET", "/api/v1/fleet/queries/run", liveQueryRequest, http.StatusOK, &liveQueryResp)
|
||||
s.DoJSON("GET", "/api/latest/fleet/queries/run", liveQueryRequest, http.StatusOK, &liveQueryResp)
|
||||
}()
|
||||
|
||||
// Give the above call a couple of seconds to create the campaign
|
||||
|
|
@ -185,7 +185,7 @@ func (s *liveQueriesTestSuite) TestLiveQueriesRestOneHostMultipleQuery() {
|
|||
},
|
||||
}
|
||||
distributedResp := submitDistributedQueryResultsResponse{}
|
||||
s.DoJSON("POST", "/api/v1/osquery/distributed/write", distributedReq, http.StatusOK, &distributedResp)
|
||||
s.DoJSON("POST", "/api/osquery/distributed/write", distributedReq, http.StatusOK, &distributedResp)
|
||||
|
||||
wg.Wait()
|
||||
|
||||
|
|
@ -259,7 +259,7 @@ func (s *liveQueriesTestSuite) TestLiveQueriesRestMultipleHostMultipleQuery() {
|
|||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
s.DoJSON("GET", "/api/v1/fleet/queries/run", liveQueryRequest, http.StatusOK, &liveQueryResp)
|
||||
s.DoJSON("GET", "/api/latest/fleet/queries/run", liveQueryRequest, http.StatusOK, &liveQueryResp)
|
||||
}()
|
||||
|
||||
// Give the above call a couple of seconds to create the campaign
|
||||
|
|
@ -283,7 +283,7 @@ func (s *liveQueriesTestSuite) TestLiveQueriesRestMultipleHostMultipleQuery() {
|
|||
},
|
||||
}
|
||||
distributedResp := submitDistributedQueryResultsResponse{}
|
||||
s.DoJSON("POST", "/api/v1/osquery/distributed/write", distributedReq, http.StatusOK, &distributedResp)
|
||||
s.DoJSON("POST", "/api/osquery/distributed/write", distributedReq, http.StatusOK, &distributedResp)
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
|
|
@ -323,7 +323,7 @@ func (s *liveQueriesTestSuite) TestLiveQueriesRestFailsToCreateCampaign() {
|
|||
}
|
||||
liveQueryResp := runLiveQueryResponse{}
|
||||
|
||||
s.DoJSON("GET", "/api/v1/fleet/queries/run", liveQueryRequest, http.StatusOK, &liveQueryResp)
|
||||
s.DoJSON("GET", "/api/latest/fleet/queries/run", liveQueryRequest, http.StatusOK, &liveQueryResp)
|
||||
|
||||
require.Len(t, liveQueryResp.Results, 1)
|
||||
assert.Equal(t, 0, liveQueryResp.Summary.RespondedHostCount)
|
||||
|
|
@ -356,7 +356,7 @@ func (s *liveQueriesTestSuite) TestLiveQueriesRestFailsOnSomeHost() {
|
|||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
s.DoJSON("GET", "/api/v1/fleet/queries/run", liveQueryRequest, http.StatusOK, &liveQueryResp)
|
||||
s.DoJSON("GET", "/api/latest/fleet/queries/run", liveQueryRequest, http.StatusOK, &liveQueryResp)
|
||||
}()
|
||||
|
||||
// Give the above call a couple of seconds to create the campaign
|
||||
|
|
@ -375,7 +375,7 @@ func (s *liveQueriesTestSuite) TestLiveQueriesRestFailsOnSomeHost() {
|
|||
},
|
||||
}
|
||||
distributedResp := submitDistributedQueryResultsResponse{}
|
||||
s.DoJSON("POST", "/api/v1/osquery/distributed/write", distributedReq, http.StatusOK, &distributedResp)
|
||||
s.DoJSON("POST", "/api/osquery/distributed/write", distributedReq, http.StatusOK, &distributedResp)
|
||||
|
||||
distributedReq = submitDistributedQueryResultsRequestShim{
|
||||
NodeKey: h2.NodeKey,
|
||||
|
|
@ -390,7 +390,7 @@ func (s *liveQueriesTestSuite) TestLiveQueriesRestFailsOnSomeHost() {
|
|||
},
|
||||
}
|
||||
distributedResp = submitDistributedQueryResultsResponse{}
|
||||
s.DoJSON("POST", "/api/v1/osquery/distributed/write", distributedReq, http.StatusOK, &distributedResp)
|
||||
s.DoJSON("POST", "/api/osquery/distributed/write", distributedReq, http.StatusOK, &distributedResp)
|
||||
|
||||
wg.Wait()
|
||||
|
||||
|
|
@ -420,13 +420,13 @@ func (s *liveQueriesTestSuite) TestCreateDistributedQueryCampaign() {
|
|||
|
||||
// create with no payload
|
||||
var createResp createDistributedQueryCampaignResponse
|
||||
s.DoJSON("POST", "/api/v1/fleet/queries/run", nil, http.StatusUnprocessableEntity, &createResp)
|
||||
s.DoJSON("POST", "/api/latest/fleet/queries/run", nil, http.StatusUnprocessableEntity, &createResp)
|
||||
|
||||
// create with unknown query
|
||||
s.DoJSON("POST", "/api/v1/fleet/queries/run", createDistributedQueryCampaignRequest{QueryID: ptr.Uint(9999)}, http.StatusNotFound, &createResp)
|
||||
s.DoJSON("POST", "/api/latest/fleet/queries/run", createDistributedQueryCampaignRequest{QueryID: ptr.Uint(9999)}, http.StatusNotFound, &createResp)
|
||||
|
||||
// create with new query
|
||||
s.DoJSON("POST", "/api/v1/fleet/queries/run", createDistributedQueryCampaignRequest{QuerySQL: "SELECT 1"}, http.StatusOK, &createResp)
|
||||
s.DoJSON("POST", "/api/latest/fleet/queries/run", createDistributedQueryCampaignRequest{QuerySQL: "SELECT 1"}, http.StatusOK, &createResp)
|
||||
assert.NotZero(t, createResp.Campaign.ID)
|
||||
assert.Equal(t, fleet.QueryWaiting, createResp.Campaign.Status)
|
||||
assert.Equal(t, uint(0), createResp.Campaign.Metrics.TotalHosts)
|
||||
|
|
@ -436,7 +436,7 @@ func (s *liveQueriesTestSuite) TestCreateDistributedQueryCampaign() {
|
|||
time.Sleep(time.Second)
|
||||
|
||||
// create with new query for specific hosts
|
||||
s.DoJSON("POST", "/api/v1/fleet/queries/run", createDistributedQueryCampaignRequest{QuerySQL: "SELECT 2", Selected: fleet.HostTargets{HostIDs: []uint{h1.ID, h2.ID}}}, http.StatusOK, &createResp)
|
||||
s.DoJSON("POST", "/api/latest/fleet/queries/run", createDistributedQueryCampaignRequest{QuerySQL: "SELECT 2", Selected: fleet.HostTargets{HostIDs: []uint{h1.ID, h2.ID}}}, http.StatusOK, &createResp)
|
||||
assert.NotEqual(t, camp1.ID, createResp.Campaign.ID)
|
||||
assert.Equal(t, uint(2), createResp.Campaign.Metrics.TotalHosts)
|
||||
|
||||
|
|
@ -444,7 +444,7 @@ func (s *liveQueriesTestSuite) TestCreateDistributedQueryCampaign() {
|
|||
time.Sleep(time.Second)
|
||||
|
||||
// create by host name
|
||||
s.DoJSON("POST", "/api/v1/fleet/queries/run_by_names", createDistributedQueryCampaignByNamesRequest{
|
||||
s.DoJSON("POST", "/api/latest/fleet/queries/run_by_names", createDistributedQueryCampaignByNamesRequest{
|
||||
QuerySQL: "SELECT 3", Selected: distributedQueryCampaignTargetsByNames{Hosts: []string{h1.Hostname}}},
|
||||
http.StatusOK, &createResp)
|
||||
assert.NotEqual(t, camp1.ID, createResp.Campaign.ID)
|
||||
|
|
@ -454,7 +454,7 @@ func (s *liveQueriesTestSuite) TestCreateDistributedQueryCampaign() {
|
|||
time.Sleep(time.Second)
|
||||
|
||||
// create by unknown host name - it ignores the unknown names
|
||||
s.DoJSON("POST", "/api/v1/fleet/queries/run_by_names", createDistributedQueryCampaignByNamesRequest{
|
||||
s.DoJSON("POST", "/api/latest/fleet/queries/run_by_names", createDistributedQueryCampaignByNamesRequest{
|
||||
QuerySQL: "SELECT 3", Selected: distributedQueryCampaignTargetsByNames{Hosts: []string{h1.Hostname + "ZZZZZ"}}},
|
||||
http.StatusOK, &createResp)
|
||||
}
|
||||
|
|
@ -467,12 +467,12 @@ func (s *liveQueriesTestSuite) TestOsqueryDistributedRead() {
|
|||
|
||||
req := getDistributedQueriesRequest{NodeKey: s.hosts[1].NodeKey}
|
||||
var resp getDistributedQueriesResponse
|
||||
s.DoJSON("POST", "/api/v1/osquery/distributed/read", req, http.StatusOK, &resp)
|
||||
s.DoJSON("POST", "/api/osquery/distributed/read", req, http.StatusOK, &resp)
|
||||
assert.Contains(t, resp.Queries, hostDistributedQueryPrefix+fmt.Sprintf("%d", hostID))
|
||||
|
||||
// test with invalid node key
|
||||
var errRes map[string]interface{}
|
||||
req.NodeKey += "zzzz"
|
||||
s.DoJSON("POST", "/api/v1/osquery/distributed/read", req, http.StatusUnauthorized, &errRes)
|
||||
s.DoJSON("POST", "/api/osquery/distributed/read", req, http.StatusUnauthorized, &errRes)
|
||||
assert.Contains(t, errRes["error"], "invalid node key")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ func (s *integrationLoggerTestSuite) TestLogger() {
|
|||
Query: ptr.String("select 1 from osquery;"),
|
||||
}
|
||||
var createResp createQueryResponse
|
||||
s.DoJSON("POST", "/api/v1/fleet/queries", params, http.StatusOK, &createResp)
|
||||
s.DoJSON("POST", "/api/latest/fleet/queries", params, http.StatusOK, &createResp)
|
||||
|
||||
logs := s.buf.String()
|
||||
parts := strings.Split(strings.TrimSpace(logs), "\n")
|
||||
|
|
@ -80,16 +80,16 @@ func (s *integrationLoggerTestSuite) TestLogger() {
|
|||
case 0:
|
||||
assert.Equal(t, "info", kv["level"])
|
||||
assert.Equal(t, "POST", kv["method"])
|
||||
assert.Equal(t, "/api/v1/fleet/login", kv["uri"])
|
||||
assert.Equal(t, "/api/latest/fleet/login", kv["uri"])
|
||||
case 1:
|
||||
assert.Equal(t, "debug", kv["level"])
|
||||
assert.Equal(t, "GET", kv["method"])
|
||||
assert.Equal(t, "/api/v1/fleet/config", kv["uri"])
|
||||
assert.Equal(t, "/api/latest/fleet/config", kv["uri"])
|
||||
assert.Equal(t, "admin1@example.com", kv["user"])
|
||||
case 2:
|
||||
assert.Equal(t, "debug", kv["level"])
|
||||
assert.Equal(t, "POST", kv["method"])
|
||||
assert.Equal(t, "/api/v1/fleet/queries", kv["uri"])
|
||||
assert.Equal(t, "/api/latest/fleet/queries", kv["uri"])
|
||||
assert.Equal(t, "admin1@example.com", kv["user"])
|
||||
assert.Equal(t, "somequery", kv["name"])
|
||||
assert.Equal(t, "select 1 from osquery;", kv["sql"])
|
||||
|
|
@ -117,13 +117,13 @@ func (s *integrationLoggerTestSuite) TestOsqueryEndpointsLogErrors() {
|
|||
require.NoError(t, err)
|
||||
|
||||
requestBody := io.NopCloser(bytes.NewBuffer([]byte(`{"node_key":"1234","log_type":"status","data":[}`)))
|
||||
req, _ := http.NewRequest("POST", s.server.URL+"/api/v1/osquery/log", requestBody)
|
||||
req, _ := http.NewRequest("POST", s.server.URL+"/api/osquery/log", requestBody)
|
||||
client := fleethttp.NewClient()
|
||||
_, err = client.Do(req)
|
||||
require.Nil(t, err)
|
||||
|
||||
logString := s.buf.String()
|
||||
assert.Contains(t, logString, `invalid character '}' looking for beginning of value","level":"info","path":"/api/v1/osquery/log"}
|
||||
assert.Contains(t, logString, `invalid character '}' looking for beginning of value","level":"info","path":"/api/osquery/log"}
|
||||
`, logString)
|
||||
}
|
||||
|
||||
|
|
@ -151,7 +151,7 @@ func (s *integrationLoggerTestSuite) TestSubmitLog() {
|
|||
Data: nil,
|
||||
}
|
||||
res := submitLogsResponse{}
|
||||
s.DoJSON("POST", "/api/v1/osquery/log", req, http.StatusOK, &res)
|
||||
s.DoJSON("POST", "/api/osquery/log", req, http.StatusOK, &res)
|
||||
|
||||
logString := s.buf.String()
|
||||
assert.Equal(t, 1, strings.Count(logString, `"ip_addr"`))
|
||||
|
|
@ -165,7 +165,7 @@ func (s *integrationLoggerTestSuite) TestSubmitLog() {
|
|||
Data: nil,
|
||||
}
|
||||
res = submitLogsResponse{}
|
||||
s.DoJSON("POST", "/api/v1/osquery/log", req, http.StatusOK, &res)
|
||||
s.DoJSON("POST", "/api/osquery/log", req, http.StatusOK, &res)
|
||||
|
||||
logString = s.buf.String()
|
||||
assert.Equal(t, 1, strings.Count(logString, `"ip_addr"`))
|
||||
|
|
@ -179,7 +179,7 @@ func (s *integrationLoggerTestSuite) TestSubmitLog() {
|
|||
Data: nil,
|
||||
}
|
||||
var errRes map[string]string
|
||||
s.DoJSON("POST", "/api/v1/osquery/log", req, http.StatusInternalServerError, &errRes)
|
||||
s.DoJSON("POST", "/api/osquery/log", req, http.StatusInternalServerError, &errRes)
|
||||
assert.Contains(t, errRes["error"], "unknown log type")
|
||||
s.buf.Reset()
|
||||
|
||||
|
|
@ -194,13 +194,13 @@ func (s *integrationLoggerTestSuite) TestSubmitLog() {
|
|||
require.NoError(t, err)
|
||||
require.NoError(t, gw.Close())
|
||||
|
||||
s.DoRawWithHeaders("POST", "/api/v1/osquery/log", body.Bytes(), http.StatusOK, map[string]string{"Content-Encoding": "gzip"})
|
||||
s.DoRawWithHeaders("POST", "/api/osquery/log", body.Bytes(), http.StatusOK, map[string]string{"Content-Encoding": "gzip"})
|
||||
logString = s.buf.String()
|
||||
assert.Equal(t, 1, strings.Count(logString, `"ip_addr"`))
|
||||
assert.Equal(t, 1, strings.Count(logString, "x_for_ip_addr"))
|
||||
|
||||
// submit same payload without specifying gzip encoding fails
|
||||
s.DoRawWithHeaders("POST", "/api/v1/osquery/log", body.Bytes(), http.StatusInternalServerError, nil)
|
||||
s.DoRawWithHeaders("POST", "/api/osquery/log", body.Bytes(), http.StatusInternalServerError, nil)
|
||||
}
|
||||
|
||||
func (s *integrationLoggerTestSuite) TestEnrollAgentLogsErrors() {
|
||||
|
|
@ -225,7 +225,7 @@ func (s *integrationLoggerTestSuite) TestEnrollAgentLogsErrors() {
|
|||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
s.DoRawNoAuth("POST", "/api/v1/osquery/enroll", j, http.StatusUnauthorized)
|
||||
s.DoRawNoAuth("POST", "/api/osquery/enroll", j, http.StatusUnauthorized)
|
||||
|
||||
parts := strings.Split(strings.TrimSpace(s.buf.String()), "\n")
|
||||
require.Len(t, parts, 1)
|
||||
|
|
|
|||
|
|
@ -61,12 +61,12 @@ func (s *integrationSSOTestSuite) TestGetSSOSettings() {
|
|||
|
||||
// double-check the settings
|
||||
var resGet ssoSettingsResponse
|
||||
s.DoJSON("GET", "/api/v1/fleet/sso", nil, http.StatusOK, &resGet)
|
||||
s.DoJSON("GET", "/api/latest/fleet/sso", nil, http.StatusOK, &resGet)
|
||||
require.True(t, resGet.Settings.SSOEnabled)
|
||||
|
||||
// initiate an SSO auth
|
||||
var resIni initiateSSOResponse
|
||||
s.DoJSON("POST", "/api/v1/fleet/sso", map[string]string{}, http.StatusOK, &resIni)
|
||||
s.DoJSON("POST", "/api/latest/fleet/sso", map[string]string{}, http.StatusOK, &resIni)
|
||||
require.NotEmpty(t, resIni.URL)
|
||||
|
||||
parsed, err := url.Parse(resIni.URL)
|
||||
|
|
|
|||
|
|
@ -286,7 +286,7 @@ func (svc *Service) InitiateSSO(ctx context.Context, redirectURL string) (string
|
|||
settings := sso.Settings{
|
||||
Metadata: metadata,
|
||||
// Construct call back url to send to idp
|
||||
AssertionConsumerServiceURL: serverURL + svc.config.Server.URLPrefix + "/api/v1/fleet/sso/callback",
|
||||
AssertionConsumerServiceURL: serverURL + svc.config.Server.URLPrefix + "/api/latest/fleet/sso/callback",
|
||||
SessionStore: svc.ssoSessionStore,
|
||||
OriginalURL: redirectURL,
|
||||
}
|
||||
|
|
@ -425,7 +425,7 @@ func (svc *Service) CallbackSSO(ctx context.Context, auth fleet.Auth) (*fleet.SS
|
|||
validator, err := sso.NewValidator(*metadata, sso.WithExpectedAudience(
|
||||
appConfig.SSOSettings.EntityID,
|
||||
appConfig.ServerSettings.ServerURL,
|
||||
appConfig.ServerSettings.ServerURL+svc.config.Server.URLPrefix+"/api/v1/fleet/sso/callback", // ACS
|
||||
appConfig.ServerSettings.ServerURL+svc.config.Server.URLPrefix+"/api/latest/fleet/sso/callback", // ACS
|
||||
))
|
||||
if err != nil {
|
||||
return nil, ctxerr.Wrap(ctx, err, "create validator from metadata")
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ func (ts *withServer) getTestToken(email string, password string) string {
|
|||
require.NoError(ts.s.T(), err)
|
||||
|
||||
requestBody := io.NopCloser(bytes.NewBuffer(j))
|
||||
resp, err := http.Post(ts.server.URL+"/api/v1/fleet/login", "application/json", requestBody)
|
||||
resp, err := http.Post(ts.server.URL+"/api/latest/fleet/login", "application/json", requestBody)
|
||||
require.NoError(ts.s.T(), err)
|
||||
defer resp.Body.Close()
|
||||
assert.Equal(ts.s.T(), http.StatusOK, resp.StatusCode)
|
||||
|
|
@ -166,11 +166,11 @@ func (ts *withServer) applyConfig(spec []byte) {
|
|||
err := yaml.Unmarshal(spec, &appConfigSpec)
|
||||
require.NoError(ts.s.T(), err)
|
||||
|
||||
ts.Do("PATCH", "/api/v1/fleet/config", appConfigSpec, http.StatusOK)
|
||||
ts.Do("PATCH", "/api/latest/fleet/config", appConfigSpec, http.StatusOK)
|
||||
}
|
||||
|
||||
func (ts *withServer) getConfig() *appConfigResponse {
|
||||
var responseBody *appConfigResponse
|
||||
ts.DoJSON("GET", "/api/v1/fleet/config", nil, http.StatusOK, &responseBody)
|
||||
ts.DoJSON("GET", "/api/latest/fleet/config", nil, http.StatusOK, &responseBody)
|
||||
return responseBody
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ func TestCreateAuthorizationRequest(t *testing.T) {
|
|||
},
|
||||
},
|
||||
// Construct call back url to send to idp
|
||||
AssertionConsumerServiceURL: "http://localhost:8001/api/v1/fleet/sso/callback",
|
||||
AssertionConsumerServiceURL: "http://localhost:8001/api/latest/fleet/sso/callback",
|
||||
SessionStore: store,
|
||||
OriginalURL: "/redir",
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#!/bin/bash
|
||||
source $FLEET_ENV_PATH
|
||||
endpoint="api/v1/fleet/me"
|
||||
endpoint="api/latest/fleet/me"
|
||||
curl $CURL_FLAGS -H "Authorization: Bearer $TOKEN" "$SERVER_URL/$endpoint"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/bash
|
||||
source $FLEET_ENV_PATH
|
||||
endpoint="api/v1/fleet/packs"
|
||||
endpoint="api/latest/fleet/packs"
|
||||
jq -n \
|
||||
--arg name "$1" \
|
||||
'.name = $name
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#!/bin/bash
|
||||
source $FLEET_ENV_PATH
|
||||
endpoint="api/v1/fleet/packs"
|
||||
endpoint="api/latest/fleet/packs"
|
||||
curl $CURL_FLAGS -H "Authorization: Bearer $TOKEN" "$SERVER_URL/$endpoint"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#!/bin/bash
|
||||
source $FLEET_ENV_PATH
|
||||
endpoint="api/v1/fleet/packs/$1/scheduled"
|
||||
endpoint="api/latest/fleet/packs/$1/scheduled"
|
||||
curl $CURL_FLAGS -H "Authorization: Bearer $TOKEN" "$SERVER_URL/$endpoint"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/bash
|
||||
source $FLEET_ENV_PATH
|
||||
endpoint="api/v1/fleet/queries"
|
||||
endpoint="api/latest/fleet/queries"
|
||||
jq -n \
|
||||
--arg name "$1" \
|
||||
--arg query "$2" \
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#!/bin/bash
|
||||
source $FLEET_ENV_PATH
|
||||
endpoint="api/v1/fleet/queries"
|
||||
endpoint="api/latest/fleet/queries"
|
||||
curl $CURL_FLAGS -H "Authorization: Bearer $TOKEN" "$SERVER_URL/$endpoint"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/bash
|
||||
source $FLEET_ENV_PATH
|
||||
endpoint="api/v1/fleet/queries/run"
|
||||
endpoint="api/latest/fleet/queries/run"
|
||||
echo "By default, $endpoint will take 90 seconds..."
|
||||
jq -n \
|
||||
--argjson query_ids "$1" \
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/bash
|
||||
source $FLEET_ENV_PATH
|
||||
endpoint="api/v1/fleet/schedule"
|
||||
endpoint="api/latest/fleet/schedule"
|
||||
jq -n \
|
||||
--arg pack_id "$1" \
|
||||
--arg query_id "$2" \
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#!/bin/bash
|
||||
source $FLEET_ENV_PATH
|
||||
endpoint="api/v1/fleet/schedule/$1"
|
||||
endpoint="api/latest/fleet/schedule/$1"
|
||||
curl $CURL_FLAGS -X DELETE -H "Authorization: Bearer $TOKEN" "$SERVER_URL/$endpoint"
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
source $FLEET_ENV_PATH
|
||||
|
||||
# Create teams
|
||||
create_team_endpoint="api/v1/fleet/teams"
|
||||
create_team_endpoint="api/latest/fleet/teams"
|
||||
|
||||
# Create Client Platform Engineering
|
||||
data='{
|
||||
|
|
@ -26,7 +26,7 @@ data='{
|
|||
curl -X POST $CURL_FLAGS -H "Authorization: Bearer $TOKEN" "$SERVER_URL/$create_team_endpoint" -d "$data" --insecure
|
||||
|
||||
# Create users
|
||||
create_user_endpoint="api/v1/fleet/users/admin"
|
||||
create_user_endpoint="api/latest/fleet/users/admin"
|
||||
|
||||
# Create Andre Verot
|
||||
data='{
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
source $FLEET_ENV_PATH
|
||||
|
||||
# Create users
|
||||
create_user_endpoint="api/v1/fleet/users/admin"
|
||||
create_user_endpoint="api/latest/fleet/users/admin"
|
||||
|
||||
# Create Anna
|
||||
data='{
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
source $FLEET_ENV_PATH
|
||||
|
||||
# Create teams
|
||||
create_team_endpoint="api/v1/fleet/teams"
|
||||
create_team_endpoint="api/latest/fleet/teams"
|
||||
|
||||
# Create Apples
|
||||
data='{
|
||||
|
|
@ -20,7 +20,7 @@ data='{
|
|||
curl -X POST $CURL_FLAGS -H "Authorization: Bearer $TOKEN" "$SERVER_URL/$create_team_endpoint" -d "$data" --insecure
|
||||
|
||||
# Create users
|
||||
create_user_endpoint="api/v1/fleet/users/admin"
|
||||
create_user_endpoint="api/latest/fleet/users/admin"
|
||||
|
||||
# Create Anna
|
||||
data='{
|
||||
|
|
|
|||
|
|
@ -1,129 +1,130 @@
|
|||
<html>
|
||||
<head>
|
||||
<style>
|
||||
div.columns {
|
||||
width: 900px;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
div.columns div {
|
||||
width: 300px;
|
||||
float: left;
|
||||
}
|
||||
div.clear {
|
||||
clear: both;
|
||||
}
|
||||
div.content {
|
||||
width: 900px;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
</style>
|
||||
<script
|
||||
src="https://code.jquery.com/jquery-3.2.1.js"
|
||||
integrity="sha256-DZAnKJ/6XZ9si04Hgrsxu/8s717jcIzLy3oi35EouyE="
|
||||
crossorigin="anonymous"
|
||||
></script>
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
// User agent handling for SSO
|
||||
|
||||
// Check for existing session token indicating user has already started SSO process.
|
||||
// If the token exists, it is used to fetch the same user info/token as the
|
||||
// normal login process, albeit via the different SSO login endpoint. Note the session token only
|
||||
// persists for a few minutes on the server side, and, when we're done
|
||||
// we always delete the token in the user agent. We use the session token
|
||||
// to keep track of state from the user agent (Kolide SPA), the service provider
|
||||
// (Kolide back end), to the identity provider (IDP) and back.
|
||||
var sessionToken = localStorage.getItem("FLEET::auth_token");
|
||||
if (sessionToken != null) {
|
||||
console.log(
|
||||
"user should be authenticated, fetching user with token " +
|
||||
sessionToken
|
||||
);
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: "https://localhost:8080/api/v1/fleet/me",
|
||||
headers: { Authorization: "Bearer " + sessionToken },
|
||||
contentType: "text/plain;",
|
||||
dataType: "json",
|
||||
success: function (data) {
|
||||
// We've successfully created a login session with a token that
|
||||
// we can use in subsequent api calls to Kolide.
|
||||
console.log("sso login succeeded " + data);
|
||||
$("#displayarea").empty();
|
||||
$("#displayarea").append(
|
||||
"<h3>Authentication succeeded</h3>" +
|
||||
"<p>Token: " +
|
||||
localStorage.getItem("FLEET::auth_token").substring(0, 16) +
|
||||
"..." +
|
||||
"</p>" +
|
||||
"<p>User: " +
|
||||
data.user.email +
|
||||
"</p>"
|
||||
);
|
||||
// print user stuff
|
||||
},
|
||||
error: function (err) {
|
||||
console.log("sso login failed " + data);
|
||||
$("#displayarea").empty();
|
||||
$("#displayarea").append("<h3>Auth failed</h3>");
|
||||
},
|
||||
});
|
||||
console.log("removing token " + localStorage.getItem("ssoSession"));
|
||||
localStorage.removeItem("ssoSession");
|
||||
}
|
||||
// Single sign on invocation. User agent chooses single sign on for a particular
|
||||
// IDP trigger the following post.
|
||||
$(".clicker").click(function (e) {
|
||||
e.preventDefault();
|
||||
<head>
|
||||
<style>
|
||||
div.columns {
|
||||
width: 900px;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "https://localhost:8080/api/v1/fleet/sso",
|
||||
data: JSON.stringify({
|
||||
// supply the url of the resource user was trying to access when
|
||||
// prompted for login
|
||||
relay_url: $("#relay").val(),
|
||||
}),
|
||||
contentType: "text/plain;",
|
||||
dataType: "json",
|
||||
success: function (data) {
|
||||
console.log(data);
|
||||
// on success we redirect to IDP URL which is in response
|
||||
window.location.href = data.url;
|
||||
},
|
||||
error: function (errMsg) {
|
||||
console.log(errMsg);
|
||||
},
|
||||
});
|
||||
div.columns div {
|
||||
width: 300px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
div.clear {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
div.content {
|
||||
width: 900px;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
</style>
|
||||
<script src="https://code.jquery.com/jquery-3.2.1.js" integrity="sha256-DZAnKJ/6XZ9si04Hgrsxu/8s717jcIzLy3oi35EouyE="
|
||||
crossorigin="anonymous"></script>
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
// User agent handling for SSO
|
||||
|
||||
// Check for existing session token indicating user has already started SSO process.
|
||||
// If the token exists, it is used to fetch the same user info/token as the
|
||||
// normal login process, albeit via the different SSO login endpoint. Note the session token only
|
||||
// persists for a few minutes on the server side, and, when we're done
|
||||
// we always delete the token in the user agent. We use the session token
|
||||
// to keep track of state from the user agent (Kolide SPA), the service provider
|
||||
// (Kolide back end), to the identity provider (IDP) and back.
|
||||
var sessionToken = localStorage.getItem("FLEET::auth_token");
|
||||
if (sessionToken != null) {
|
||||
console.log(
|
||||
"user should be authenticated, fetching user with token " +
|
||||
sessionToken
|
||||
);
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: "https://localhost:8080/api/latest/fleet/me",
|
||||
headers: {Authorization: "Bearer " + sessionToken},
|
||||
contentType: "text/plain;",
|
||||
dataType: "json",
|
||||
success: function (data) {
|
||||
// We've successfully created a login session with a token that
|
||||
// we can use in subsequent api calls to Kolide.
|
||||
console.log("sso login succeeded " + data);
|
||||
$("#displayarea").empty();
|
||||
$("#displayarea").append(
|
||||
"<h3>Authentication succeeded</h3>" +
|
||||
"<p>Token: " +
|
||||
localStorage.getItem("FLEET::auth_token").substring(0, 16) +
|
||||
"..." +
|
||||
"</p>" +
|
||||
"<p>User: " +
|
||||
data.user.email +
|
||||
"</p>"
|
||||
);
|
||||
// print user stuff
|
||||
},
|
||||
error: function (err) {
|
||||
console.log("sso login failed " + data);
|
||||
$("#displayarea").empty();
|
||||
$("#displayarea").append("<h3>Auth failed</h3>");
|
||||
},
|
||||
});
|
||||
console.log("removing token " + localStorage.getItem("ssoSession"));
|
||||
localStorage.removeItem("ssoSession");
|
||||
}
|
||||
// Single sign on invocation. User agent chooses single sign on for a particular
|
||||
// IDP trigger the following post.
|
||||
$(".clicker").click(function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "https://localhost:8080/api/latest/fleet/sso",
|
||||
data: JSON.stringify({
|
||||
// supply the url of the resource user was trying to access when
|
||||
// prompted for login
|
||||
relay_url: $("#relay").val(),
|
||||
}),
|
||||
contentType: "text/plain;",
|
||||
dataType: "json",
|
||||
success: function (data) {
|
||||
console.log(data);
|
||||
// on success we redirect to IDP URL which is in response
|
||||
window.location.href = data.url;
|
||||
},
|
||||
error: function (errMsg) {
|
||||
console.log(errMsg);
|
||||
},
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h3>Single sign on test page</h3>
|
||||
<div class="content">
|
||||
This page is used to test single sign on identity providers. The
|
||||
<strong>Relay URL</strong> field contains the URL of the Kolide resource
|
||||
to invoke after authentication with the IDP. It defaults to this page.
|
||||
Click <a class="clicker" href="#">Request Authorization</a> to trigger the
|
||||
authorization process. The browser's javascript console may contain useful
|
||||
debugging information. The
|
||||
<a href="https://addons.mozilla.org/en-US/firefox/addon/saml-tracer/"
|
||||
>SAML Tracer</a
|
||||
>
|
||||
add-on for Firefox is also useful in diagnosing problems with a particular
|
||||
identity provider.
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h3>Single sign on test page</h3>
|
||||
<div class="content">
|
||||
This page is used to test single sign on identity providers. The
|
||||
<strong>Relay URL</strong> field contains the URL of the Kolide resource
|
||||
to invoke after authentication with the IDP. It defaults to this page.
|
||||
Click <a class="clicker" href="#">Request Authorization</a> to trigger the
|
||||
authorization process. The browser's javascript console may contain useful
|
||||
debugging information. The
|
||||
<a href="https://addons.mozilla.org/en-US/firefox/addon/saml-tracer/">SAML Tracer</a>
|
||||
add-on for Firefox is also useful in diagnosing problems with a particular
|
||||
identity provider.
|
||||
</div>
|
||||
<div class="columns">
|
||||
<div>Relay URL:</div>
|
||||
<div>
|
||||
<input type="text" name="relay" id="relay" value="/test" />
|
||||
</div>
|
||||
<div class="columns">
|
||||
<div>Relay URL:</div>
|
||||
<div>
|
||||
<input type="text" name="relay" id="relay" value="/test" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
<p><a class="clicker" href="#">Request Authorization</a></p>
|
||||
<div id="displayarea"></div>
|
||||
</body>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
<p><a class="clicker" href="#">Request Authorization</a></p>
|
||||
<div id="displayarea"></div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -7,24 +7,24 @@
|
|||
--tls_server_certs=/etc/osquery/fleet.crt
|
||||
|
||||
--enroll_secret_env=ENROLL_SECRET
|
||||
--enroll_tls_endpoint=/api/v1/osquery/enroll
|
||||
--enroll_tls_endpoint=/api/osquery/enroll
|
||||
|
||||
--config_plugin=tls
|
||||
--config_tls_endpoint=/api/v1/osquery/config
|
||||
--config_tls_endpoint=/api/osquery/config
|
||||
--config_refresh=10
|
||||
|
||||
--disable_distributed=false
|
||||
--distributed_plugin=tls
|
||||
--distributed_interval=10
|
||||
--distributed_tls_max_attempts=3
|
||||
--distributed_tls_read_endpoint=/api/v1/osquery/distributed/read
|
||||
--distributed_tls_write_endpoint=/api/v1/osquery/distributed/write
|
||||
--distributed_tls_read_endpoint=/api/osquery/distributed/read
|
||||
--distributed_tls_write_endpoint=/api/osquery/distributed/write
|
||||
|
||||
--logger_plugin=tls
|
||||
--logger_tls_endpoint=/api/v1/osquery/log
|
||||
--logger_tls_endpoint=/api/osquery/log
|
||||
--logger_tls_period=10
|
||||
|
||||
--disable_carver=false
|
||||
--carver_start_endpoint=/api/v1/osquery/carve/begin
|
||||
--carver_continue_endpoint=/api/v1/osquery/carve/block
|
||||
--carver_start_endpoint=/api/osquery/carve/begin
|
||||
--carver_continue_endpoint=/api/osquery/carve/block
|
||||
--carver_block_size=2000000
|
||||
|
|
|
|||
Loading…
Reference in a new issue