diff --git a/backend/src/main/java/com/park/utmstack/service/elasticsearch/ElasticsearchService.java b/backend/src/main/java/com/park/utmstack/service/elasticsearch/ElasticsearchService.java index 01a76e672..f45a84f9a 100644 --- a/backend/src/main/java/com/park/utmstack/service/elasticsearch/ElasticsearchService.java +++ b/backend/src/main/java/com/park/utmstack/service/elasticsearch/ElasticsearchService.java @@ -341,7 +341,7 @@ public SearchResponse search(List filters, Integer top, Strin try { Assert.hasText(indexPattern, "Parameter indexPattern must not be null or empty"); SearchRequest query = buildQuery(indexPattern, filters, top, pageable); - return client.getClient().search(query, type); + return client.execute(c -> c.search(query, type)); } catch (Exception e) { throw new RuntimeException(ctx + ": " + e.getMessage()); } @@ -400,12 +400,86 @@ public Map getLatestDocument(List filters, String in public SearchResponse search(SearchRequest request, Class type) { final String ctx = CLASSNAME + ".search"; try { - return client.getClient().search(request, type); + return client.execute(c -> c.search(request, type)); } catch (Exception e) { throw new RuntimeException(ctx + ": " + e.getMessage()); } } + @FunctionalInterface + public interface SearchBatchConsumer { + /** Returns false to stop iteration early. */ + boolean accept(List batch) throws Exception; + } + + /** + * Streams a result set using search_after pagination, never holding more than {@code pageSize} + * documents in memory at a time. Designed for very large exports where loading every hit at + * once would OOM the JVM (and take the OpenSearch client's I/O reactor down with it). + * + * Sort is forced to {@code @timestamp desc} with {@code _id desc} as tiebreaker so that + * search_after is stable and deterministic. + * + * @param filters filters to apply + * @param max hard upper bound on total documents to emit; null or <=0 means unbounded + * @param indexPattern target index pattern + * @param pageSize batch size (capped at 10000 by OpenSearch per request) + * @param type deserialization type + * @param consumer receives each batch; return false to stop early + * @return total number of documents emitted + */ + public long searchStream(List filters, Integer max, String indexPattern, + int pageSize, Class type, SearchBatchConsumer consumer) { + final String ctx = CLASSNAME + ".searchStream"; + try { + Assert.hasText(indexPattern, "Parameter indexPattern must not be null or empty"); + Assert.notNull(consumer, "consumer must not be null"); + if (pageSize <= 0) pageSize = 500; + + long emitted = 0; + List after = null; + while (true) { + int remaining = (max != null && max > 0) ? (int) (max - emitted) : pageSize; + if (remaining <= 0) break; + int size = Math.min(pageSize, remaining); + + final List afterFinal = after; + final int sizeFinal = size; + SearchResponse response = client.execute(c -> { + SearchRequest.Builder srb = new SearchRequest.Builder() + .index(indexPattern) + .query(SearchUtil.toQuery(filters)) + .size(sizeFinal) + .sort(s -> s.field(f -> f.field("@timestamp").order(SortOrder.Desc))) + .sort(s -> s.field(f -> f.field("_id").order(SortOrder.Desc))); + if (afterFinal != null && !afterFinal.isEmpty()) + srb.searchAfter(afterFinal); + return c.search(srb.build(), type); + }); + + if (response == null || response.hits() == null) break; + List> hits = response.hits().hits(); + if (hits == null || hits.isEmpty()) break; + + List batch = new ArrayList<>(hits.size()); + for (org.opensearch.client.opensearch.core.search.Hit h : hits) + batch.add(h.source()); + + boolean keepGoing = consumer.accept(batch); + emitted += hits.size(); + + if (!keepGoing) break; + if (hits.size() < size) break; + + after = hits.get(hits.size() - 1).sort(); + if (after == null || after.isEmpty()) break; + } + return emitted; + } catch (Exception e) { + throw new RuntimeException(ctx + ": " + e.getMessage(), e); + } + } + public void updateByQuery(Query query, String index, String script) { final String ctx = CLASSNAME + ".updateByQuery"; try { diff --git a/backend/src/main/java/com/park/utmstack/service/elasticsearch/OpensearchClientBuilder.java b/backend/src/main/java/com/park/utmstack/service/elasticsearch/OpensearchClientBuilder.java index f6f62d042..e2db9cc13 100644 --- a/backend/src/main/java/com/park/utmstack/service/elasticsearch/OpensearchClientBuilder.java +++ b/backend/src/main/java/com/park/utmstack/service/elasticsearch/OpensearchClientBuilder.java @@ -16,26 +16,71 @@ public class OpensearchClientBuilder { private static final String CLASSNAME = "OpensearchClientBuilder"; private final Logger log = LoggerFactory.getLogger(OpensearchClientBuilder.class); - private OpenSearch client; + private volatile OpenSearch client; + + @FunctionalInterface + public interface OsAction { + T apply(OpenSearch client) throws Exception; + } @Order(Ordered.HIGHEST_PRECEDENCE) @EventListener(ApplicationReadyEvent.class) public void init() throws Exception { - final String ctx = CLASSNAME + ".init"; + buildClient(); + } + + public OpenSearch getClient() { + return client; + } + + /** + * Runs an action against the OpenSearch client with one-shot recovery: if the underlying + * Apache HttpAsyncClient I/O reactor has transitioned to STOPPED (typically after an OOM + * or a fatal callback exception while streaming a very large response), the singleton + * client is rebuilt and the action is retried once. All other failures propagate unchanged. + * Callers that don't need recovery should keep using {@link #getClient()} directly. + */ + public T execute(OsAction action) throws Exception { + try { + return action.apply(client); + } catch (Exception e) { + if (!isReactorStopped(e)) + throw e; + log.warn("OpenSearch I/O reactor is STOPPED; rebuilding client and retrying once", e); + rebuild(); + return action.apply(client); + } + } + + public synchronized void rebuild() { + final String ctx = CLASSNAME + ".rebuild"; + try { + OpenSearch old = this.client; + buildClient(); + tryClose(old); + } catch (Exception e) { + String msg = ctx + ": " + e.getMessage(); + log.error(msg); + throw new RuntimeException(msg); + } + } + + private synchronized void buildClient() { + final String ctx = CLASSNAME + ".buildClient"; try { String host = System.getenv(Constants.ENV_ELASTICSEARCH_HOST); - Assert.hasText(host, "Environment variable ELASTICSEARCH_HOST is missing or his value is null or empty"); + Assert.hasText(host, "Environment variable ELASTICSEARCH_HOST is missing or its value is null or empty"); String port = System.getenv(Constants.ENV_ELASTICSEARCH_PORT); - Assert.hasText(port, "Environment variable ELASTICSEARCH_PORT is missing or his value is null or empty"); + Assert.hasText(port, "Environment variable ELASTICSEARCH_PORT is missing or its value is null or empty"); String user = System.getenv(Constants.ENV_ELASTICSEARCH_USER); - Assert.hasText(user, "Environment variable ELASTICSEARCH_USER is missing or his value is null or empty"); + Assert.hasText(user, "Environment variable ELASTICSEARCH_USER is missing or its value is null or empty"); String password = System.getenv(Constants.ENV_ELASTICSEARCH_PASSWORD); - Assert.hasText(password, "Environment variable ELASTICSEARCH_PASSWORD is missing or his value is null or empty"); + Assert.hasText(password, "Environment variable ELASTICSEARCH_PASSWORD is missing or its value is null or empty"); - client = OpenSearch.builder() + this.client = OpenSearch.builder() .withHost(host, Integer.parseInt(port), HttpScheme.https) .withCredentials(user, password) .build(); @@ -46,7 +91,28 @@ public void init() throws Exception { } } - public OpenSearch getClient() { - return client; + private void tryClose(OpenSearch old) { + if (old == null) return; + try { + if (old instanceof AutoCloseable) { + ((AutoCloseable) old).close(); + } + } catch (Exception ignored) { + // best-effort: the old client is unusable anyway + } + } + + /** + * Detects the Apache HttpAsyncClient "Request cannot be executed; I/O reactor status: STOPPED" + * condition anywhere in the cause chain. + */ + public static boolean isReactorStopped(Throwable t) { + while (t != null) { + String msg = t.getMessage(); + if (msg != null && msg.contains("I/O reactor") && msg.contains("STOPPED")) + return true; + t = t.getCause(); + } + return false; } } diff --git a/backend/src/main/java/com/park/utmstack/util/UtilCsv.java b/backend/src/main/java/com/park/utmstack/util/UtilCsv.java index 96a907998..179020008 100644 --- a/backend/src/main/java/com/park/utmstack/util/UtilCsv.java +++ b/backend/src/main/java/com/park/utmstack/util/UtilCsv.java @@ -1,6 +1,7 @@ package com.park.utmstack.util; import com.fasterxml.jackson.databind.ObjectMapper; +import com.jayway.jsonpath.DocumentContext; import com.jayway.jsonpath.JsonPath; import com.jayway.jsonpath.PathNotFoundException; import com.park.utmstack.domain.shared_types.DataColumn; @@ -13,6 +14,7 @@ import org.springframework.util.StringUtils; import javax.servlet.http.HttpServletResponse; +import java.io.IOException; import java.time.Instant; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -51,6 +53,7 @@ public static void prepareToDownload(HttpServletResponse response, DataColumn[] List rows = new ArrayList<>(); data.forEach(d -> { + DocumentContext docctx = JsonPath.parse(d); String[] cells = new String[columns.length]; for (int i = 0; i < columns.length; i++) { String fieldName = columns[i].getField(); @@ -59,7 +62,7 @@ public static void prepareToDownload(HttpServletResponse response, DataColumn[] Object value; try { - value = JsonPath.parse(d).read("$." + fieldName); + value = docctx.read("$." + fieldName); } catch (PathNotFoundException e) { continue; } @@ -81,6 +84,7 @@ public static void prepareToDownload(HttpServletResponse response, DataColumn[] cells[i] = value.toString(); } } + cells[i] = sanitizeCsvCell(cells[i]); } rows.add(cells); }); @@ -104,4 +108,91 @@ public static void prepareToDownload(HttpServletResponse response, DataColumn[] throw new UtmCsvException(msg); } } + + /** + * Opens a CSV response stream: sets content-type/disposition headers and writes the header row. + * Caller is responsible for closing the returned printer (try-with-resources is fine). + * + * Column names are normalized in-place by stripping a trailing {@code .keyword}. + */ + public static CSVPrinter openCsvStream(HttpServletResponse response, DataColumn[] columns) throws IOException { + Assert.notEmpty(columns); + + Arrays.stream(columns).forEach(column -> + column.setField(column.getField().replace(".keyword", ""))); + + String[] headers = Stream.of(columns).map(column -> { + if (StringUtils.hasText(column.getLabel())) + return column.getLabel(); + return column.getField().replace(".keyword", ""); + }).toArray(String[]::new); + + response.setContentType("text/csv"); + response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=data.csv"); + + return new CSVPrinter(response.getWriter(), + CSVFormat.DEFAULT.withHeader(headers).withQuoteMode(QuoteMode.ALL)); + } + + /** + * Writes a batch of source maps as CSV rows using the same field-extraction logic as + * {@link #prepareToDownload}. Intended to be called repeatedly while paginating through + * a large result set; pair with {@link #openCsvStream}. + */ + public static void writeCsvBatch(CSVPrinter printer, DataColumn[] columns, List data) throws IOException { + if (data == null || data.isEmpty()) return; + + final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss z") + .withLocale(Locale.getDefault()).withZone(TimezoneUtil.getAppTimezone()); + + for (Object d : data) { + DocumentContext ctx = JsonPath.parse(d); + String[] cells = new String[columns.length]; + for (int i = 0; i < columns.length; i++) { + String fieldName = columns[i].getField(); + String fieldType = columns[i].getType(); + cells[i] = null; + + Object value; + try { + value = ctx.read("$." + fieldName); + } catch (PathNotFoundException e) { + continue; + } + + if (value == null) + continue; + + if (value instanceof String) { + cells[i] = "date".equals(fieldType) ? DATE_FORMATTER.format(Instant.parse(String.valueOf(value))) : + String.valueOf(value).replace("\n", " ").replace("\t", " "); + } else if (value instanceof List) { + cells[i] = ((List) value).stream().map(String::valueOf).collect(Collectors.joining(",")); + } else if (value instanceof Number) { + cells[i] = String.valueOf(value); + } else if (value instanceof Map) { + try { + cells[i] = OBJECT_MAPPER.writeValueAsString(value); + } catch (Exception ex) { + cells[i] = value.toString(); + } + } + cells[i] = sanitizeCsvCell(cells[i]); + } + printer.printRecord((Object[]) cells); + } + printer.flush(); + } + + /** + * Neutralizes CSV-injection payloads by prefixing a single quote to any cell whose first + * character is interpreted as a formula trigger by Excel/LibreOffice/Sheets. + */ + private static String sanitizeCsvCell(String value) { + if (value == null || value.isEmpty()) return value; + char first = value.charAt(0); + if (first == '=' || first == '+' || first == '-' || first == '@' || first == '\t' || first == '\r') + return "'" + value; + return value; + } } diff --git a/backend/src/main/java/com/park/utmstack/web/rest/elasticsearch/ElasticsearchResource.java b/backend/src/main/java/com/park/utmstack/web/rest/elasticsearch/ElasticsearchResource.java index c1d6623a3..a69c54110 100644 --- a/backend/src/main/java/com/park/utmstack/web/rest/elasticsearch/ElasticsearchResource.java +++ b/backend/src/main/java/com/park/utmstack/web/rest/elasticsearch/ElasticsearchResource.java @@ -23,6 +23,7 @@ import com.utmstack.opensearch_connector.types.SearchSqlResponse; import com.utmstack.opensearch_connector.types.SqlQueryRequest; import lombok.RequiredArgsConstructor; +import org.apache.commons.csv.CSVPrinter; import org.opensearch.client.opensearch.cat.indices.IndicesRecord; import org.opensearch.client.opensearch.core.SearchResponse; import org.opensearch.client.opensearch.core.search.Hit; @@ -197,43 +198,45 @@ public ResponseEntity> search(@RequestBody(required = false) List searchToCsv(@RequestBody @Valid CsvExportingParams params, HttpServletResponse response) { final String ctx = CLASSNAME + ".searchToCsv"; - try { - SearchResponse searchResponse = elasticsearchService.search(params.getFilters(), params.getTop(), - params.getIndexPattern(), Pageable.unpaged(), Map.class); - - if (Objects.isNull(searchResponse) || Objects.isNull(searchResponse.hits()) || searchResponse.hits().total().value() == 0) - return ResponseEntity.ok().build(); - - List hits = searchResponse.hits().hits().stream().map(Hit::source).collect(Collectors.toList()); - boolean needsEchoes = false; - for (DataColumn col : params.getColumns()) { - if ("echoes".equals(col.getField())) { - needsEchoes = true; - break; - } + boolean needsEchoes = false; + for (DataColumn col : params.getColumns()) { + if ("echoes".equals(col.getField())) { + needsEchoes = true; + break; } - if (needsEchoes) { - hits.forEach(d -> { - Object id = d.get("id"); - if (id != null) { - long countEchoes = elasticsearchService.count( - List.of(new FilterType("parentId", OperatorType.IS, id.toString())), - params.getIndexPattern() - ); - d.put("echoes", countEchoes); - } - }); - } - - UtilCsv.prepareToDownload(response, params.getColumns(), hits); - + } + final boolean enrichEchoes = needsEchoes; + + try (CSVPrinter printer = UtilCsv.openCsvStream(response, params.getColumns())) { + elasticsearchService.searchStream( + params.getFilters(), + params.getTop(), + params.getIndexPattern(), + 500, + Map.class, + batch -> { + if (enrichEchoes) { + for (Map d : batch) { + Object id = d.get("id"); + if (id != null) { + long countEchoes = elasticsearchService.count( + List.of(new FilterType("parentId", OperatorType.IS, id.toString())), + params.getIndexPattern()); + d.put("echoes", countEchoes); + } + } + } + UtilCsv.writeCsvBatch(printer, params.getColumns(), batch); + return true; + }); return ResponseEntity.ok().build(); } catch (Exception e) { String msg = ctx + ": " + e.getMessage(); - log.error(msg); + log.error(msg, e); applicationEventService.createEvent(msg, ApplicationEventType.ERROR); - return ResponseUtil.buildErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR, msg); + return ResponseUtil.buildErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR, + "An internal error occurred while exporting the CSV. Please check server logs."); } } diff --git a/installer/go.mod b/installer/go.mod index 06065f282..f845e7928 100644 --- a/installer/go.mod +++ b/installer/go.mod @@ -3,7 +3,7 @@ module github.com/utmstack/UTMStack/installer go 1.25.1 require ( - github.com/cloudfoundry/gosigar v1.3.118 + github.com/cloudfoundry/gosigar v1.3.119 github.com/docker/docker v28.5.2+incompatible github.com/kardianos/service v1.2.4 github.com/shirou/gopsutil/v3 v3.24.5 @@ -74,7 +74,7 @@ require ( golang.org/x/arch v0.23.0 // indirect golang.org/x/crypto v0.47.0 // indirect golang.org/x/net v0.49.0 // indirect - golang.org/x/sys v0.43.0 // indirect + golang.org/x/sys v0.44.0 // indirect golang.org/x/text v0.33.0 // indirect golang.org/x/time v0.14.0 // indirect golang.org/x/tools v0.41.0 // indirect diff --git a/installer/go.sum b/installer/go.sum index cc9be246d..69a6e7a3b 100644 --- a/installer/go.sum +++ b/installer/go.sum @@ -16,8 +16,8 @@ github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1x github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cloudfoundry/gosigar v1.3.118 h1:M5I101sHroieCCM07+HDVhYq6AUThH9LTJF4WY1d3O0= -github.com/cloudfoundry/gosigar v1.3.118/go.mod h1:HaIEZU356TAVnxmEvDFe5PXOTCOeSmUgVxoPzrat5Po= +github.com/cloudfoundry/gosigar v1.3.119 h1:+wm7uWf3uNVvIxY8vHpjRNmdpCNPoX6gAuoJMn7IQcI= +github.com/cloudfoundry/gosigar v1.3.119/go.mod h1:JUefZL7X7jvezhtLqCWv8sctPNHgz9X7r59hOVJFfv0= github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M= github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU= github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI= @@ -200,8 +200,8 @@ golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI= -golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/sys v0.44.0 h1:ildZl3J4uzeKP07r2F++Op7E9B29JRUy+a27EibtBTQ= +golang.org/x/sys v0.44.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= diff --git a/plugins/aws/go.mod b/plugins/aws/go.mod index 35854e71d..48e6e5f44 100644 --- a/plugins/aws/go.mod +++ b/plugins/aws/go.mod @@ -29,7 +29,7 @@ require ( github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.23 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.23 // indirect github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.23 // indirect - github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.73.0 + github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.74.0 github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.9 // indirect github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.23 // indirect github.com/aws/aws-sdk-go-v2/service/sso v1.30.17 // indirect diff --git a/plugins/aws/go.sum b/plugins/aws/go.sum index 7790ca40f..3e029874e 100644 --- a/plugins/aws/go.sum +++ b/plugins/aws/go.sum @@ -18,8 +18,8 @@ github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.23 h1:bpd8vxhlQi2r1hiueO github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.23/go.mod h1:15DfR2nw+CRHIk0tqNyifu3G1YdAOy68RftkhMDDwYk= github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.24 h1:OQqn11BtaYv1WLUowvcA30MpzIu8Ti4pcLPIIyoKZrA= github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.24/go.mod h1:X5ZJyfwVrWA96GzPmUCWFQaEARPR7gCrpq2E92PJwAE= -github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.73.0 h1:JmrHkELR2Q0O28swrFMm0hZNwpQrV8qmbhnb7suKIfc= -github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.73.0/go.mod h1:MLJu3PUd8fp5Qvj4CiLvyY5H8y7kxHKlTp060Wsd+Vc= +github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.74.0 h1:6TqDeYdvJJEIJGg5ICy7nzC7/UuHk2Eg3wrpb5bWKPM= +github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.74.0/go.mod h1:MLJu3PUd8fp5Qvj4CiLvyY5H8y7kxHKlTp060Wsd+Vc= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.9 h1:FLudkZLt5ci0ozzgkVo8BJGwvqNaZbTWb3UcucAateA= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.9/go.mod h1:w7wZ/s9qK7c8g4al+UyoF1Sp/Z45UwMGcqIzLWVQHWk= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.23 h1:pbrxO/kuIwgEsOPLkaHu0O+m4fNgLU8B3vxQ+72jTPw= diff --git a/plugins/crowdstrike/go.mod b/plugins/crowdstrike/go.mod index 374752153..52e79b7d9 100644 --- a/plugins/crowdstrike/go.mod +++ b/plugins/crowdstrike/go.mod @@ -3,7 +3,7 @@ module github.com/utmstack/UTMStack/plugins/crowdstrike go 1.25.5 require ( - github.com/crowdstrike/gofalcon v0.20.0 + github.com/crowdstrike/gofalcon v0.20.1 github.com/google/uuid v1.6.0 github.com/threatwinds/go-sdk v1.1.21 google.golang.org/grpc v1.81.1 @@ -17,6 +17,7 @@ require ( github.com/bytedance/gopkg v0.1.3 // indirect github.com/bytedance/sonic v1.15.0 // indirect github.com/bytedance/sonic/loader v0.5.0 // indirect + github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cloudwego/base64x v0.1.6 // indirect github.com/gabriel-vasile/mimetype v1.4.13 // indirect diff --git a/plugins/crowdstrike/go.sum b/plugins/crowdstrike/go.sum index ab62a6c08..280fa3acc 100644 --- a/plugins/crowdstrike/go.sum +++ b/plugins/crowdstrike/go.sum @@ -10,12 +10,14 @@ github.com/bytedance/sonic v1.15.0 h1:/PXeWFaR5ElNcVE84U0dOHjiMHQOwNIx3K4ymzh/uS github.com/bytedance/sonic v1.15.0/go.mod h1:tFkWrPz0/CUCLEF4ri4UkHekCIcdnkqXw9VduqpJh0k= github.com/bytedance/sonic/loader v0.5.0 h1:gXH3KVnatgY7loH5/TkeVyXPfESoqSBSBEiDd5VjlgE= github.com/bytedance/sonic/loader v0.5.0/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCcdf5x77udYiSJRo= +github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= +github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M= github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU= -github.com/crowdstrike/gofalcon v0.20.0 h1:Z/NERPVowOBCYsCgnkMRnrfrRkHBFo910kk7zrjzE0A= -github.com/crowdstrike/gofalcon v0.20.0/go.mod h1:a12GB+md+hRSgVCb3Pv6CakeTIsDIUCIVWRlJelIhY0= +github.com/crowdstrike/gofalcon v0.20.1 h1:cqdvyNeJvaQ9sK0k09h/n+z308VJffS+4JfgS+bNaSY= +github.com/crowdstrike/gofalcon v0.20.1/go.mod h1:GYbhi35odSf8qFrcxAX6Sx7N/QIJyz8vKmUzuam7Xd8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= diff --git a/plugins/gcp/go.mod b/plugins/gcp/go.mod index f17873d36..041eb77e6 100644 --- a/plugins/gcp/go.mod +++ b/plugins/gcp/go.mod @@ -6,7 +6,7 @@ require ( cloud.google.com/go/pubsub v1.50.2 github.com/google/uuid v1.6.0 github.com/threatwinds/go-sdk v1.1.21 - google.golang.org/api v0.279.0 + google.golang.org/api v0.280.0 google.golang.org/grpc v1.81.1 google.golang.org/protobuf v1.36.11 ) @@ -66,17 +66,17 @@ require ( go.opentelemetry.io/otel/trace v1.43.0 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect golang.org/x/arch v0.24.0 // indirect - golang.org/x/crypto v0.50.0 // indirect + golang.org/x/crypto v0.51.0 // indirect golang.org/x/exp v0.0.0-20260112195511-716be5621a96 // indirect - golang.org/x/net v0.53.0 // indirect + golang.org/x/net v0.54.0 // indirect golang.org/x/oauth2 v0.36.0 // indirect golang.org/x/sync v0.20.0 // indirect - golang.org/x/sys v0.43.0 // indirect - golang.org/x/text v0.36.0 // indirect + golang.org/x/sys v0.44.0 // indirect + golang.org/x/text v0.37.0 // indirect golang.org/x/time v0.15.0 // indirect google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20260319201613-d00831a3d3e7 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260427160629-7cedc36a6bc4 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260511170946-3700d4141b60 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect sigs.k8s.io/yaml v1.6.0 // indirect ) diff --git a/plugins/gcp/go.sum b/plugins/gcp/go.sum index b36838045..59dcdaf18 100644 --- a/plugins/gcp/go.sum +++ b/plugins/gcp/go.sum @@ -206,8 +206,8 @@ golang.org/x/arch v0.24.0 h1:qlJ3M9upxvFfwRM51tTg3Yl+8CP9vCC1E7vlFpgv99Y= golang.org/x/arch v0.24.0/go.mod h1:dNHoOeKiyja7GTvF9NJS1l3Z2yntpQNzgrjh1cU103A= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI= -golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q= +golang.org/x/crypto v0.51.0 h1:IBPXwPfKxY7cWQZ38ZCIRPI50YLeevDLlLnyC5wRGTI= +golang.org/x/crypto v0.51.0/go.mod h1:8AdwkbraGNABw2kOX6YFPs3WM22XqI4EXEd8g+x7Oc8= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20260112195511-716be5621a96 h1:Z/6YuSHTLOHfNFdb8zVZomZr7cqNgTJvA8+Qz75D8gU= golang.org/x/exp v0.0.0-20260112195511-716be5621a96/go.mod h1:nzimsREAkjBCIEFtHiYkrJyT+2uy9YZJB7H1k68CXZU= @@ -220,8 +220,8 @@ golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA= -golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs= +golang.org/x/net v0.54.0 h1:2zJIZAxAHV/OHCDTCOHAYehQzLfSXuf/5SoL/Dv6w/w= +golang.org/x/net v0.54.0/go.mod h1:Sj4oj8jK6XmHpBZU/zWHw3BV3abl4Kvi+Ut7cQcY+cQ= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= @@ -235,12 +235,12 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI= -golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/sys v0.44.0 h1:ildZl3J4uzeKP07r2F++Op7E9B29JRUy+a27EibtBTQ= +golang.org/x/sys v0.44.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg= -golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164= +golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc= +golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38= golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -251,8 +251,8 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= -google.golang.org/api v0.279.0 h1:hsx2M2OaRcaKtVYK6vXEUnQvdjnend7ZYES+lYaot74= -google.golang.org/api v0.279.0/go.mod h1:B9TqLBwJqVjp1mtt7WeoQwWRwvu/400y5lETOql+giQ= +google.golang.org/api v0.280.0 h1:F4OfEHZhZh6a7uTufJAXXVd/2TQ8EjM4vZH+jX/vFYk= +google.golang.org/api v0.280.0/go.mod h1:oGKmPZRDoD3vdkf6MA7F4VNkR1rxCiuaPSkhsf3EolU= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= @@ -262,8 +262,8 @@ google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7 h1:XzmzkmB14QhVhgn google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7/go.mod h1:L43LFes82YgSonw6iTXTxXUX1OlULt4AQtkik4ULL/I= google.golang.org/genproto/googleapis/api v0.0.0-20260319201613-d00831a3d3e7 h1:41r6JMbpzBMen0R/4TZeeAmGXSJC7DftGINUodzTkPI= google.golang.org/genproto/googleapis/api v0.0.0-20260319201613-d00831a3d3e7/go.mod h1:EIQZ5bFCfRQDV4MhRle7+OgjNtZ6P1PiZBgAKuxXu/Y= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260427160629-7cedc36a6bc4 h1:tEkOQcXgF6dH1G+MVKZrfpYvozGrzb91k6ha7jireSM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260427160629-7cedc36a6bc4/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260511170946-3700d4141b60 h1:seT2EwLWM78plQ7wcDfuWBc/4FAEAXDDiaSol4ku4qo= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260511170946-3700d4141b60/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= diff --git a/plugins/modules-config/go.mod b/plugins/modules-config/go.mod index f04bf8c89..bc168e49c 100644 --- a/plugins/modules-config/go.mod +++ b/plugins/modules-config/go.mod @@ -9,13 +9,13 @@ require ( github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.7.0 github.com/aws/aws-sdk-go-v2/config v1.32.17 github.com/aws/aws-sdk-go-v2/credentials v1.19.16 - github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.73.0 + github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.74.0 github.com/aws/aws-sdk-go-v2/service/sts v1.42.1 - github.com/crowdstrike/gofalcon v0.20.0 + github.com/crowdstrike/gofalcon v0.20.1 github.com/gin-gonic/gin v1.12.0 github.com/threatwinds/go-sdk v1.1.21 golang.org/x/sync v0.20.0 - google.golang.org/api v0.279.0 + google.golang.org/api v0.280.0 google.golang.org/grpc v1.81.1 google.golang.org/protobuf v1.36.11 ) @@ -48,6 +48,7 @@ require ( github.com/bytedance/gopkg v0.1.3 // indirect github.com/bytedance/sonic v1.15.0 // indirect github.com/bytedance/sonic/loader v0.5.0 // indirect + github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cloudwego/base64x v0.1.6 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect @@ -126,7 +127,7 @@ require ( golang.org/x/time v0.15.0 // indirect google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20260319201613-d00831a3d3e7 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260427160629-7cedc36a6bc4 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260511170946-3700d4141b60 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect sigs.k8s.io/yaml v1.6.0 // indirect ) diff --git a/plugins/modules-config/go.sum b/plugins/modules-config/go.sum index 73d9470b2..9b9c9950b 100644 --- a/plugins/modules-config/go.sum +++ b/plugins/modules-config/go.sum @@ -58,8 +58,8 @@ github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.23 h1:bpd8vxhlQi2r1hiueO github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.23/go.mod h1:15DfR2nw+CRHIk0tqNyifu3G1YdAOy68RftkhMDDwYk= github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.24 h1:OQqn11BtaYv1WLUowvcA30MpzIu8Ti4pcLPIIyoKZrA= github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.24/go.mod h1:X5ZJyfwVrWA96GzPmUCWFQaEARPR7gCrpq2E92PJwAE= -github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.73.0 h1:JmrHkELR2Q0O28swrFMm0hZNwpQrV8qmbhnb7suKIfc= -github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.73.0/go.mod h1:MLJu3PUd8fp5Qvj4CiLvyY5H8y7kxHKlTp060Wsd+Vc= +github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.74.0 h1:6TqDeYdvJJEIJGg5ICy7nzC7/UuHk2Eg3wrpb5bWKPM= +github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.74.0/go.mod h1:MLJu3PUd8fp5Qvj4CiLvyY5H8y7kxHKlTp060Wsd+Vc= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.9 h1:FLudkZLt5ci0ozzgkVo8BJGwvqNaZbTWb3UcucAateA= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.9/go.mod h1:w7wZ/s9qK7c8g4al+UyoF1Sp/Z45UwMGcqIzLWVQHWk= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.23 h1:pbrxO/kuIwgEsOPLkaHu0O+m4fNgLU8B3vxQ+72jTPw= @@ -82,6 +82,8 @@ github.com/bytedance/sonic v1.15.0 h1:/PXeWFaR5ElNcVE84U0dOHjiMHQOwNIx3K4ymzh/uS github.com/bytedance/sonic v1.15.0/go.mod h1:tFkWrPz0/CUCLEF4ri4UkHekCIcdnkqXw9VduqpJh0k= github.com/bytedance/sonic/loader v0.5.0 h1:gXH3KVnatgY7loH5/TkeVyXPfESoqSBSBEiDd5VjlgE= github.com/bytedance/sonic/loader v0.5.0/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCcdf5x77udYiSJRo= +github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= +github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -93,8 +95,8 @@ github.com/cncf/xds/go v0.0.0-20260202195803-dba9d589def2 h1:aBangftG7EVZoUb69Os github.com/cncf/xds/go v0.0.0-20260202195803-dba9d589def2/go.mod h1:qwXFYgsP6T7XnJtbKlf1HP8AjxZZyzxMmc+Lq5GjlU4= github.com/coder/websocket v1.8.14 h1:9L0p0iKiNOibykf283eHkKUHHrpG7f65OE3BhhO7v9g= github.com/coder/websocket v1.8.14/go.mod h1:NX3SzP+inril6yawo5CQXx8+fk145lPDC6pumgx0mVg= -github.com/crowdstrike/gofalcon v0.20.0 h1:Z/NERPVowOBCYsCgnkMRnrfrRkHBFo910kk7zrjzE0A= -github.com/crowdstrike/gofalcon v0.20.0/go.mod h1:a12GB+md+hRSgVCb3Pv6CakeTIsDIUCIVWRlJelIhY0= +github.com/crowdstrike/gofalcon v0.20.1 h1:cqdvyNeJvaQ9sK0k09h/n+z308VJffS+4JfgS+bNaSY= +github.com/crowdstrike/gofalcon v0.20.1/go.mod h1:GYbhi35odSf8qFrcxAX6Sx7N/QIJyz8vKmUzuam7Xd8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= @@ -379,8 +381,8 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= -google.golang.org/api v0.279.0 h1:hsx2M2OaRcaKtVYK6vXEUnQvdjnend7ZYES+lYaot74= -google.golang.org/api v0.279.0/go.mod h1:B9TqLBwJqVjp1mtt7WeoQwWRwvu/400y5lETOql+giQ= +google.golang.org/api v0.280.0 h1:F4OfEHZhZh6a7uTufJAXXVd/2TQ8EjM4vZH+jX/vFYk= +google.golang.org/api v0.280.0/go.mod h1:oGKmPZRDoD3vdkf6MA7F4VNkR1rxCiuaPSkhsf3EolU= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= @@ -390,8 +392,8 @@ google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7 h1:XzmzkmB14QhVhgn google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7/go.mod h1:L43LFes82YgSonw6iTXTxXUX1OlULt4AQtkik4ULL/I= google.golang.org/genproto/googleapis/api v0.0.0-20260319201613-d00831a3d3e7 h1:41r6JMbpzBMen0R/4TZeeAmGXSJC7DftGINUodzTkPI= google.golang.org/genproto/googleapis/api v0.0.0-20260319201613-d00831a3d3e7/go.mod h1:EIQZ5bFCfRQDV4MhRle7+OgjNtZ6P1PiZBgAKuxXu/Y= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260427160629-7cedc36a6bc4 h1:tEkOQcXgF6dH1G+MVKZrfpYvozGrzb91k6ha7jireSM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260427160629-7cedc36a6bc4/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260511170946-3700d4141b60 h1:seT2EwLWM78plQ7wcDfuWBc/4FAEAXDDiaSol4ku4qo= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260511170946-3700d4141b60/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=