[New Integrationi] Anduril Lattice#20021
Conversation
Elastic Docs Style Checker (Vale)Summary: 1 warning found
|
| File | Line | Rule | Message |
|---|---|---|---|
| packages/anduril_lattice/data_stream/entity/fields/fields.yml | 572 | Elastic.Latinisms | Latin terms and abbreviations are a common source of confusion. Use 'for example' instead of 'e.g'. |
The Vale linter checks documentation changes against the Elastic Docs style guide. To use Vale locally or report issues, refer to Elastic style guide for Vale.
This comment has been minimized.
This comment has been minimized.
TL;DRBuildkite build Remediation
Investigation detailsRoot CauseThe actionable failure line is missing from the available Buildkite log, but the failed build is stale relative to the current PR head:
Evidence
Verification
Follow-upIf Buildkite still fails on What is this? | From workflow: PR Buildkite Detective Give us feedback! React with 🚀 if perfect, 👍 if helpful, 👎 if not. |
🚀 Benchmarks reportTo see the full report comment with |
teresaromero
left a comment
There was a problem hiding this comment.
for Vale linting fixes you van use the skill on this repository for the agents to update the readmes according to the elastic Vale style
| resource.timeout: {{http_client_timeout}} | ||
| {{/if}} | ||
| resource.url: {{url}} | ||
| state: |
There was a problem hiding this comment.
The manifest/README claim OAuth2 tokens are auto-refreshed with a 30-minute lifetime, but the program never actually caches one: the state.?client_id check on line 29 only picks the auth mode (OAuth2 vs. static token), and the fetched auth.token is never written back into state (the state.with(...) returns on lines 56/69 only set events/cursor/want_more). So every poll re-authenticates from scratch — at the default 5s interval, ~720 token exchanges/hour instead of one per 30 minutes.
Per the Filebeat CEL input docs (https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-input-cel.html), plain state fields persist across poll intervals for the life of the input, so caching is safe here. packages/cyera/data_stream/datastore/agent/stream/cel.yml.hbs (https://github.com/elastic/integrations/blob/main/packages/cyera/data_stream/datastore/agent/stream/cel.yml.hbs) already does this via has(state.?next.expiry) && timestamp(state.next.expiry) > now, reusing state.next.access_token when still valid. Worth the same pattern here.
| - sandbox_token | ||
| program: |- | ||
| state.with( | ||
| (state.?client_id.orValue("") != "") ? |
There was a problem hiding this comment.
| (state.?client_id.orValue("") != "") ? | |
| has(state.client_id) ? |
| request( | ||
| "POST", | ||
| state.url.trim_right("/") + "/api/v1/oauth/token" | ||
| ).with( | ||
| { | ||
| "Header": {"Content-Type": ["application/json"]}, | ||
| "Body": { | ||
| "client_id": state.client_id, | ||
| "client_secret": state.client_secret, | ||
| }.encode_json(), | ||
| } | ||
| ).do_request().as(tok_resp, |
There was a problem hiding this comment.
| request( | |
| "POST", | |
| state.url.trim_right("/") + "/api/v1/oauth/token" | |
| ).with( | |
| { | |
| "Header": {"Content-Type": ["application/json"]}, | |
| "Body": { | |
| "client_id": state.client_id, | |
| "client_secret": state.client_secret, | |
| }.encode_json(), | |
| } | |
| ).do_request().as(tok_resp, | |
| post_request( | |
| state.url.trim_right("/") + "/api/v1/oauth/token", | |
| "application/json", | |
| { | |
| "client_id": state.client_id, | |
| "client_secret": state.client_secret, | |
| }.encode_json() | |
| ).do_request().as(tok_resp, |
| (tok_resp.StatusCode == 200) ? | ||
| tok_resp.Body.decode_json().as(tok_body, | ||
| { | ||
| "token": string(tok_body.access_token), |
There was a problem hiding this comment.
| "token": string(tok_body.access_token), | |
| "token": tok_body.access_token, |
But why is this being kept twice?
| ) | ||
| ) | ||
| : | ||
| {"token": state.?token.orValue("")} |
There was a problem hiding this comment.
| {"token": state.?token.orValue("")} | |
| {?"token": state.?token} |
| request( | ||
| "POST", | ||
| state.url.trim_right("/") + "/api/v1/entities/events" | ||
| ).with( | ||
| { | ||
| "Header": { | ||
| "Content-Type": ["application/json"], | ||
| ?"Authorization": (state.token != "") ? | ||
| optional.of(["Bearer " + state.token]) | ||
| : | ||
| optional.none(), | ||
| ?"Anduril-Sandbox-Authorization": (state.?sandbox_token.orValue("") != "") ? | ||
| optional.of(["Bearer " + state.sandbox_token]) | ||
| : | ||
| optional.none(), | ||
| }, | ||
| "Body": { | ||
| "sessionToken": state.?cursor.session_token.orValue(""), | ||
| "batchSize": int(state.batch_size), | ||
| }.encode_json(), | ||
| } | ||
| ).do_request().as(resp, |
There was a problem hiding this comment.
| request( | |
| "POST", | |
| state.url.trim_right("/") + "/api/v1/entities/events" | |
| ).with( | |
| { | |
| "Header": { | |
| "Content-Type": ["application/json"], | |
| ?"Authorization": (state.token != "") ? | |
| optional.of(["Bearer " + state.token]) | |
| : | |
| optional.none(), | |
| ?"Anduril-Sandbox-Authorization": (state.?sandbox_token.orValue("") != "") ? | |
| optional.of(["Bearer " + state.sandbox_token]) | |
| : | |
| optional.none(), | |
| }, | |
| "Body": { | |
| "sessionToken": state.?cursor.session_token.orValue(""), | |
| "batchSize": int(state.batch_size), | |
| }.encode_json(), | |
| } | |
| ).do_request().as(resp, | |
| request( | |
| "POST", | |
| state.url.trim_right("/") + "/api/v1/entities/events", | |
| { | |
| ?"sessionToken": state.?cursor.session_token, | |
| "batchSize": int(state.batch_size), | |
| }.encode_json() | |
| ).with( | |
| { | |
| "Header": { | |
| "Content-Type": ["application/json"], | |
| ?"Authorization": state.token.optMap(t, ["Bearer " + t]), | |
| ?"Anduril-Sandbox-Authorization": state.?sandbox_token.optMap(t, ["Bearer " + t]),.orValue("") != ""), | |
| } | |
| ).do_request().as(resp, |
| "version": 2, | ||
| "visualizationType": "lnsXY" | ||
| }, | ||
| "title": "Diposition Distribution" |
There was a problem hiding this comment.
| "title": "Diposition Distribution" | |
| "title": "Disposition Distribution" |
| "layers": {} | ||
| } | ||
| }, | ||
| "filters": [], |
There was a problem hiding this comment.
This should have a filter to restrict it to the data stream.
| }, | ||
| "zoom": 3.08 | ||
| }, | ||
| "title": "[Anduril Lattice] Entity Map", |
There was a problem hiding this comment.
| "title": "[Anduril Lattice] Entity Map", | |
| "title": "Entity Map", |
Already in the dashboard.
There was a problem hiding this comment.
Add titles to the metrics panels.
Add layer-level queries to the maps so that if the map query is cleared we don't get all logs-*.
There was a problem hiding this comment.
We don't need this; it will be injected.
|
✅ All changelog entries have the correct PR link. |
💚 Build Succeeded
History
|
Proposed commit message
Adds a new integration for the Anduril Lattice Common Operational Picture API. Collects entity lifecycle events (tracks, assets, geospatial zones, signals) via long-poll REST API with OAuth2 and static bearer token auth.
Checklist
changelog.ymlfile.Author's Checklist
How to test this PR locally
Need a developer account with Anduril to test
Screenshots